 Welcome to another episode of GUI challenges where I build interfaces my way and then I challenge you to build it 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 and in today's GUI challenge we are building floating action buttons aka fabs and these are actions that you sort of want to have in your viewport at all times so that no matter where the user is scrolling they can have this particular action to add a new post or like something or whatever it is you've got it right there for them nice and easy next to your thumbs and I'm going to show you how I built mine but first let's check out this intro this is the lovely debugging corner where I have multiple versions of safari represented here I have firefox represented over here chrome on android down here and chrome on desktop and if you're noticing anything kind of silly right now about the way that I want maybe not silly but why is this one different maybe this one's over here on the other side of the document so this one's in the bottom right this one's in the bottom left what is going on well maybe you've guessed it I've used logical properties and I've changed the direction of the document to right to left and if I go back to left to right it's now on the side that you've probably known to come in love as a a westerner or you know reading mostly English and in this case we've kind of articulated that the floating action button should go as we read from left to right and left to right left right we're going to put an action there at the end of that line where you're reading and if you're in a right to left language well logical properties lets me do that exact same UX consideration for folks reading from right to left and then it's just kind of a cool little uh cool little feature in there of using logical properties you get to sort of make this internationally relative positioning very easy right I wrote one style instead of many to consider it later you also might be noticing this little icon here so this is the accessibility tree view you can enable this by going to um well here go to settings at the settings cog go to experiments and scroll down you'll see enable full accessibility tree view in the elements panel and here is why that's cool so if I am too let's just kind of pull this so I guess I don't know to pull that open um pull this down here's our fabs so this is a group that's look it's even has a roll group and an aria label that describes its um floating action buttons and then in each here we have a button that's a button element it has a class a title and an aria label and an svg icon was set to aria hidden true now maybe you're very well versed in accessibility and you know how this all gets interpreted into a screen reader but maybe you don't well hit this button and you can get a really good idea so here we can see our group floating action buttons this could be read out to a screen reader button uh with the text of adnew action currently focusable or it's focusable true if I'd tab in here it will be focused true right and this is kind of cool and notice if I try to twirl it open there's nothing in there and that's because the contents were set to aria hidden true and it's already got a label so everything is kind of fulfilled here um a non-sided user has all of this information to use before choosing any of these buttons so kind of cool I really like this feature and being able to go verify um at a quick glance now this doesn't replace testing on actual devices um but it is kind of a cool feature that way one of the other things that I thought was interesting is the group here uh with the roll group is the one that's kind of controlling the layout and positioning of the buttons and then each button just gets to be a button so really these are just icon buttons they're not necessarily floating action buttons in this particular case I think what makes them floating is here if I zoom in like we were looking at in the intro you can see there's a shadow on them and when I push the shadow goes away they also move down a little bit so this definitely gives them the sense of floating um so that's they're a little bit more unique than maybe a regular um icon button so here it command zero to go back to regular zoom size um and that was cool the fabs here are just using display flex flex direction column reverse oh well we're gonna have to talk about that in a second but place items center look if I take that off oh is place item center is shorthand for a line item center and justify item center so it looks like my preprocessor has populated those just for funsies look if I go line items center and justify content center I can see that all snapped together and look we even got nice tools if I hover over here you can see where that's they're kind of being pulled to so there's the axis in the center going vertically because we're setting flex direction to column and then we're setting items to align in the center and we can see them being gravitationally pulled by flex into that center they even lost their alignment of stretch there because we said align item center instead of align items stretch which is the default so cool tools helping us visualize but let's talk about column reverse so if I pop open our tools again just go to regular column this is what the floating action buttons are um described in the document so here if I let me pull down our little uh display here drag this down so here's our group here's our first button oh look it's on top and then our heart button is underneath our secondary our mini fab is underneath the other one well that's not necessarily how design asked us to present this design wanted us to have the heavy weighted button on the bottom and the secondary options on top and in fact if we tab we want to tab into this this group of buttons and definitely get the primary action first and hit tab to get the other one secondary so if I go back into here and change it back to column reverse what we do is we get the effect that we want so we have the document order that we want so if I tab in that primary item that's first in the the document here gets focused first if I tab again I go to the secondary button and thanks to our sort order or kind of flex direction we're able to reverse it visually so visually we see that weighted item on the bottom but to the document that item is first in the list and so kind of a cool tricky little interaction in fact I'm going to put a link in the show notes right now so you can go see how the CSS working group is talking about how could CSS change the order visually and then have that inform the document order also because it's not always the same sometimes your your visual order is different than your document order and maybe you want the visual order to inform the document order and how do you do that and today that's not very easy so all right that's enough accessibility talk and HTML talk it's time to get into some CSS let's go check out the CSS what do you think check out my styles I've got some styles my styles yeah yeah my styles expanded okay like you like my little hold music as we transitioned into this view I doubt it I doubt you liked that because I didn't even like it okay anyway let's just jump it we have a viewport margin uh being defined inside of the fabs container and that's just so that we're trying to push away from the edge and we want to do that evenly and uh it it looks nice if you share that with gap right so then you have the same space away from the edges this is the same space you have between your items just made tons of sense for a container to control this so we're fixed position we have a little bit of zindex we're using display flex we've already talked about column reverse and placing our items our gap and our insets are all using that one custom property and that concludes the the layout for the group container which I thought was kind of neat how that turned out so uh succinct now let's talk about the fab item itself so we've set a size here and that's because the mini one can be set into a smaller size so if we go check that out and we inspect the mini fab fab with the extra class of mini here we are if we change this look at how everything scales so nicely well it's not so mini anymore is it it is now the mega fab I like mini and mega that was from the dialogue episode now it's now it's good stuff okay so anyway it's just nice being able to have a single point of control for the sizing and we're doing that all with custom properties uh right here so we're setting that to size we use size in a couple other places like as you can see here in the padding and in our svg so the inline size and the block size are set to that particular size so the padding and the icon are all controlled from one single uh point gotta love custom properties and how they sort of cascade down really sweet and if you're not familiar with gooey challenges and some of the patterns that we've been working with in the past here's one that I really like where we upfront define um our light and dark variables and then we pivot them um later so here I'll briefly describe this one so we have a light background a light background hover color and this is using open props and in open props as the numbers get higher they become darker so in a light background we're going to have a pretty good vibrant dark pink and then when we hover it we're going to go even darker and that's another rule in gooey challenges where hover and focus interactions should increase the contrast to make something more visible you shouldn't hover or something and have the icon disappear because it became too faint so anyway open props helps us here because we can just hover and increase the number to get a darker color and then the light theme that's going to contrast more with the uh color of the icon so again with dark dark we're going to pick a lighter pink and then when we hover we're going to go even lighter and now we can start to use these props so our background property is going to contain light by default same thing with our foreground it's going to be light by default so we have a light foreground and a dark foreground color and here we can use those simple properties so we have a background set to the background property a color set to the foreground color property and in dark mode let's just switch down here to dark mode if the um user's preference is dark we'll set the bg to the dark bg and the foreground to the dark foreground so these things become really sort of um descriptive so the properties are descriptive of what they hold and then when we flip the values they become descriptive of the adapting that they're doing so they're adapting to this particular media query and that base property is now adapting itself to a darker context we did that even here with the motion so if i uh scroll down here so motion reduced is going to hold what is okay to animate when motion is reduced for that user and that's going to be box shadow and background color if motion is okay we're going to also we're going to keep animating box shadow and background color but we're going to additionally animate the transform and the outline offset and here's our transition base property set to motion reduced by default our transition is set to transition right so just like we did with the foreground and the background and then if motion is okay we'll flip that transition base property to the motion okay property and so now we have this adaptive system where everything is very declarative and our switches are really clear and concise about where they're switching and they're only switching one thing at a time which is kind of cool all right let's review a little bit more of the styles here our padding is just half the size it's kind of a nice way to scale it with it because we weren't using font size the icons weren't using font size you probably could using ms and rems or ms if you wanted to but we have border radius at the radius round and an open props this is just a huge value i think we've talked about radius round before even doing something like one e five px which is the same thing as one with five zeros px in there it's a cool way to write a large number if you need it but anyway that's what's tucked behind that value we talked about our background and color um open props comes with some really nice shadows and what kind of floating action button wouldn't have a shadow being cast under it so we use a shadow four which is a pretty big shadow and if you noticed when we clicked it um it became a smaller shadow and since open props gives us those shadows we can easily do this on active box shadow shadow two so we'll transition that box shadow from shadow four to shadow two on active state and if motion is okay we'll even move the element a little bit too on click which we'll go check out again here in a second so here's our mini versions here's our sort of adaptive custom properties adapting our motion adapting our color our svg having its size um if motion is okay we're going to transition the transform and that's going to be um that rotation on the plus that sort of has that squishy effect it has a little bit of elasticity it's all done here with that custom property active we've talked about here is um if the button is active hovered or focused visible we're changing the background color so the bg prop turns into light bg hover unless we're in a dark scenario in which case it turns into dark bg hover we could probably make a custom property here another one called bg hover and then just set bg hover to whatever these are and kind of avoid a little bit of this but i don't know it's a similar way to get the same task done this one was interesting here we have and not first of type so we're currently looking at buttons these are the fab button classes and if it's not the first one in the list it's going to get zindex negative one and that's going to push those smaller buttons behind the first button so even though they come later in the dom order that puts them on top of something and in a stacking context and this makes sure that they're all behind that main one so that their shadows don't cast over top of that big button the small buttons shouldn't cast their shadows over top of the big ones and we handle that right here with zindex negative one and lastly this data icon plus for hovering on that particular button that has that we're going to rotate that um plus icon on the z by a quarter turn and i really like using turns and that gives it that nice subtle effect so i'm going to go back to our demo you can see as i hover we get that nice elastic in fact let's go to the animations panel animations pull this up hover c r let me click that yeah c r curve here this is our svg being rotated it starts down and it comes up then it goes down under again and that's what's giving that a little bit over rotation and a little bit of the under rotation as it goes across it gives it that elastic effect super cool it's just a prop and open props and use it as much as you like um also if we click notice that our shadow animates from that deep shadow till a much more shallow shadow when we hover the background color is changing from that pink to a darker pink in fact let's change to the light theme and if we hover we can see that it goes a little bit darker right we want to increase the contrast we press and it's going to drop we're going to get less of a shadow and we get a nice little floating action button type of effect i hope you learned something in this gooey challenge it kind of uh you know taxed a lot of our different parts of our brain we had to use the clever animations we had logical properties we have um adaptive custom properties and all the little goodies that go into making a good strong button um end up taking a lot of time so i hope you enjoyed this gooey challenge and i'll see you all next time take it easy