Putting Flexbox into Practice (Fronteers)

84
FLEXBOX Zoe Mickley Gillenwater @zomigi Fronteers October 2013 PUTTING INTO PRACTICE

description

Putting Flexbox into Practice presentation for Fronteers conference, October 10, 2013. Slightly updated version of slides posted in September. Get links to the demo page and related resources at http://www.zomigi.com/blog/flexbox-presentation.

Transcript of Putting Flexbox into Practice (Fronteers)

Page 1: Putting Flexbox into Practice (Fronteers)

FLEXBOX Zoe Mickley Gillenwater @zomigi Fronteers

October 2013

PUTTING INTO

PRACTICE

Page 2: Putting Flexbox into Practice (Fronteers)

and I wrote these books on CSS:

I’m a web designer/front-end dev

Stunning CSS3: A Project-based Guide to the Latest in CSS www.stunningcss3.com

Flexible Web Design: Creating Liquid and Elastic Layouts with CSS www.flexiblewebbook.com

Presenter
Presentation Notes
[SLIDE CONTENT] I’m pretty proud of these books and think they stand up well over time…
Page 3: Putting Flexbox into Practice (Fronteers)

My portfolio site from 2000

Presenter
Presentation Notes
…but I don’t feel the same way about this web site that I created about 13 or so years ago. This is my first portfolio web site promoting my awesome web design skills Notice how circle is cut off on bottom? That’s because I designed background to exactly fit 800x600. Looks awful on bigger windows. Apart from that, design not so bad (flat design before its time, sweet rollover effect), but laid out with table…
Page 4: Putting Flexbox into Practice (Fronteers)

My portfolio site from 2000

Presenter
Presentation Notes
…as all sites were at time because we had no other way to create multi-column layouts Some of you have probably never created a table-based layout, but let me just say that they had a lot of weaknesses In 2003, started new job, new boss had heard you could create layouts without tables, just CSS, and wanted to try it. I knew about CSS for text formatting but that’s about it…
Page 5: Putting Flexbox into Practice (Fronteers)

2003: Introduced to floats

Presenter
Presentation Notes
…so I was blown away by the idea of pure CSS layouts too, read up on it, learned that table-free layouts primarily created with CSS floats By 2004 had switched to float-based layouts completely, got good at it
Page 6: Putting Flexbox into Practice (Fronteers)

Problems with float layout

Difficulty with containment Unwanted wrapping, aka “float drop” Visual location somewhat tied to HTML order No built-in equal-height columns No float:center

Presenter
Presentation Notes
But floats weren’t designed for full-page, multi-column layout, so I ran into limitations that made float-based layout difficult and frustrating sometimes For instance, having to deal with floats hanging out of their containers or wrapping when there’s not enough space Also, visual location somewhat dependent on HTML source order, because floats don’t move up, only over to one side And of course, the classic complaints that you can’t make separate floats match each other in height and can’t center a float Most of these things can be worked around in various ways, of course, but the techniques for doing so can be messy and confusing. They’re complications that have to be worried about and fiddled with every time, instead of features that just work.
Page 7: Putting Flexbox into Practice (Fronteers)

The nickname for the CSS Flexible Box Layout Module, a new layout mechanism and box model.

What is flexbox?

Presenter
Presentation Notes
CSS Flexible Box Layout module, called flexbox, solves a lot of these shortcomings One of many layout mechanisms added to CSS in last couple years Makes building fluid, responsive, and adaptive layouts much easier than our current layout methods, though you can use it on fixed-width layouts too Candidate recommendation since September 2012, so it’s quite solid and well-vetted now
Page 8: Putting Flexbox into Practice (Fronteers)

2009 display:box

2011 display:flexbox

Now display:flex

v.10

v.7

Which is which?

See also http://css-tricks.com/old-flexbox-and-new-flexbox/

* with -webkit- prefix

† with -ms- prefix

* *

* v.3+

*

Presenter
Presentation Notes
But before candidate recommendation, went through a lot of changes, and different browsers support different versions Can be hard to keep track of which is which, but display value is a great indicator, so when you’re looking at demos/tutorials online check that out so you can tell which version of syntax they’re using and which browsers it will thus work in
Page 9: Putting Flexbox into Practice (Fronteers)

Turn it on

display: flex

flex item flex item

flex container

plain old box

Presenter
Presentation Notes
To turn on flexbox, set display:flex on wrapper to make it [CLICK] “flex container” and indicate that you’re using new box model on its children [CLICK], called “flex items” Note that only direct children are flex items [CLICK], not all descendants. Can be limiting, but you can nest flex containers by making a flex item a flex container too.
Page 10: Putting Flexbox into Practice (Fronteers)

flex-direction specifies orientation of flex items’ layout

row (default)

row-reverse

column

column-reverse

Presenter
Presentation Notes
Once I’ve created my flex container I need to specify flow direction of flex items within it Flex items can be laid out side by side or stacked vertically. Default is side by side running from left to right, but can change this using flex-direction property on flex container. As you can imagine, this makes flexbox great for RWD, since I can change orientation easily at different screen sizes
Page 11: Putting Flexbox into Practice (Fronteers)

Demo site:

www.smoresday.us Use Chrome, Opera, Safari 7, or IE 10 for full effect (Zoe really loves s’mores)

Presenter
Presentation Notes
To demonstrate these flexbox properties I created a site devoted to s’mores, because they’re delicious. How many of you have had a s’mores? [IF NOT MANY] It’s a dessert that you make typically when you go camping, by roasting a marshmallow over fire then sandwiching it with chocolate between graham crackers. I’m kind of obsessed with coming up with crazy variations of this. Now, obviously, since this is a demo of flexbox, you ought to view it in browser with good flexbox support, preferably Chrome or Opera (Safari 7 and IE 10 are almost spot-on), but there are a few fallbacks in there for non-supporting browsers, as we’ll talk about later
Page 12: Putting Flexbox into Practice (Fronteers)

Demo: horizontal navigation

1. Turn <ul> into flex container: .list-nav { display: flex; flex-direction: row; /* default */ }

2. Children <li> become flex items laid out on single horizontal line

