dogear

enter for all results · esc to close

Enhancing Responsiveness With Flexbox

youtube.comvideo

Zoe M. Gillenwater, CSSConf EU 37:13

transcript

[Music] so um yeah I am uh I live in Amsterdam I'm originally from the US and um I live there with my husband and my two kids who came with me today but they didn't really think this was cool enough to sit in on so I think they're running around outside um I've been doing web design professionally for about 15 years and I'm currently a senior designer at booking.com where I do both design as well as HTML and CSS one of the things that's fun about working there is seeing the rather creative um photos and names that some properties have chosen for themselves for instance how would you like to stay in wrong place and of course you stay in Hell or Heaven depending on the type of person that you are I guess and finally there's Jesus this is my favorite line from its property description that Jesus is a great guy so these are just a few of the over 82,000 properties providing booking with their own content for us to display that content then has to be translated ated into 42 languages as does all the other website content and the prices that you see on this site are in one of 54 currencies with this huge variation in content I have to make sure that my designs can be incredibly flexible for instance if I have to design a component that includes the name of a property that name might be as short as two characters or as long as 109 characters or anywhere in between so my component has to be flexible enough to hold all the Vari in an elegant way in responsive web design the challenge is that you never know how much space is available outside the component here the problem is kind of the opposite not knowing how much stuff is available inside the component but in both cases the question is the same how big do I make this thing so that everything will fit nicely in response to web design you answer this question by picking a percentage an M or REM value or a viewport unit based on what will work well for that item and the others on the page the majority of the time and these are all good relative units of measurement but they're not perfect they are still a decision that you are making ahead of time rather than a calculation made on the Fly for an individual users precise set of viewing conditions and the precise piece of content that they're viewing at that moment they're always going to be your best guess at what will work well um for the majority but not necessarily the ideal for anyone thing in particular now don't get me wrong I have nothing against using these units of measurement of course they are the units that I have chosen to use in my work um whenever possible for the last 10 years and I continue to use them but any imposed unit of measurement is always going to be an approximation of the ideal flexbox is not the ideal either it's a tool with strengths and limitations just like any other but it gets us closer to the ideal because with it we no longer have to set explicit Dimensions at all we can let the browser figure out um what size is best based on the space available the surrounding elements and the content within and we still get to tell the browser a starting size a starting point for that size um to give it some guidance but we're not laying down a law as we are with explicit Dimensions even relative ones let me give you an example of the difference between the two approaches here is the job search form from the guardian site it's a responsive uh layout they give all the Fields percentage widths including the select uh menu and the button and they change those percentages at different break points this is the widest version of the layout and they didn't use flexbox on it as they do now for their main site they still use floating here so I decided to make a copy of it to see if I could improve it at all by adding Flex box just as an exercise for me not because there's anything bad with how they're doing it currently so I copied it this is my copy it uses floats and percentage widths as they do and I use this as my starting point and I then tried to see if there was anywhere where I could add Flex box to make the um form more responsive and I found two opportunities for simple Progressive enhancement the first issue is that because the select menu is set to a percentage not its content length the menu text can sometimes be cut off also the button can grow much wider than its text which looks rather awkward in my opinion even if you like it like that the um which is fine the point is that you can't control it the viewport is controlling it and sometimes it will be snug to its text and sometimes not the percentage sizing becomes kind of arbitrary this is the problem with explicit Dimensions now I could fix it by tweaking the break points and not changing the layout until I'm sure that the select menu content can fit but this is unreliable you can't always create a whole new set of break points to accommodate one piece of content on one page out of your whole site also it's dependent on all users having the same font size and on the content in that select menu never changing neither of which I think are safe assumptions this is the perfect case for flexbox because as I said it lets you avoid explicit dimensions and use the flex property instead to control sizing this tells the browser the starting size that you want to use including the native content size and whether the item can grow bigger or smaller than the size to fit the space available so for the select menu and the button I want them to stay at their content width exactly not get bigger or smaller so I don't want them to flex with the text Fields I want them to stretch to take up whatever space is left after the select the button and all the margins have been accounted for and I don't have to do any math to figure out what value this should be I just tell them to flex and let the browser figure out the math so I can also at the same time that I do this keep the percentage widths in place for non-supporting browsers and add these Flex values on top as an enhancement the second problem with the original that I wanted to fix is that there's a slight misalignment of the fields across the line even though I set the same padding on all of them this shows two different browsers again I could fix this by adjusting all the paddings um but it is browser dependent so it's really annoying hard to get perfect a more reliable and easier fix is to just turn on Flex box for each field wout because Flex items across a row are equal height by default so with its wrapper a flex container each field will stretch to match the tallest one on its line so these two lines of CSS and pink fix the height mismatch in five seconds and actually you can write it as one line because you can leave the second off it's the default value so although the visual effect isn't huge in this case neither is the effort to polish up this form none of the flex box Chang changes that I made to the form have to be hidden from older browsers they simply override existing properties and browsers that understand them which makes it really easy to progressively enhance this form I9 and earlier we'll see the top version which looks a bit different but is still usable and just about everyone else will see the bottom version I think this enhancement is worthwhile to add because even though the flexbox form does use the same break points as the float original the fields inside are more responsive to their content so overall the layout of the fields looks more proportional inside each of these break points content driven breakpoints are better than device sized breakpoints but they are still a decision that you're um making based on what is best for hopefully the majority of your content but not every component or piece of content on every page at every moment flexbox can enhance your components to be more responsive within your break points the job form was just a demo but we do use flexbox in a similar Way live at booking.com on our customer service form which uses a fluid responsive layout using Flex the fields fill the full width of their container no matter its size switching from stacked to 2x two automatically as soon as they can fit um beside each other and by automatically I mean no media queries this is all of the CSS that's needed to create those two layouts there's no media queries um because the browser figures out the breako for you using Flex box the flex property again is simply an enhancement on top of the floating and the percentage uh width that control the layout of the form when flexbox isn't available so the starter non flexbox version of the uh form layout seen in i7 through 9 it has the same two layouts they just don't stretch to be full width but I think that this small difference is an acceptable tradeoff for being able to write just a few lines of CSS no media queries and being completely done with laying out an entire responsive form let me walk you through how this CSS works so first um we turn on flexbox using display Flex on the container that turns the form into a flex container and the child Fields into Flex items by default this puts the items horizontally on a single row but Flex wrap wrap allows them to wrap onto multiple rows as needed so if I didn't have Flex wrap wrap set um the fields would always stay on run one row no matter what even if content has to be cut off or they overflow out of their container but with flex wrap they will be stacked on narrow screens and then automatically switched to side by side when there's room for them to fit it's similar to changing Flex direction from column to row in a media query but without needing any media query so the breakpoint can happen automatically in a more natural spot with less CSS so the fields do say row orientation the whole time it's just that they may for form up to four rows when the viewport is narrow which then looks like one column so then the question is what makes them decide to wrap the browser wraps them when it can't fit them on one line but how does it know they can't fit at a certain point this is where their Flex values come in so let me Define the flex property first before explaining this particular value of the property so the flex property is set on Flex items to assign them a proportional size it affects either their width or their height whichever is the main size and that's the dimension along the main axis so the main axis is simply the um set by Flex Direction so Flex direction is set to row my main axis is horizontal and width is my main size if Flex direction is set to column my main axis is vertical and height is my main size and there's up to three components to a flex value as it's a shorthand property Flex grow means how much the flex item will grow relative to other items if there's extra space available Flex shrink means how much the item will shrink relative to others if there's not enough space and both Flex grow and flex shrink are set to unitless integers like 0 1 2 since they are specifying a proportion not an absolute value it's like the number of shares of extra space that they get Flex basis is the initial start starting Dimension before free space is added on or taken away from the item and it's set to any standard with their height value including Auto which basically sizes the item according to its content for example on the booking.com customer service form Flex basis is set to 40% um so that's the starting point uh each field will be 40% of the width of its container um and then the browser looks at the flex grow and flex shrink values to decide whether to get bigger or smaller than the flex basis value Flex shrink the second value set to zero doesn't let the field shrink smaller than 40% effectively this means that the most we can ever have an align together is two right because three or four 40% wide items are never going to fit on a line together so that's why the form only gets to um into a 2 x two layout at its widest Flex grow the first value set to one means that each field will get one share of any available extra width on a line and this is what ensures that the form is always full width because it um tells each field to stretch to take up whatever space is left over after the 40% Flex basis and the pixel margin and padding have been accounted for so basically what happens is when the viewport gets narrow the combination of the percentage Flex basis size and the pixel margin and padding makes two inputs add up to more than 100% which forces them to wrap and stack the same thing happens with the float version this is not a new sort of layout Behavior but with the flex value as an enhancement the flex grow piece of that value Flex grow set to one ensures that when the wrap happens each field stretches to fill the width perfectly rather than remaining 40% wide and again flexbox overrides the floating and the width values automatically so the flex property can be added on to the same rule without having to hide anything from non-supporting browsers so three extra lines flexbox CSS made this form much more responsive to the space available and all without having to use a media query another place on booking.com where we change the layout without a media query is within the map info windows that show when you click on a marker I had the task to add a message about the room price that you see being almost sold out and the logical place to put it seemed to be next to the price especially since there's often a big gap there and this is what that would look like the price and the message are visually connected and the message kind of leads you to the the call to action button so I like this but the problem is that there is not always a big gap there rack rate pricing long languages long currencies can all take up a lot of space in this case this is due to variable content but the same issue applies in responsive web design of course where the width that you have available in varies um that you have some sorry the width that you have available to put something in varies as the viewport width changes size so in both cases I have the problem of wanting to put something in a spot but not being sure if that spot is always big enough what I would like to happen is that the text sits beside the price if there's enough room and then when the space strengths below some minimum width that I set it drops down onto the following line and then it stretch just to take up the full width now without an explicit width on the availability message the red text making it float or inline block will not let its text wrap so this first image with the red text wrapping could not happen the text would want to stay all in one line and so it would always drop below the price table cell will let the text wrap within that area but it won't let the entire block wrap down below the price when there's not enough room um or when the space is just too narrow for that text to look good there so this second image with the red text below couldn't happen so that leaves flexbox which is kind of like The Best of Both Worlds and lets me have both of these languages with one piece of CSS or both of these layouts with one you know piece of CSS so I get the stretch and squish behavior of table cell um but it lets the boxes wrap if um if I tell it to and if it needs to based on the space available and again it does this without media qu varies so ie7 8 and9 users will simply see the Avail availability message always below the price which doesn't look bad or broken the few line of lines of flexbox code are then layered on top as an enhancement for the vast majority of users and flexbox is great for this sort of micro layout stuff managing the sizing and spacing of items within a component or module you can use flex blocks in a similar way and respons designs where you have a component that sometimes has room for its sub items to sit side by side and sometimes needs them to stack without you having to figure out at what point that happens another example of how Flex box can handle wrapping more elegantly is in what we call the mini info windows on our maps that show when you hover over a marker I used flexbox to lay out the review score and the price on opposite sides of the same line again I couldn't give either of these two blocks a width even in a relative unit of measurement because the length of the content in each can vary wildly without set widths um inline block would not move the price um the price block to the right side so that was out table cell worked fine without set widths but if the content was long the two pieces could overlap instead of the second block wrapping to new line which would be completely unacceptable that left floating and flexbox as my layout options floating worked but when the content was long and the price wrapped to a second line as in this screenshot down here with the long German words um it would stay right aligned which looks awkward so I decided to use both float for older browsers and then I overrode it with flexbox which lets the text wrap to the left Edge um more elegantly I didn't have to use modernizer and hide pieces of CSS from certain browsers flexbox just takes over if the browser understands it so no matter what the two blocks will appear side by side in all browsers and they will wrap when needed the wrapping and alignment of the text just isn't quite as Nic looking in non- flexbox browsers but that was going to happen whether or not I added flexbox here um I made a demo uh to show you how this improved wrapping Behavior can come in handy on responsive sites specifically this article header uses flexbox as an enhancement on top of display table cell to layout and align its various chunks of content um and it switches the layout automatically without a media query this header block is basically a a media block UI pattern that you see everywhere right with an image plus a block of text associated with it except here the text portion stretches to fill the whole width and the whole height available thanks to flex on the category the green block and align content on the multiple rows using Flex to push the date to the opposite side is a great enhancement for what happens when there's not enough room to fit both the category and the date on the same line such as when the viewport is very narrow or the content is very long or both there's lots of ways to align content to opposite sides of a line with the old existing CSS that we've had forever but if I used floating or text a line to push the date to the right side when the date needed to wrap it would wrap down to the right Edge just like in the mini info windows on the maps which looks kind of weird using Flex instead it wraps to the left side which looks a lot more natural um this is not the only alignment enhancement that Flex Blox can accomplish that no other CSS can produce I briefly showed you the Align content property on this this header but there are two other flexbox alignment properties that allow you to align content in new ways really simply which is invaluable in responsive designs where the content wraps differently at different viewport widths for instance flexbox can distribute an unknown number of items across an unknown um an area of unknown width or height such as making a nav bar full width with equal spaces in between all of the links if you wanted to make a nav bar like this you'd probably first turn to display table cell and you would be able to make the nav full width and um have the first and last Links at the edges and you could even make each of the link boxes equal in width to each other if used table layout fixed but you would discover that you could not get equal spaces between the text block of each link so if I do display table and table layout fixed on a UL it makes each Li the same width so they look equally spaced if they have backgrounds or borders but remove the backgrounds and borders and you see that the gaps actual um the gaps between the actual links text is not equal so longer links have smaller spaces around them shorter links have bigger spaces but flexbox can fix these unequal gaps really simply here is a simple nav bar from my flexbox demo site sores day. us um for the starter layout I used inline block to Center the links in a row under the logo they don't stretch full width but there's nothing broken a wrong looking and it works as a layout in in the responsive page but there's no reason why I can't add a few lines of flex box on top of this CSS to enhance the responsiveness of the nav further I simply added these two lines of flex BLX in pink to the existing rules the LI are still set to inline block but now they're Flex items too so I can take advantage of these new um alignment properties within Flex box such as justify content setting justify content to space between moves the first and last Li to the edges and it equally distributes the space uh remaining in between the other links so using justify content space between here is how the nav then looks on medium width screens the links stretch out in the flexbox version and they remain centered in the non- flexbox browsers now having the nav filling the full width looks great on medium width screens like this but on really wide screens it starts looking too stretched out I wanted to make it more responsive to this extra space so I decided to use flexbox to pin the first two links to the left side of the logo and the last two links to the right side of the logo again a pretty common responsive uh nav layout to do this I first added a media query for wide screens so you do sometimes need to still use media quaries with flex boox and I also added a link to the modernizer script because I need to feed some styles to only flexbox browsers in this particular case as you'll see in just a minute much of the time flexbox and fallback Styles can coexist as they did with the medium width version of the Navar that I just showed you but occasionally they'll conflict and you'll only want to apply a certain property if flexbox is in effect or not the modernizer script is perfect for this it can detect whether the browser does or doesn't support flexbox and whether it supports an old version or the current version and then it adds the appropriate classes to your HTML tag which you can use to scope the rules in your CSS if you don't like modernizer and you want to keep the feature detection in your CSS you can also use the at supports uh rule to detect whether the browser supports flexbox and feed rules only in that case to do something like this so at supports and modernizer are both good options for those rare cases when you do need to isolate your flexbox styles from your other CSS for my Navar here I used modernizer flexbox Class to scope this new rule to only flexbox browsers where I want the nav to move up on the to the same line as the logo non-supporting browsers will not use this rule um so they will still get the inline block centered nav beneath the logo only the flexbox version of the nav will move up now to move the last two links to the right side I simply set margin left Auto on the third link um the throw party link against scoped to only flexbox browsers and the reason that this works is that in flexbox if you set a margin in the main access to Auto it takes up all of the free space that's left um in that line so with margin left Auto on the throw a party link the browser places all of the extra space in the line to its left side effectively pushing it and all the stuff after it to the right Edge so I get the appearance of a split list without having to cheat and break it into two lists um in the HTML Which is less accessible and robust not so good for responsive web design where I'm trying to keep my HTML the same at all uh viewport widths this is a simple nav bar but thanks to a bit of flexbox it can make full use of the changing width flexbox increases its responsiveness as an enhancement where available flexbox is not only a great way to make better use of the changing widths in a responsive layout but also to make better use of the changing Heights so as the youport changes width your content wraps differently so you can't count on constant Heights for your content blocks Flex blocks can enhance the appearance of this variable height because it works in any direction so let's say that I want to uh show some social media sharing icons uh down the side of each article or media object and that media object content varies as does the viewport width which controls wrapping so the height of each varies and if I want to equally space the icons uh vertically to take up the full height I am out of luck I cannot explicitly set each of them to height 33% because the parent media object has no explicitly set height itself to base these percentages off of so uh percentage height value does nothing here but I don't need the height property with flexbox first I make the icon section and the content section Flex items with the default horizontal row alignment and I do this because I need them to be equal height and sibling Flex items are equal height by default thanks to the line items property set to stretch by default um you can't see it here because the icons are still top aligned within their section but if the two sections had background colors you would see that the icon section stretches to match the height of the content section so now the icon and the content section are equal height Flex items but the individual icon images are not Flex items because only children of a flex container become Flex items not all descendants but something can be both a flex item and a flex container so that's what I do I turn the icons section into a flex container that makes its three CH children icon images into Flex items but this time I set Flex direction to column to stack them vertically from top to bottom this doesn't change anything visually yet they already were stacked vertically but remember that Flex direction also controls the main axis with flex Direction column the icon's main axis is now vertical so if I use justify content space between to um it will equally space them over the main axis which is the height no matter how tall that is and here's the result each media object has a different height but the icons always span the full height with equal spaces in between to make this work with non- flexbox browsers you can use whatever technique you normally would to get the icon block to sit next to the content block such as display table cell or floating both of these can work um and exist with flexbox and the same CSS rules floating uh I mean flexbox just overrides uh the float and table properties and browsers that understand it and then in non-supporting browsers your the icons will be either top of line um with the text or vertically centered as a block the browsers that don't support flexbox have about 5% global market share so a few users will see the non-flex boox versions that I've shown you in these examples but none of those versions look wrong or broken just a little different which is already happening all the time anyway flexbox is simply an enhancement to make better use of the space especially between your break points it's not a true grid system system it wasn't designed to be so it's not the best choice for your overall page layout but it is a great choice for intelligently sizing um and aligning components and smaller chunks of content within the major page page sections flexbox also lets you visually rearrange content which comes in handy again on responsive sites where you're stuck with the same HTML order at all the sizes but you want to shuffle content around on different views and it's sometimes hard to make a block go where you want it to when you're tied to a certain Source order but Flex Blox makes this easier so remember the split nav bar I used relative positioning and a negative Top Value to move the nav bar up overlapping the same line as the logo which is fine but since the logo is not actually in the middle of the list the links on either side of it can overlap it if the browser window gets too small I avoid this with a media query but if the logo was actually moved in the flow to the middle of the list I wouldn't have to do this but I don't want to move the logo in the middle of the list in the HTML because on narrow screens I still want it to come before the nav with flexbox I can keep the logo in uh before the links in the HTML but move it visually and in the flow to the middle using the order property you set the order property on Flex items to specify which order you want the browser to lay them out um in their container regardless of the HTML order and the browser runs from the lowest numbers including negative to the highest so you can think of it like assigning the items a position number in a line the first two links I want to stay first so they need the lowest order value so I'll just leave them with the default of zero the logo I want to be next so it needs the next highest order value I gave it one the last two links need to come after the logo so they need the next highest order value I gave them two so now that the logo is part of the line not separate from it it won't work to just have margin left Auto on that uh third link as before because with every last bit of extra space in the line uh put to its left it will squish the logo over on the right side to fix this I can use two Auto margins and the browser will simply divide the extra space on the line evenly between the two um items with those margins so throw a party already has margin left Auto from before but I'll add oh sorry I'll add the same to the logo so half the extra space goes on the left side of the logo half of it goes on the left side of the throw a party link and thus the logos move to the center now in order to make this work I had to move the logo from outside the UL to inside at the same level as the other links that's because order only works um on siblings within the same Flex container you cannot move elements outside of their container coner to be before or after stuff that's outside the container this does make it limiting you have more sourcer order Independence than current layout methods um but you still don't have complete freedom to move anything anywhere this is perhaps a good thing because you don't want to go crazy moving everything around with the order property when you reorder content with flexbox you are only reordering it visually it does not change the screen reading order or the tab order so if the content that you're you're reordering contains text or tabbable content make sure that the HTML order is logical first and then use visual reordering um only if it's just decorative and doesn't change the meaning of the content um I'm running out of time but let me quickly give you a simple example of accessible reordering with flexbox so on this recipe the photo comes before the ingredients list in the HTML so that on the wider view I can float it beside the ingredients and the narrow mobile view just Stacks everything in the default HTML order but I could use the flexbox order property to move the photo from its HTML position before the ingredients to above the recipe title on mobile only and in this case this is not going to cause accessibility problems because there's no links in the photo to tab to and there's no text in the photo to be read by screen readers because I would give it null alt text because the recipe itself provides a text alternative so to move the photo in the style outside any media queries I set Flex direction to column to stack everything and I set um the order value of the image to negative one all the other Flex items inside the recipe container have the default order value of zero so negative one will move it to the top of the stack and then on the desktop view I simply turn off flexbox by setting the recipe's display back to block that puts the image back in the normal flow order where I can then float it to the right so there's no concern about flexbox support on desktop since I'm not using it there and any mobile browsers that don't support it will simply see the image before the ingredients as normal um I already showed you the GU Guardians job search form which doesn't use flexbox but their main site now does and they use flexbox to shuffle the stories around when you get to the wide view um they actually don't use the order property to do this um the flexbox lets you run content not just top to bottom and left to right but also bottom to top and right to left so this is another clever way that flexbox can improve responsiveness so definitely go to their site and check out their CSS to learn more about the um their sort of reordering I've shown you code for most of these examples but I don't think that the code is the most important part of learning flexbox I think the biggest obstacle to getting started with it is not being able to picture how to use it because you're stuck thinking in terms of um what was possible with floats and other old layout methods it was the same when we switched from tables to CSS and from fix to fluid um you had to make a mental shift to start thinking in terms of um the new possibilities um and approaches to Old problems flexbox lets you do lots of things that you haven't been able to do before and lots of things that you could do before but now in an even simpler way once you see what flexbox can do in the real world you can start picturing how to use it in your own work to solve real responsive web design problems today um flexbox can be tricky to wrap your head around at first but once you've learned it it's an incredibly quick cheap way for you to add more responsiveness to your components and it may sound weird to talk about enhancing responsiveness but I don't think that responsive web design is either on or off either your site is responsive or it's not there's always more that you could do to make a responsive site even more responsive to the different user settings um and the content within it flexbox is one of those things that you can do as I hope you have seen with these examples don't be afraid to add flexbox to your work because flexbox is not all or nothing you um you don't need to use it uh you don't need to use every single part of it to lay out every single thing on your site you can keep using Floats or table display or whatever it is you use to create layouts just add on flexbox in one spot to add one little enhancement and see how it can improve responsiveness on your site thanks very much [Music]

from
Must-Watch Talks, Flexbox
added
2026-10-10
likes
0

Must-Watch Talks › 2015: “Zoe M. Gillenwater, CSSConf EU 37:13”