 Welcome to another episode of GUI Challenges where I build interfaces my way and then I challenge you to do your way because with our creative minds combined we're going to find multiple ways to solve these interfaces and expand the diversity of our skills. D-D-Demo time! Let's check out all the sweet features this has. Like first we'll start with the mouse as we hover over each of these buttons. Look at how they uniquely shoot out in 3D space. We're translating Z and since we have perspective on the whole body here they have somewhere to vanish towards or to come at us and look at this I'm bringing things towards the screen to create this focus and I have multiple layers and since each of them are traveling a different distance and I have a little bit of delay in the animations it really makes this a cool effect like something is really moving in 3D space towards us. It also kind of feels like we're in an AR you know video game or something like that right like we've got a little pointer in our hands and look as I mouse back and forth like this and up and down we can kind of change the rotation that's like slowly happening so there's an animation that's causing this to sort of constantly float in space but my mouse can interrupt it and sort of get in there and create even more of like a 3D experience in there so anyway those are some of the mouse experiences down here is the light theme we've got the light theme and reduced motion so look at the reduced motion experience we're not rotating the thing in 3D space there's no like motion float effect and there's no animation as we hover over each but we are still pushing things in 3D space it's just much less like see new game here it's sort of like I think this one has like 10 pixels of distance is traveling and this one's traveling like 40 or 50 pixels and so way less distance traveled still getting a nice color highlight still looks like a focused element and still has a nice push effect like look at this look at that push effect and it's very satisfying it feels really nice on a controller too or like on your keyboard as you push space and those things drop in there like here I'll tab into this I hit up and down on my arrow keys just like if I was on a controller hit space and look at these that's just nice right feels like I'm right at home in a video game we can see it rendering across all these different browsers here's ios safari on a tablet we have ios safari on a phone and we have android down here and so that covers our light theme our keyboard usage we've got screen reader accessibility because of the way that we structured our html and we'll check that out in a second but there's one more thing I want to talk about that's kind of hard to see and I it's probably not coming through in the video but on my screen which is an ht screen I've tapped into safari's ability to show brighter colors using display p3 and the borders on these are just like lightning neon on my screen and they're just really vibrant and bright they just look they are they're pushing all the pixels on my screen to their brightest nits and it looks so cool so that's an overview of what we have built and let me go into sort of how I built that and the sort of internals and to start let's start with the html what I chose to do was make a button list and I did that with a ul has a class of 3d button set there's an li for each button so that gives us a list of buttons and screen reader technology and all sorts of things know exactly what that is and how to display it so with that structural markup as our base let's go look at a couple things that we needed to set on the body so that we got 3d perspective and can start building out our layout that you know makes the buttons grow and look big and juicy and then start filling out of the three-dimensional layers let's go check that out in chrome this looks so sweet huge I love that the buttons at the bottom just are so different and they're a little bit more extreme in the transform than in the middle like the middle it's coming towards you right you have to like turn this thing to the side to even know that it's really doing that okay anyway I digress let's open up our dev tools and look at some of the things that are making this all happen all right first off let's throw a couple of the grid overlays on here because they track the 3d elements so look at this we have a grid on body that's centering our content centering our ul list and then we have a grid on flexbox that look at that it's even showing like there's still some margins on the ul I have to take that off or is that padding it's probably some padding and then there's some gap in between each of the buttons and look at the overlay continue to paint while this is rotating 3d space just what a cool feat and it looks really neat in the editor there and I could probably go in there and like change some of the gaps and stuff and watch it continue to follow it and that's just really cool I thought I'd show that just because that looks so neat and you can see how much the perspective is helping this thing bust out of its box so here let's get rid of the flexbox one and keep this box and go change some of the perspective on the body so this value right here 40 viewport wide is what I've set the perspective to and this drastically changes the way that the it's like the amount of effect that a rotation or something in 3d has and interestingly lower numbers result in a bigger more here I'll just show you lower numbers are going to result in a more extreme rotation so here I don't want negatives but look at this it's like I go to six or seven vw look at this whoa talk about being in 3d space whoa okay wait let's let's change that let's go back up to something a little bit larger here's 21 all right still a little too extreme let's turn off the grid just so we get a smoother experience here nice okay so right I didn't want anything that extreme I wanted something a little bit more subtle than that and so I settled on something like 40 vw but if we crank this up to like 82 watch as we sort of get way less out of our rotations and way less out of our translate z and so this is like a fun lever that you can play with when you're building something in 3d on the web is what is your perspective how much do you want your changes in 3d to be reflected visually in perspective and this is the way that you can go change that so here let me go change this back down to 40 awesome the next thing I want to show you is um this rotation that's happening on this ul is just a let's go to the animations and we can hit refresh and it should record yeah here we go here's our animation so we've got one happening here it's called rotate y on the whole ul and that is what's continually and infinitely playing back and forth and here I can grab the scrubber here and kind of change that and see it and what it's doing there and it says it's only rotating y but there is a light rotation on x oh it says rotate y because that's what I named it and if we hover on each of these we can see each of these animations pop up here too and we can kind of go replay them and see how many different effects I've put on there right we have a background color that's changing when I hover we have a position that's hovering for each of these different pseudo elements right there's a before and an after on the button and it's just kind of neat to see all of that play out like that okay so that's our animation panel that was the rotation that we have on there it's just an animation right here rotate y five seconds ease in out forever um let's go actually look at that animation really quick because it has a cool technique in it that I want to share the animation definition is right here with at key frames rotate y and notice that I'm only setting a middle point so I'm not saying zero or a hundred percent or from and to I'm saying 50 and what this allows me to do is tell it where it should be in the middle of the animation and zero and a hundred percent are going to be the natural positions of rotate y and rotate x which allows me to easily do an infinite animation because it's going to go from its current position to this one at 50 percent and then back to its original position and then back to middle and back to a hundred percent so we get this really subtle way of making an infinite animation that can kind of ping pong itself with just one key frame so you might have been tempted to do like something like zero percent uh a hundred percent here this is like a shortcut way if folks like to do it um and then put your like transform rotate y and rotate x is zero in there that's totally unnecessary you can just say in the middle I want it to be here and it will figure out the rest and I just think that's a really cool effect next let's start drilling into the css very specifically let's open up the 3d button set and look at some of the custom properties we have x and y here those are going to be set with javascript on mouse interaction we have a distance set to one pixel and that's because when you're doing transforms these days you're going to want the position of things to be at least one pixel in space uh zero is sort of a struggle because it's in the middle of all the planes and anyway if you set a distance of one pixel you'll save yourself from a lot of 3d perspective um issues so anyway kind of a hot tip one pixel there is great for uh translate z or something like that as a starting place because you're sort of like giving it an initial 3d position to be in we have some color theming happening we have max rotate y and max rotate x at 10 degrees and 15 degrees and then some colors here also this bounce ease super cool so that's why when you're hovering and you're getting that nice bounce effect through all the layers and because we're just sharing that custom property to all of them we'll get into that but I want to show uh how we use the rotate y and rotate x these maximums here it's kind of fun so we remove the margins on a ul we got a vertical rag right layout right display flex flex direction column so it's going to go top to bottom align items flex start is going to make sure that they don't stretch to the width and gap of two and a half vh so they're getting a nice little vertical gap in there we set transform style to preserve 3d so you need this if you're going to be doing things in 3d it's very easy to forget but this tells the container that things are going to happen in 3d space here it gives like I said here creates a 3d space context uh and we're going to do that a couple times here as we go through the css but here's our clamped menu rotation so right we don't want to be too extreme so our rotate y we're going to pass in clamp and clamp is going to set a min at like negative 15 degrees a max at 15 degrees and it's going to allow the middle range to be set by javascript here is the y value and notice this is transformed so when we hover we're setting this y and we're setting this x and these clamps make sure that we don't overly rotate that cool card and we don't under rotate the card we're sort of within a healthy range and it's kind of a lot to read but I broke it out and I thought it really like the end solution is really nice css is handling a lot of really cool uh complex behavior here all right when we have motion okay so this should look pretty familiar as like a custom media that I stash we said we'll change to transform right we're going to tell the browser hey we're going to be doing a lot of transform changes here so you should be ready for that then we also set the transition to transform 0.1 seconds so as we're mousing over we want to transition between these new x and y values instead of instantly snapping to some new rotation then we're also consecutively like running an animation all the time it's called rotate y but we saw it rotated x and y we set that for five seconds easing out forever right super cool our dark theme here and here's our hd color so if the browser supports a high dynamic range of color and they support this color syntax here color display p3 of this is just a really deep black well then i'm going to set the theme to a really nice vibrant purple that i created here and that's why in safari which does support hd color and supports this color syntax gets that really nice vibrant color set there so that is how the styles were applied to the ul let's look at the 3d button set for the li what do we do here okay so we have another display inline flex that pretty much gets oh yeah here we say change display type from list item because otherwise we see a bullet so this gets rid of the marker slash bullet position relative because the buttons are going to have pseudo elements that need to be positioned inside of this container and again we create another 3d space context here so i'm go ahead and collapse that and last year we'll look at our 3d button set so here's our button this is where a lot of the magic happens so first we want to get rid of a lot of the default button styles because we're going pretty custom we want to bring in some of our brand style so here's where we set the background color and the text shadows and stuff like that and these can all be changed you know in a media query so our font size of v min file i just wanted a big text i brought in a custom font called audio wide so it looked more like a video game some padding inline some logical properties here border radius we have five pixels and 20 pixels and that gives them the sort of asymmetrical corners well one of the corn two of the corners are like very rounded and the other two are just slightly rounded gives it a nice like future effect i thought then we have here prepare for three perspective transforms so we set our transform to translate zvar distance that's going to be one pixel by default and we set our transform style to preserve 3d so again we're saying this is a space where things are going to be popping in 3d and we want to make sure that those come through and that they have a space to work inside a 3d space so anyway this is just another hook for them to go into the perspective now this is kind of a tricky one here but it says is hover or focus visible so right this is focus visible as if my i'm coming from a keyboard if i'm not with my mouse like i don't want to see normal focus i want to see focus only for um folks that are using something that need to see focus i'm just relying on the browser to sort of give me a more minimal focus state here it's just a more appropriate one so if it's being hovered or focused and the button is not being pressed then what i want to do is increase the distance right because if it's pressed i want to restore it back to that distance of one pixel that's what gives it that pressed effect and so while it's not being pressed we set the distance to 15 pixels i set the background color to a nice little hover background highlight and if motion is okay right i can set up transitions and increase the distance even more so if motion is okay i set the distance to 3v max so it gives us a nice relative unit to the screen we set the transition timing function to that bounce ease that we set up earlier and a transition duration of 0.4 seconds then in order to get a nice little stagger effect the after and before each have a different transition duration so that means the one in the back and the one in the front of this button are all going to sort of transition at a different speed but arrive in their final locations really nice and just gives it that nice like bouncy staggered effect that i thought looked really nice and now let's go to find some of our before and after so our before and afters are kind of unique they're mostly just border elements they're absolutely positioned border elements that i created so that when they're flat they look like one border but when you hover you can see that it's actually three layers so i set the content here so we can create an empty element i set the opacity to 0.8 just because futuristic ui's always have some sort of transparency in them don't they i cover the parent with position absolute and inset zero so this gives our pseudo elements the top right bottom left of zero which is going to expand it to fill the whole area so it's a quick way to cover a whole item uh with another item and you know create like a stack effect and i'm a style of the element for border accents so this is our border one pixel we get that theme that nice blue uh depending on for a darker light i get that border radius again so we match the border radius of the border that they're inside of and i move in z space with a multiplier so here's we're currently still in the before and after so both of them are going to get translate z this is where we're starting to push things into three-dimensional space we calculate that distance which we set to a vmax value and we divide by three so that's going to give each of these a distance that's a little bit different than the main button itself and if motion is okay we'll transition that transform so that they push in space that way and then i'm going to make an exception here yeah exceptions for one of the other items so one gets pushed back and one gets pushed forward and this one's going to get pushed back because it's going to take that same calculation but multiply it by a negative one and by multiplying a negative one we're going to push one border behind our button and we're going to bring one border in front of our button so we want our text nice and legible but we want these three cool layers and then uh another effect i don't know if anyone noticed is on dark mode there's a glow around the button and this is how i got that glow effect is and i just thought it looked kind of cool if you're in a dark room it's always nice when things that are nice and bright have a cool glow effect and again here if motion is okay we're going to tell the browser we're about to change the transform on these pseudo elements and these buttons like you better be ready and here's how you should do it do the background color at half a second with ease and transform you know transition the transforms at 0.2 seconds and rotate y that's literally all the css and all the hgml that it took to get that primary effect done now there's some javascript that we wrote to get some more effects but let's go look at the dom and let's go look at the dev tools and kind of like inspect some of these things really quick just to get a better grip of what's going on there all right we're back in giant chrome giant demo area and maybe you can now see the little glow effect that's happening you can see the glow around the edges here and look as we hover you can see that one border was pushed in front of our button layer right that's see it's like a little bit in front and then another one is behind it so our our main button that has like the most solid of the text here is in the middle of two borders that sort of one shot towards you and one shot away and I just thought that made for a really cool fact they all move a little bit but some move farther than others and again with that delay and the bounce effect we get it just really nice sort of like I don't know this feels very lightweight and physical in nature and just kind of cool also if you look over here in the style you can see the x and y are being set as I mouse around this element here look at that those are being fed into our calc or our clamp remember and those are changing the actual position and we're transitioning that over point one seconds and that's how we're doing that and that transition is able to interrupt the animation and it just looks kind of cool I thought it was really nice let's twirl open our oh one of our buttons here and look at our pseudo elements nice okay so we have a pseudo element here and a pseudo element here and when we hover we can see that they push out a little bit and just that's that was all the effect that it took you can see that they're covering the whole space one of them has a little bit more of a border too it has a yeah three pixel border width and here I'll just bump it up a little bit to like eight and we'll hover and you can see that that's the one in the back so the one in the back is sort of like the the primary border that's like very visual but I push it back in so much that I can bring up a really hairline one towards you and this kind of creates this cool effect because when they're sitting together you don't really know that there's three layers but when you push in or when you hover you get this nice effect that they're there so let's like briefly go over some of the java script and we'll go from there because one of the things of course we have roving UX in here and that's what's enabling me to use my up and down arrow keys here and create a focus strap inside this menu and that I think makes a really nice effect because you can use left and right arrows or up and down arrows to navigate this and I think that's a really important thing to consider here especially because this looks like it should be used from a controller you should be able to use it from the keyboard and a controller just made a whole lot of sense anyway let's go briefly look at the java script and then we'll jump out of this demo there are two parts to the java script the first one is the mouse parallax and then the arrow key support so let's start with the arrow key support I imported roving index from my roving UX library which we've been using in a lot of these demos it sure seems like the roving keyboard navigation is really important so anyway I bring it in all the time and here I am I can target my 3d button set and tell it that the targets for the focus are the buttons and so that's why when you focus into this element it pushes it down to the first button and then allows you to iterate through the buttons and that was as easy as that you can install this from npm or from a cdm but now let's look at the mouse parallax so the first thing I do is I grab the menu with a selector so that I can grab its bounding client rect and so by looking at the full container here and then getting its bounds I'm able to know if the mouse is in the left side or the right side or the upper part or the lower part and then I can use those bounds with the current mouse position to decide how much I want to rotate it so anyway we'll we'll get there here I check if motion is okay on load so if there is a no preference which means motion is going to be okay so this will match if the user is okay with motion and I give it a quick little rename we'll use this right here to set up our event listeners so here's our event listener as long as motion is okay we're going to watch mouse move and grab the target which is going to be our window object and the x and the y and the x and the y we're going to feed directly into git angles and git angles is going to return us a delta of x and y we're going to use the delta to set these custom properties and we're going to pad that we're like drastically going to reduce how much delta there is by dividing by 20 so you can kind of play with these values down here but then here's git angles takes the current mouse x y grabs the some values off of the bounding rect that we grabbed earlier so we stashed this in memory on load and now we can grab the height and width and the x and the y of this particular element use the current mouse positions and figure out what's going on here and so in this case we're saying client x which is their current x mouse position we're going to take the half of the width plus the x position of this element so this element in the middle of the screen so we need to know it's x and we also want to know if we're on the left or the right side so that's why we're multiplying by 0.5 and by doing this calculation in this one we're able to return a delta that we can then use in here so that's how the JavaScript worked to get that mouse effect this is how we got the keyboard effect we went over every piece of html and every piece of css i hope you enjoyed this demo of this 3d game menu i had a whole lot of fun building it and be stoked for the next gooey challenge i'll see you later y'all thanks for watching