Presenter
Presentation Notes
We’ll go over the flexbox CSS for various pieces of the s’mores builder page throughout the rest of this presentation, but a simple way to see how display:flex and flex-direction work is with main nav I built site mobile-first, so at narrow widths I wanted links all in row under logo. Set display:flex on .list-nav, which is the <ul>. This in turn sets flex-direction to default row, so children <li> become flex items laid out on single horizontal line.
Page 13: Putting Flexbox into Practice (Fronteers)

Demo: horizontal navigation

Before

After

Presenter
Presentation Notes
Here’s how main nav then looks on narrow screens Links went from stacked to horizontal
Page 14: Putting Flexbox into Practice (Fronteers)

I can do the same thing with display: inline.”

What’s the big deal?

Yes, you can.

We’re just laying the groundwork for the cool stuff that’s coming.

Baby steps.

Presenter
Presentation Notes
And you’re probably not impressed with those screenshots, because you can easily put links on same line with display:inline or others Totally true—simply laying groundwork for the cool stuff that’s coming. I’m just showing you how to create flex container, but we haven’t really started manipulating its flex items yet. We will.
Page 15: Putting Flexbox into Practice (Fronteers)

How the CSS might really look

.list-nav { display: -webkit-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-box-direction: normal; -webkit-box-orient: horizontal; -ms-flex-direction: row; -webkit-flex-direction: row; flex-direction: row; }

2009 Android

Safari 3-6

2011 IE 10

current Chrome Firefox Opera

Safari 7 Blackberry

Presenter
Presentation Notes
But now that I’ve shown you one code sample, I ought to point out that CSS in real world might look a lot more complicated because of browser variants. This shows two properties using all syntaxes and prefixed versions for browsers currently in use. Chrome and Firefox only ones that support non-prefixed current syntax. I’m not saying I think you ought to include all of these variants, but this is what the simple code sample that I showed you earlier would look like if you did.
Page 16: Putting Flexbox into Practice (Fronteers)

Keeping track of variants

Flexy Boxes code generator shows old and new syntaxes: www.the-echoplex.net/flexyboxes/

Let Sass or LESS do it for you, for instance: https://github.com/mastastealth/sass-flex-mixin https://gist.github.com/cimmanon/4461470

The -prefix-free script can do some of it for you: http://leaverou.github.io/prefixfree/

Presenter
Presentation Notes
Tough to keep track of which properties and values correspond, so one tool I like to use is Flexy Boxes. Flexbox code generator, includes legacy, look at generated CSS to see equivalents. If you use Sass or Less, use flexbox mix-in to create all the variants for you, or at least the variants you want, because I’m definitely not saying you need to add all of them. Another option is -prefix-free script, but keep in mind only adds prefixes to whatever syntax you write. You have to write in different syntax manually, w/out prefixes, if you want script to create prefixed versions of that different syntax. Gets you part way there. (Useful if already using –prefix-free for something else.) I’m kind of undecided on whether you should use the old syntaxes. Like most things, I think it sometimes depends on the project and which pieces of flexbox you’re utilizing.
Page 17: Putting Flexbox into Practice (Fronteers)

But for the sake of readability, I’m omitting them from the code samples on these slides. You can see them in the live demo.

Now back to flex-direction.

Use the variants you want.

Presenter
Presentation Notes
The bottom line is this: you go ahead and use whichever variants you want, or none of them. But, to keep the CSS I show you from being super long and hard to read, I’m omitting all the prefixed versions from the code samples on these slides. That doesn’t mean I’m saying you shouldn’t use any prefixed versions in the real world, I’m just trying to keep things simple and clear here. I have included most of them in the live demo, so you can see them if you poke around in the CSS. Now that that’s all out of the way, let’s get back to talking about flex-direction.
Page 18: Putting Flexbox into Practice (Fronteers)

Setting a point of reference

Main axis

Cross axis

(for flex-direction: row)

Presenter
Presentation Notes
Even though I don’t have to manually set flex-direction to row since it’s the default value, it’s important to keep in mind what the flex-direction is, because it determines which direction will be what flexbox calls the main axis and which will be cross axis. Row = flex items flow horizontally => main axis, and width is main dimension. Vertical is cross axis and height is cross dimension. This is all reversed when flex-direction:column. These axes important because affect all other flexbox properties that will come later. Flexbox is so flexible because its properties can make items lay out and align in any direction, but it needs to basically know at what point it’s supposed to start and move out from, and in which direction.
Page 19: Putting Flexbox into Practice (Fronteers)

flex-wrap controls whether flex items can lay out on multiple lines and which direction new lines are stacked in

wrap (for row)

wrap (for column)

nowrap (default; for row)

wrap-reverse (for row)

Presenter
Presentation Notes
Also needs to know whether to lay out flex items on single line (default) or wrap to multiple lines. Controlled by flex-wrap. Also controls which direction new lines stack in. For row, do I want rows stacked top to bottom or bottom to top? For column, do I want columns stacked left to right or right to left? This property sets that.
Page 20: Putting Flexbox into Practice (Fronteers)

Problems with flex-wrap

Firefox doesn’t support it yet No browser supports 2009 equivalent box-lines property

Limited control of where breaks occur without support for break-before/break-after properties (only IE 10 and Opera support them)

Presenter
Presentation Notes
flex-wrap is extremely useful, but major problem with it is that Firefox doesn’t support it. It doesn’t support old box-lines property either, so you can’t feed it anything to work around this lack of support. In fact, no browser ever supported box-lines, so if you’re including 2009 syntax for benefit of Safari and Android, you’ll be out of luck if you want flex items to wrap. Another issue is that you have some control but not complete, iron-clad control over where breaks occur without support for break-before and break-after properties. Not part of flexbox spec, but they’d be very useful in conjunction with flexbox. Unfortunately only IE 10 and Opera support. So, I’m still going to show you how to use flex-wrap in examples, because it’s so essential, but lack of Firefox support means you probably can’t use it just yet
Page 21: Putting Flexbox into Practice (Fronteers)

Summary: setting the stage

1. Create flex container using display:flex 2. Set its flex-direction to control

orientation (horizontal or vertical) 3. Set its flex-wrap to control whether and in

which direction to wrap (Or, set flex-flow as shorthand for flex-direction and flex-wrap)

Presenter
Presentation Notes
But flex-wrap is basically third piece of what we need to set the stage when firing up flexbox [SLIDE CONTENT]
Page 22: Putting Flexbox into Practice (Fronteers)

.builder

.component

.gallery

.gallery-item

Mobile block layout

.action

Presenter
Presentation Notes
Let’s start digging into how I used these properties on s’mores site Not much need for flexbox at default mobile-first styles, shown here. Block layout takes care of stacking, single column. But wider, S’mores Builder page has two main sections that need layout, the builder form containing four component boxes and an action box at bottom, and the gallery of s’mores combinations containing bunch of gallery-item boxes.
Page 23: Putting Flexbox into Practice (Fronteers)

Add flexbox for larger widths

No need to put within media query—it can “kick in” whenever space allows (auto breakpoints!) 1. Create flex container:

.gallery { display: flex; flex-wrap: wrap; margin-left: -20px; }

Presenter
Presentation Notes
As viewport gets wider, I want to start taking advantage of space and make some of these items sit side by side, so I’ll add flexbox to handle this I don’t have to put this in media query—I put it in default styles outside media queries, and it just kicks in whenever space allows. Kind of like browser is figuring out content-driven breakpoints for you. Here’s CSS creating flex container for gallery section
Page 24: Putting Flexbox into Practice (Fronteers)

Add flexbox for larger widths

2. Size flex items: .gallery-item { flex: 1 0 200px; margin: 0 0 20px 20px; padding: 20px; }

Presenter
Presentation Notes
For children flex items (dark brown boxes), don’t need to set explicit widths, but instead use flex property to specify their proportional size and let items resize to fit space
Page 25: Putting Flexbox into Practice (Fronteers)

This is where flexbox gets flexible.

And kinda confusing.

The flex property

Presenter
Presentation Notes
This property is one of the foundations of flexbox, big part of what makes it so powerful But, can be difficult to fully understand at first, so let’s break it down
Page 26: Putting Flexbox into Practice (Fronteers)

Defining the flex property

Makes flex items change their width or height (whichever is dimension along main axis) to fit available space

Shorthand for 3 properties: flex-grow flex-shrink flex-basis

Presenter
Presentation Notes
Flex property set on flex items and affects either width or height, whichever is main dimension along main axis. Gallery items are horizontal, so flex will affect their widths. Three components to flex value, which is a shorthand property: flex-grow, flex-shrink, and flex-basis
Page 27: Putting Flexbox into Practice (Fronteers)

Defining the flex property

flex-grow how much flex item will grow relative to other items if extra space is available (proportion of extra space that it gets)

flex-shrink how much item will shrink relative to others if there is not enough space (proportion of overflow that gets shaved off)

flex-basis the initial starting size before free space is distributed (any standard width/height value, including auto)

Presenter
Presentation Notes
flex-grow means how much flex item will grow relative to other items if extra space is available (or, proportion or number of shares of extra space that it gets) flex-shrink means how much item will shrink relative to others if there’s not enough space (or, proportion of the overflowing pixels that it will have to get lopped off of itself to get everything to fit again) flex-basis is the initial starting dimension before free space is added on or taken away from the item. Can be set to any standard width/height value, including auto keyword.
Page 28: Putting Flexbox into Practice (Fronteers)

Breaking it down

.gallery-item { flex: 1 0 200px;

flex-grow give every item 1 share of extra width

flex-shrink don’t let the items shrink at all (but they wouldn’t anyway due to flex-wrap)

flex-basis start them out at 200 pixels wide (basically, min-width)

Presenter
Presentation Notes
So for .gallery-item flex value, I set flex-grow to 1 because I want each to get 1 share of extra width Setting flex-shrink to 0 means don’t let the items shrink at all if they can’t all fit, but flex-wrap won’t let items shrink anyway because once there’s not enough room to include a certain number on the line, it will wrap them instead of shrinking them. That means flex-basis basically becomes min-width. Each item will start out at 200px, the browser will put as many 200px boxes as it can on a line, then wrap, and then will expand each if needed to fill up extra width in line. They’ll always be at least 200px wide.
Page 29: Putting Flexbox into Practice (Fronteers)

Let’s see it flex live

Presenter
Presentation Notes
TIME SHOULD BE 10:05 Flex is one of those things you just have to see live, so let’s switch to Chrome now to take a look [CHROME: Start with 1 gallery item to a line, widen slowly] Remember, none of CSS controlling these layout changes is inside media queries, don’t have to define different percentage widths at different breakpoints, which is especially nice here because margin is in px (Similar to setting items to inline-block, but with flexbox they expand to fill line, instead of leaving gap on ends of line until there’s enough room for another box to move up)
Page 30: Putting Flexbox into Practice (Fronteers)

Single-digit flex values

Common to see flex: 1 in demos flex: [number] is equivalent to flex: [number] 1 0px

Be sure you really want flex-basis to be 0 When wrap on, essentially min-width 0px therefore means items can shrink to 0px If everything can get down to 0px, nothing ever

has a reason to wrap

Presenter
Presentation Notes
When you’re reading about flexbox, often see single-digit flex values in examples Fine to use single digit, but you need to know that that digit becomes flex-grow value When flex-shrink left off it gets set to 1, and when flex-basis is left off it gets set to 0px Be careful with this, because you may not want flex-basis to be 0. Remember that when wrap on, basis => min-width, so you’re saying you’re fine with your items shrinking all the way down to 0px. And if everything can get down to 0px, and doesn’t have other stuff like margins to give it dimension, nothing ever has a reason to wrap.
Page 31: Putting Flexbox into Practice (Fronteers)

My first attempt

Zoe’s Brain Said:

“Since .action starts out at 100%, it won’t have space to sit on the first line with the content preceding it, and will wrap to a second line.”

.component { flex: 1; }

.action { flex: 1 1 100%; }

The expected outcome:

Presenter
Presentation Notes
I learned this the hard way when trying to lay out the builder section of the page, shown here. Four tan boxes have .component class, bar below with field to name your s’mores and button has .action class. My thought process went like this: I want all four components to be same width, so I’ll set flex to 1 for each, and to force action section to new line, all I have to do is give it flex-basis of 100%, because if it’s 100% wide it won’t fit with anything else, so it will wrap to a second line. Perfect.
Page 32: Putting Flexbox into Practice (Fronteers)

Flexbox fail

Presenter
Presentation Notes
And this is what I ended up with—everything squished and overlapping I was totally baffled Angry comments were written into the CSS during this period
Page 33: Putting Flexbox into Practice (Fronteers)

My first attempt

Reality:

Since it’s fine for each .component to shrink to only 0px wide, a 100% wide element can and will sit on the same line as all the components.

.component { flex: 1 1 0px; } .action { flex: 1 1 100%; }

Presenter
Presentation Notes
What was happening, was that by setting flex to 1, I was inadvertently setting flex-basis to 0, which allowed all four components to shrink down to 0px wide (This was early skeleton of page, before I added any borders, padding, or margin onto component boxes) If they take up literally no space, then it’s perfectly fine for .action to sit on the same line with them, and that’s exactly what happened. (It shrunk them to 0px only because it had a 100% box it was trying to fit too—my flex value of 1 told browser this was OK to do if it needed to.) (Same problem with gallery initially, before setting flex-basis of each item to 200px—I thought they would wrap when they hit longest word, but they just kept shrinking and letting content overflow, and all stayed on one line)
Page 34: Putting Flexbox into Practice (Fronteers)

Forcing the wrap

Fixed:

.action will always wrap to new line, and .components will wrap to additional lines when there’s less space than their combined flex-basis values (plus margin, etc.).

.component { flex: 1 1 200px; } .action { flex: 1 1 100%; }

Presenter
Presentation Notes
But, changing flex-basis to 200px meant that components would start out at that width, so when browser would go to add 100%-wide .action section, it would never have room for it on a line with any components and would always wrap it to new line.
Page 35: Putting Flexbox into Practice (Fronteers)

Live demo time again

Presenter
Presentation Notes
Let’s look at builder section in Chrome now [CHROME: Start with components stacked, widen slowly] Again, none of this is inside media queries, all controlled with those same few lines of CSS [When at layout with 3 components on top line and 4th below] I’m fine with this layout, because these 3 components are the 3 essential parts of traditional s’mores and this “accessories” box is crazy extras, so it makes sense for it to be separated out. (If I didn’t like this, I could change flexbox CSS in a media query, of course)
Page 36: Putting Flexbox into Practice (Fronteers)

Why flex is great

Presenter
Presentation Notes
Being able to use flex has several advantages over having to set explicit widths or heights
Page 37: Putting Flexbox into Practice (Fronteers)

Less need for media queries

Layout changes that would previously have been hardcoded into a media query can now be done on the fly when browser determines stuff can fit

Presenter
Presentation Notes
You’ve already seen how dramatically layout can change without having to create different versions within multiple media queries. Here are the four different layouts builder section goes through, all controlled by same few lines of CSS outside of the first media query You don’t have to figure out where to put the breakpoints and what crazy percentage widths to assign to your boxes within each breakpoint, browser does all that. (You will still need media queries, and I still love media queries, but it’s nice any time you can automate things and keep your CSS simpler.)
Page 38: Putting Flexbox into Practice (Fronteers)

Flex adjusts for margin

.component { width: 25%; margin-left: 20px; }

.component { flex: 1 1 200px; margin-left: 20px; }

The boxes won’t all fit Works like a charm

box-sizing only takes care of padding and border added on to width, not margin

Presenter
Presentation Notes
Flex also adjusts widths to accommodate margins. box-sizing is used frequently nowadays to let you mix pixel padding and borders with percentage widths, but doesn’t apply to margin For instance, if I was to try to make four components each 25% wide with 20px left margin, they wouldn’t all fit. The margin is added on. But with flex, the margin is accounted for in calculating how much space is available, and all four components can fit perfectly.
Page 39: Putting Flexbox into Practice (Fronteers)

Flex adjusts for quantity of items

Great for sites with dynamic or frequently changing content blocks, e.g.: News stories on home page vs inner page Product or feature tiles Pricing page with plans side by side

Makes HTML/CSS more modular—an item can move anywhere and adjust in size as needed

Presenter
Presentation Notes
Browser would also make them fit if I added or removed items from HTML, without me having to adjust any CSS This makes flexbox really useful on sites where the number of blocks of content may change frequently, or dynamically based on user interaction, or based on section of site you’re in. Maybe on your home page you have three blocks sitting side by side for three features of your widget that you want to highlight, but on your features page you want to show five feature blocks. And then a month from now, you boss decides to add a sixth block. Don’t have to change widths in CSS or use different classes on same items when in different sections of the site—flex property of flexbox can take care of this for you. Makes your HTML and CSS more modular, move item anywhere within site and have it adjust in size automatically
Page 40: Putting Flexbox into Practice (Fronteers)

Flex can combine different units

Items measured in different units can sit side-by-side and all fit perfectly

Pixels Ems Mystery percentage

Presenter
Presentation Notes
Flex is great to use in hybrid layouts, where you’re using different units of measurement across a line Like here—I want text field to stretch to remaining width of its line, but I have no idea what width value to give it [CLICK], because content before it has widths in mix of pixels and ems, and parent box is some changing percentage of the page
Page 41: Putting Flexbox into Practice (Fronteers)

Flex can combine different units

Set only the text field to flex: .component li:last-child { display: flex; } .component .other-name { flex: 1; }

Presenter
Presentation Notes
Using flexbox, I simply use flex property to tell text input (.other-name) to take up all the remaining space. Radio button and label are flex items too, since I set their parent <li> to a flex container, but I don’t set them to flex, so they just size to their content or pixel dimensions. Only text input flexes, so if parent component box is narrow or wide, input always stretches to fill rest of the width on line.
Page 42: Putting Flexbox into Practice (Fronteers)

Flex can be proportional

Setting flex-grow/flex-shrink to different values can make flex items size themselves relative to each other

flex: 1; flex: 1; flex: 2;

Presenter
Presentation Notes
Another really cool thing about flex is that it can make siblings have proportional sizes to each other If I set two boxes to flex:1 and one box to flex:2, flex:2 box will be twice as wide as others. Browser first allocates pixels to padding and margins, then sees how many left for flex widths and gives 2px to flex:2 box for every 1px it gives to each of the flex:1 boxes. Think of it like grid units in CSS framework. This red box is 2 grid units wide, as if I had set a class of span2 or something on it, while others are only 1 grid unit each. It’s just that these grid units are totally flexible and determined by the browser, instead of me having to calculate them.
Page 43: Putting Flexbox into Practice (Fronteers)

But be careful!

Having widths be in multiples of each other only works if flex-basis is 0 If all start out 0px, then all the width on the line is extra, so the flex:2 item gets twice as much width as the others and is thus twice as wide as the others

flex: 1 0 0px; flex: 1 0 0px; flex: 2 0 0px;

Presenter
Presentation Notes
But you have to be careful with this, because it only works as you expect if flex-basis is 0, as it is when you’re using single-digit flex values. This is because if all the boxes start out at 0px, then all the pixels on the line are extra, so flex:2 item gets twice as many of these pixels added on to 0 and is thus twice as wide as the others
Page 44: Putting Flexbox into Practice (Fronteers)

If flex-basis isn’t 0px…

…the widths may not end up as you expect The third box gets twice as much of the extra, but that doesn’t make it twice as wide overall

flex: 1 0 10px; flex: 1 0 10px; flex: 2 0 10px;

10px + 5px extra = 15px 10px + 5px extra = 15px 10px + 10px extra = 20px

if 50px available

Presenter
Presentation Notes
If flex-basis isn’t 0, the flex:2 item won’t necessarily be twice as wide as the flex:1 items. Browser will still give it 2px for every 1px it gives to the others, but it will be adding these pixels onto starting widths. For instance, let’s say total width available on this line is 50px. If flex-basis:10px for all three boxes (30px total), that leaves only 20 extra px to divide between them in ratio of 2:1, so each flex:1 box gets 5px extra and flex:2 box gets 10px extra (twice as much). That means each flex:1 box will be 15px wide (10px flex-basis plus 5px extra) and flex:2 box will be 20px wide (10px flex-basis plus 10px extra). 20px is not twice as wide as 15px. That’s science. This isn’t knock on flex, just a detail about it that most online tutorials leave out, which can trip you up if you don’t understand why it’s happening. Flex is still awesome.
Page 45: Putting Flexbox into Practice (Fronteers)

While support improves, consider using flexbox now on small page components as progressive enhancement.

Here are a few ideas.

You can use it now

Presenter
Presentation Notes
That gives you taste of how flexbox can be used to create entire page layout But, with browser support where it’s at, probably don’t want to use flexbox for entire layout on live site just yet However, you could use it now in smaller ways as progressive enhancement Let me show you few examples where flexbox could be used on components of page rather than whole page layout in a way where non-supporting browsers still get acceptable fallback experience
Page 46: Putting Flexbox into Practice (Fronteers)

Single-line, full-width form

All items on same line Text input(s) stretches to fill remaining space All items vertically centered or equal height

Presenter
Presentation Notes
Sometimes you’ll have a simple form with only one or two fields that you want to stretch across single line, full-width, with all items either vertically centered or equal height Common for site search and login as shown here, also email subscription, product listing in an order form, etc. On s’mores site, I wanted to use this layout for .action section
Page 47: Putting Flexbox into Practice (Fronteers)

Form without flexbox

.action { text-align: center; }

.action * { display: inline; /* default */ vertical-align: middle; }

Presenter
Presentation Notes
W/out flexbox, can set each item to inline or inline-block and use vertical-align to get everything centered…
Page 48: Putting Flexbox into Practice (Fronteers)

Form without flexbox

All items on same line Text input stretches to take up remaining space All items vertically centered or equal height

X

Presenter
Presentation Notes
…but that doesn’t make text input stretch to fill line
Page 49: Putting Flexbox into Practice (Fronteers)

Form with flexbox

.action { flex: 1 1 100%; display: flex; align-items: stretch; /* default */ } .action input { flex: 1; } .action input, .action label { margin-right: 10px; }

Presenter
Presentation Notes
W/ flexbox, just set input to flex and leave label and button at their default widths based on the length of their text, and input will take up whatever space is left A nice bonus to creating flex container: all items (label, input, button) stretch to height of tallest one (button). Due to align-items property being set to stretch by default on flex containers.
Page 50: Putting Flexbox into Practice (Fronteers)

align-items aligns flex items in cross axis

flex-start flex-end

center baseline

stretch (default)

foo foo foo

Presenter
Presentation Notes
align-items property, set on flex container, aligns flex items in cross axis. This form uses default flex-direction:row = cross axis is vertical => align-items affects items’ vertical alignment Finally, equal-height columns and vertical centering, two of the most stupidly impossible effects for CSS, are as simple as setting a property!
Page 51: Putting Flexbox into Practice (Fronteers)

Form with flexbox

All items on same line Text input stretches to take up remaining space All items vertically centered or equal height

Presenter
Presentation Notes
Here’s how .action section looks with input flexing to fill line This accomplishes all of the criteria I had for this design pattern, but having label stretch to height of button/input doesn’t look great
Page 52: Putting Flexbox into Practice (Fronteers)

Override alignment on label

.action label { align-self: center; }

Presenter
Presentation Notes
So, all I gotta do is set align-self to center on the label to override its align-items value of stretch, and then it will be vertically centered while other two items match in height The align-self property has same values as align-items, it just applies to individual flex items while align-items is set on container and applies to all flex items as a group W/ align-items and align-self, you have total control over alignment now
Page 53: Putting Flexbox into Practice (Fronteers)

Combine the two

.action { flex: 1 1 100%; display: flex; text-align: center; /* fallback */ } .action input { flex: 1; } .action label { align-self: center; } .action input, .action label { margin-right: 10px; }

Presenter
Presentation Notes
For non-supporting browsers, form can fall back to appearance where everything’s on one line but not full-width, as we saw earlier, by simply adding back in text-align:center to the .action wrapper. Won’t have any affect on flexbox-supporting browsers since they’re stretching to fill the line, and non-supporting browsers will just ignore flexbox properties/values => coexist peacefully (I’m highlighting flex properties in red in these examples so you can see that’s it’s only a tiny bit more CSS to add flexbox as progressive enhancement)
Page 54: Putting Flexbox into Practice (Fronteers)

Another option: stack, center

.action {

flex: 1 1 100%;

display: flex;

flex-wrap: wrap;

align-items: center;

text-align: center; /* fallback */

}

.action input {

flex: 1;

display: block; /* fallback */

width: 100%; /* fallback */

box-sizing: border-box; /* fallback */

}

.action button {

flex: 1 1 100%;

margin-top: 10px;

}

Presenter
Presentation Notes
On narrow screens, a different fallback approach might be to stack and horizontally center the items, then add a few flexbox properties to enhance appearance in supporting browsers I can set input to display:block and width:100% so that on non-supporting browsers it will take full line, but flex:1 on it will effectively override this and let input flex to fit next to label in flexbox-supporting browsers
Page 55: Putting Flexbox into Practice (Fronteers)

Narrow version

Non-flexbox fallback version Flexbox version

Presenter
Presentation Notes
Here’s what that looks like in non-supporting and flexbox browsers See, input on own line and full-width in fallback version, but sits next to label in flexbox version, and I didn’t have to hide either of these conflicting chunks of CSS from the other browser (nice, makes progressive enhancement easier)
Page 56: Putting Flexbox into Practice (Fronteers)

Add Modernizr as needed

Flexbox and fallback styles can often co-exist, but sometimes need to isolate them

Modernizr can add flexbox, no-flexbox, and flexbox-legacy classes to do this

Example: add margin between label and input only if flexbox is on: .flexbox .action label { margin-right: 10px; }

Presenter
Presentation Notes
Much of the time, flexbox and fallback styles can coexist like this, but occasionally they’ll conflict, you’ll only want to apply certain property if flexbox is in effect, etc. Modernizr script perfect for this, can detect whether browser doesn’t support flexbox, supports the old version, or supports current version, and then it adds appropriate class to html tag In the case of the .action section, the only tiny piece I needed to hide from non-flexbox browsers was right margin on label—only should apply if label and input on same line, screws up horizontal centering when label on its own line in non-supporting browsers [IF TIME IS BEFORE 10:20: Live demo changing layout of .action]
Page 57: Putting Flexbox into Practice (Fronteers)

Full-width nav bar

Requirements: All links on same line First link flush left, last link flush right Equal spaces between all links

Using display:table-cell can do full-width but not equal spaces

Presenter
Presentation Notes
TIME SHOULD BE 10:20 A similar design challenge to the full-width form is the full-width nav bar, but here, don’t want items themselves to stretch, just space themselves out to span full width (Sort of thing that’s easy in Photoshop but hard on real web pages) Using display:table-cell can get you the full-width part but can’t do the equal spacing in between links
Page 58: Putting Flexbox into Practice (Fronteers)

Nav with flexbox

.list-nav { display: flex; justify-content: space-between; margin: 0; padding: 0; list-style: none; } .list-nav li { /* no flex & no width = shrinkwrap */ text-align: center; }

Presenter
Presentation Notes
But if I make <li> elements flex items but not flex, so they stay at size of text, I can then set justify-content property to space-between to move first and last items to edges and equally distribute remaining space in between links
Page 59: Putting Flexbox into Practice (Fronteers)

justify-content aligns flex items along main axis

space-around

flex-end center

flex-start (default)

space-between

Presenter
Presentation Notes
justify-content property aligns flex items along main axis, which in this case is horizontal flex-start is default value, but again, space-between is what we want here for full width with equal spaces
Page 60: Putting Flexbox into Practice (Fronteers)

Combine with inline-block

.list-nav {

display: flex;

justify-content: space-between;

margin: 0;

padding: 0;

list-style: none;

text-align: center; /* fallback */

}

.list-nav li {

display: inline-block; /* fallback */

padding: 0 .5em; /* fallback */

text-align: center;

}

.list-nav li:first-child { padding-left: 0; }

.list-nav li:last-child { padding-right: 0; }

Presenter
Presentation Notes
I can use both inline-block and flexbox together on the nav so that items will be centered in non-flexbox browsers and full-width in flexbox browsers Don’t need to hide anything here using Modernizr classes
Page 61: Putting Flexbox into Practice (Fronteers)

Non-flexbox fallback version

Flexbox version

Combine with inline-block

Presenter
Presentation Notes
And here’s how nav looks on medium-width screens. Fallback version doesn’t attempt to imitate full-width, but there’s nothing broken/wrong-looking with it being centered Now, if your links happen to all be about same # characters, or mirror each other, like in this nav where I have short links on outside and long links inside…
Page 62: Putting Flexbox into Practice (Fronteers)

Combine with table-cell

.list-nav {

width: 100%; /* fallback */

display: table; /* fallback */

display: flex; /* override display:table for flexbox browsers */

justify-content: space-between;

}

.list-nav li {

display: table-cell; /* fallback */

padding: 0 .5em;

text-align: center;

}

.list-nav li:first-child {

padding-left: 0;

text-align: left; /* fallback */

}

.list-nav li:last-child {

padding-right: 0;

text-align: right;

}

Presenter
Presentation Notes
…you can probably get away with using display: table-cell as your fallback instead. It will make nav full-width, so your fallback will look very similar to flexbox version. Table-cell can’t actually do equal spaces (because table cells sized relative to content length, so if content is longer, padding within cell will be longer => bigger gaps around longer links), but if links are same length, you’ll inadvertantly get spaces that are almost equal, so it may look fine to the naked eye (Or it may look so close as to be annoying to the designer eye—you’ll just have to try it and see what it looks like with your nav’s words) Note that I have both display:table and display:flex set on .list-nav. Don’t have to hide from each other because display:flex overrides in browsers that understand it, and browsers that don’t just keep using display:table
Page 63: Putting Flexbox into Practice (Fronteers)

Variation: pagination

Wide view: all links on same line, centered Set justify-content:center

Medium view: all links on same line, full-width, equal spacing Set justify-content:space-between

Presenter
Presentation Notes
Variation on full-width nav bar is pagination. Mine looked too stretched out on really wide screens, so I can keep it centered there, but looks good full-width on medium screens, as shown here. Just like with the nav, I simply use justify-content: space-between to do this.
Page 64: Putting Flexbox into Practice (Fronteers)

Variation: pagination

Narrow view: two lines with “previous” and “next” links on first row, full-width Set flex-wrap:wrap Set justify-content:space-between Use order property to move “next” link up

Presenter
Presentation Notes
On narrow screens, I can keep it full-width, but it would be cool to move previous and next links up to their own row—but I don’t want to touch the HTML to do this, next link still last in pagination <ul> Flexbox can do this. Let me quickly walk you through the CSS.
Page 65: Putting Flexbox into Practice (Fronteers)

Visual reordering with flexbox

1. Make “previous” link come first visually, “next” link second, and all the rest third .pagination li { order: 2; display: inline-block; /* fallback */ } .pagination li:first-child { /* “Previous” link */ order: 0; text-align: left; } .pagination li:last-child { /* “Next” link */ order: 1; text-align: right; }

Presenter
Presentation Notes
I set order property on flex items to specify which order I want browser to lay them out on the page, regardless of HTML order Browser runs from lowest numbers (including negative) to highest, so previous link comes first with order:0, next link comes second with order:1, and all the rest links come third with order:2 This moves next link right after previous, visually, but we haven’t done anything yet to force a new row after next link
Page 66: Putting Flexbox into Practice (Fronteers)

Visual reordering with flexbox

2. Force links to wrap after “next” link by making it and “previous” link take up 100% of the first line together .flexbox .pagination li:first-child, .flexbox .pagination li:last-child { width: 50%; } .pagination { display: flex; flex-wrap: wrap; justify-content: space-between; text-align: center; /* fallback */ }

Presenter
Presentation Notes
To do that, I turn on flex-wrap on flex container Then set previous and next links to 50% wide each, so together they take up 100% of a line, which means rest of links have to wrap onto second line. Scoped this rule to only flexbox browsers, because only makes sense for previous/next links to have 50% width if flexbox is wrapping them onto their own line. (Someday we’ll do this with break-after: always instead, but it’s only supported in IE 10 and Opera for now.) [IF TIME: Live demo changing layout of pagination]
Page 67: Putting Flexbox into Practice (Fronteers)

Accessibility implications

Pro Keep content in logical order in HTML instead of structuring HTML to achieve visual layout

Con Focus/tab order won’t always match expected order, may jump around seemingly randomly

Presenter
Presentation Notes
This ability to arrange content visually in a different order than it appears in the source can have accessibility implications, both good and bad Pro: can keep content in logical order in HTML instead of structuring HTML illogically simply to achieve particular visual layout, which allows screen readers and other user agents that don’t pay attention to CSS layout to present content in logical order. Con: tab order won’t always match expected visual order of left to right (for LTR languages), top to bottom, which can be very disorienting to sighted non-mouse users when their focus outline jumps around the page in a seemingly arbitrary way as they tab.
Page 68: Putting Flexbox into Practice (Fronteers)

Tab order = HTML order

1

2

10

“Next” won’t be second link tabbed to after “Previous” since it doesn’t follow it in HTML

Presenter
Presentation Notes
Tabbing order depends on HTML order, so when you move content visually-only using flexbox order property, tab order doesn’t change. For example, in pagination, user would first tab to previous link, then page 1 link, then page 2 link, and so forth, until tenth tab press brings them to next link In this case, I don’t think this would be disorienting—even though next link is higher, page 1 link is right below previous link, so it wouldn’t be strange to see tab order move there after previous.
Page 69: Putting Flexbox into Practice (Fronteers)

Limitations of order property

Potential to create confusing tab order Can only rearrange sibling elements Flexbox rows/cols can’t overlap, so content

may not always slide into the spot left by the re-ordered content

So: reserve flexbox order property for small moves that don’t hurt accessibility, and use CSS3 Grid Layout, etc., for bigger re-ordering

Presenter
Presentation Notes
So I don’t think there’s an accessibility problem with my use of order property in pagination, but keep in mind that confusing tab order can result if you go crazy with order property I’ve found, though, that you often can’t really use order property anyway for really extensive re-ordering, since it can only re-order sibling elements, for instance Other CSS3 layout modules like Grid Layout are going to have much more robust re-ordering capabilities. Still, order property is a nice useful feature for smaller layout shifts!
Page 70: Putting Flexbox into Practice (Fronteers)

Pinned item at bottom

All boxes equal in height

Final item in each box pinned to the bottom so that all final items across grid appear to align

Presenter
Presentation Notes
Let’s move on to my final flexbox progressive enhancement example: pinning items to the bottom of equal-height boxes Really common for plan/pricing comparison boxes as shown here (red buttons pinned to bottom), also seen in product listings, galleries, etc.
Page 71: Putting Flexbox into Practice (Fronteers)

Pinned item at bottom

Without flexbox, “other” fields disconnected from each other and thus can’t align

With flexbox, they’re still disconnected, but their parents aren’t and can be equal height, plus…

Presenter
Presentation Notes
I wanted to use the effect on the “other” fields at bottom of each component box W/out flexbox, “other” fields unrelated from each other in HTML and thus can’t align W/ flexbox, they’re still unrelated, but their parent component boxes aren’t and can be equal height easily, plus…
Page 72: Putting Flexbox into Practice (Fronteers)

New “auto” margin behavior

Margins set to auto get all the free space left So, to pin flex item to bottom of its flex

container: set flex-direction:column on flex container

so items can fill its height set margin-top:auto on item you want to pin

Presenter
Presentation Notes
…in flexbox, if you set a margin in main axis to auto, it will take up all the free space left So, to pin flex item to bottom of its flex container, set flex-direction to column on flex container so items can fill its height, and then set margin-top:auto on flex item you want to pin
Page 73: Putting Flexbox into Practice (Fronteers)

Pin the “other” fields

1. Make each .component match in height by making parent .builder a flex container (already done) .builder { display: flex; align-items: stretch; /* default */ flex-wrap: wrap; justify-content: space-between; margin: 0 0 40px -20px; }

Presenter
Presentation Notes
And to make a bunch of bottom-pinned items appear to be aligning with each other, first make sure their parents are all same height. In our case, those parents are .component boxes, and default align-items value of stretch on flex container makes them equal height.
Page 74: Putting Flexbox into Practice (Fronteers)

Pin the “other” fields

2. Make each <ul> a flex item and stretch to full height, then make it a flex container with vertical direction so its <li> will stack .component { flex: 1 1 200px; display: flex; flex-direction: column; }

.component ul { flex: 1; display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }

Presenter
Presentation Notes
Not only do four component boxes need to be equal height, but <ul> within each needs to be equal height with other <ul>s too. So, I make each component a flex container with vertical direction so its child <ul> can flex to fill its entire height. (Using height:100% won’t work because .component has no explicit height for that 100% to be relative to. Setting flex:1 will work to stretch full-height. Another advantage of flex property over explicit dimensions.) I also make the <ul> into a flex container so its <li> will be flex items and can thus use auto margins in this new way
Page 75: Putting Flexbox into Practice (Fronteers)

Pin the “other” fields

3. Give “other” <li> an auto top margin so all free space left in <ul> is put above that <li>, pushing it to bottom of <ul> .component li:last-child { margin-top: auto; }

Presenter
Presentation Notes
Finally, I give the “other” row, the last <li> child of <ul>, auto top margin so whatever free space left in full-height <ul> is put above that last <li> This effectively pushes/pins it to the bottom of its parent <ul>
Page 76: Putting Flexbox into Practice (Fronteers)

Pinning without flexbox

Use display:table-cell for equal height boxes

Add bottom padding in ems to each box Use absolute positioning to pin “other” row in

space left by padding

Presenter
Presentation Notes
I won’t walk you through the CSS you could use as fallback to create similar pinning effect, but the gist is that you could use display:table-cell to get equal height boxes, add a good chunk of padding (in ems) to bottom of each box, and then use absolute positioning to pin “other” row in space left by that padding This isn’t as nice as flexbox version because absolute items have potential to overlap other content, and you have to hardcode the padding value, but it will look the same as the flexbox version—just not as robust
Page 77: Putting Flexbox into Practice (Fronteers)

Variation: two-piece main nav

.flexbox .list-nav {

justify-content: flex-start;

position: relative;

top: -70px;

}

.flexbox #link-home { margin-right:20px; }

.flexbox #link-tumblr { margin-left:20px; }

.flexbox #link-party {

margin-left: auto;

}

Presenter
Presentation Notes
I also made use of auto margins on wide view of main nav Simply set margin-left:auto on third link (throw a party), which pushed all the extra space in the line to its left side, effectively pushing third link and everything after it to right edge W/out flexbox, most would cheat and break this isn’t two lists, which is less accessible and robust (Also note that I’ve used positioning on flex container .list-nav—you can combine flexbox with positioning and floats, just test well since I’ve found some browser bugs in certain combinations in the past, though not yet with recent browser implementations of flexbox.)
Page 78: Putting Flexbox into Practice (Fronteers)

Why go to the trouble to use flexbox as progressive enhancement now?”

I can use it, but why should I? “

Presenter
Presentation Notes
Hopefully you feel eager to try out some of these flexbox tricks But, some of you might be thinking, ok, I see that I CAN use flexbox as progressive enhancement right now, but WHY would I want to go to the trouble? After all, all the examples I showed you were basically just cosmetic enhancements, and they may not be seen by a whole lot of your users, so is the extra work worth it? I say yes. I think you should learn and use flexbox now, for these reasons.
Page 79: Putting Flexbox into Practice (Fronteers)

Develop it as a career skill

Essential layout tool in the future, especially with responsive web design

Syntax is not going to change much, so what you learn now will still work later

Better to learn something before it’s needed in a project rather than during

Presenter
Presentation Notes
It’s going to be an essential layout tool in the future, especially as responsive web design becomes more prevalent, so it’s better for your career to learn it now, get ahead of the competition. The syntax is not going to change much as this point, so what you learn now will still work later, and you’ll have skill ready to go for when it’s needed, hit the ground running There’s less pressure and more chance of success if you learn flexbox before having to use it in live project instead of during In our field, we’re always having to add to our skillset, and sometimes make big shifts in the way we do things I already told you about when I learned about pure CSS layout, but it was a while before that when I was introduced to CSS as a thing
Page 80: Putting Flexbox into Practice (Fronteers)

when I can do the same thing with <font> tags?”

Why should I do it with CSS “ –Zoe, circa 2002

Presenter
Presentation Notes
For some reason, I can remember exactly where I was when I first heard about CSS, and this is a nearly verbatim quotation of one of the things I said to the person who was trying to convince me that CSS was the next big thing. I have a distinct memory of defending font tags. This seemed like a perfectly logical viewpoint at the time, and it actually did have some validity to it.
Page 81: Putting Flexbox into Practice (Fronteers)

when I can do the same thing with floats?”

Why should I do it with flexbox “

Presenter
Presentation Notes
This seems like a perfectly logical viewpoint now. And it definitely has validity to it, I won’t deny it. But at some point, our ever-changing industry forces us to stop asking this question because that new technology or new technique is no longer really new and has now become standard and expected. Just like learning CSS or floats or responsive web design, the pain was less if you learned it early, when it was still somewhat new and not yet “the way it’s done,” and gave yourself time to experiment with it.
Page 82: Putting Flexbox into Practice (Fronteers)

We all learn best by doing

I learned a lot more about flexbox by building demo site for this presentation—a lot

Have to try it to learn it Using it for small cosmetic enhancements is

low-risk way to try it

Presenter
Presentation Notes
The best way to learn flexbox, of course, is to use it, hands on. I learned a lot more about flexbox by building demo site for this presentation. Remember when I inadvertently was setting flex-basis to 0 and that was causing nothing to wrap? That was really frustrating, but it was a great learning experience. I understand flex-basis and the flex property far better now. Using flexbox for small cosmetic enhancements like the progressive enhancement examples I showed may seem trivial, but those sort of things are a really low risk way to try it and get comfortable with the syntax and how it works.
Page 83: Putting Flexbox into Practice (Fronteers)

It’s fun

Great user experience is important, but great developer experience is worthwhile too

Enjoy your job to get better at your job Sometimes the little extra time is worth the

fun challenge and reward at the end

Presenter
Presentation Notes
And finally, I think you should start using flexbox because it’s fun. You can read lots of articles on web design/UX blogs about the little moments of delight we can and should be giving to users through our work, but what about giving ourselves little moments of delight through our work? There’s no reason why we can’t do both. We should enjoy our jobs to get better at our jobs. It might take a little longer to add on flexbox as progressive enhancement, but if it’s fun challenge and rewarding to see at the end, it’s worth it. Every once in a while, forget the rule that you only add something to the site if the browser metrics ROI user A/B test analytics say it’s worthwhile, and add a bit of CSS because you think it’s awesome and you’ll have fun writing it.
Page 84: Putting Flexbox into Practice (Fronteers)

Learn more

Download slides and get links at www.zomigi.com/blog/flexbox-presentation

Thanks! Zoe Mickley Gillenwater @zomigi [email protected] zomigi.com | stunningcss3.com | flexiblewebbook.com Credit: “S’more” photo by Christopher Penn on Flickr. Looks like that man really knows how to make a good s’mores!

Presenter
Presentation Notes
I had fun creating this presentation for you guys, and if you want to download it and get links to related resources, head over to this URL on my blog. [CONTACT INFO]