using flexbox today (frontier conf 2016)
TRANSCRIPT
tables
positioning
floats
inline-block
table-cell
flexbox
grid multi-column exclusions
shapes
regions flexbox
Flexbox has 97% coverage worldwide
We support IE 8 and 9 at Booking, but still use flexbox as progressive enhancement.
Do I want to create a layout in 1 dimension (row OR column)
or 2 dimensions?
Hat-tip to Rachel Andrew: https://rachelandrew.co.uk/archives/2016/03/30/should-i-use-grid-or-flexbox/
Flexbox is not a grid ¨ Not meant for or great at whole page layout ¨ Flex items only care about space in their
own row/column ¨ They don’t care about lining up in the other
dimension
Flexbox is best for: ¨ UI components ¨ Simple whole page layouts (not grid-based) ¨ Enhancing a complex layout’s alignment,
spacing, etc. (not controlling placement)
Content determines boxes’ size and
placement
(Mega-useful when content is unknown and variable, or readability is
a top priority.)
Structure determines content’s size and
placement
(P.S. Flexbox can do this too, if you want. It’s just the reverse that doesn’t
work so well.)
Flexbox Grids
New things flexbox offers ¨ Content-driven, unit-less sizes ¨ Content-driven, media-query-less layout changes ¨ Mixed-unit layouts ¨ Equal-height columns ¨ Vertical centering and other alignments ¨ Spacing out or stretching items to fill unknown width/height ¨ Combining content wrapping and block wrapping ¨ Pinning items without overlaps ¨ Visual order different than HTML/reading order
Content-driven sizing on Booking.com Last year’s sidebar searchbox design, with fixed-width select fields
Content-driven sizing on Booking.com .sb-dates { display: flex;
}
.sb-dates__icon {
flex: 0 0 23px;
} .sb-dates__select-day {
flex: 1 0 auto;
margin: 0 6px;
}
.sb-dates__select-month { flex: 1 1 auto;
}
flex container
main axis flex items
Translating the flex property .sb-dates { display: flex;
}
.sb-dates__icon {
flex: 0 0 23px;
} .sb-dates__select-day {
flex: 1 0 auto;
margin: 0 6px;
}
.sb-dates__select-month { flex: 1 1 auto;
}
Start out 23px wide, and don’t grow or shrink further
Start out sized to your content, then grow with 1 share of any extra space available, but don’t ever shrink
Start out sized to your content, then grow with 1 share of extra space, but if there’s an overflow shrink
Mixed-unit layout is easier with calc(), but not even it can do: calc(100% - 23px - the width of the day field in Greek)
Taking advantage of variable space Task: add a message about low availability of the room price shown: “We have only X left on our site!”
How about right here in this lovely big gap?
Taking advantage of variable space Problem: the gap is not always big enough to hold a sentence of text
Taking advantage of variable space Solution: use flexbox to place text beside price when space allows; otherwise, it can wrap below price and stretch
Not possible with floats, inline-block Not possible with table-cell
Layout change without media query 1. Let the blocks wrap and stack when needed:
.article-header { display: flex; flex-direction: row; flex-wrap: wrap; }
/* default */
Switching between columns and rows
flex-direction: column
or
flex-direction: row flex-wrap: wrap (or the shorthand flex-flow: row wrap)
@media min-width... flex-direction: row
1 column when narrow Multiple rows when wide
Same, no change needed
Layout change without media query 2. Size the blocks to control their wrapping
point: .article-header-image { flex: 1 1 320px; padding-left: 20px; } .article-header-text {
flex: 1 1 20em; padding-left: 20px; }
< 100% = 1 row, 2 columns > 100% = wrap to 2 rows
Full-width nav bar with equal spacing
Non-flexbox fallback version
Flexbox version
http://codepen.io/zomigi/pen/vKjbbY/
Full-width nav bar with equal spacing .menu-list { display: flex;
justify-content: space-between;
margin: 0;
padding: 0;
list-style: none; text-align: center; /* fallback */
}
.menu-list-item {
display: inline-block; /* fallback */
padding: 0 .5em; /* fallback */ }
Equally spaces items across main axis (width in this case)
Full-height menu with equal spacing
.menu-list { display: flex;
flex-direction: column;
justify-content: space-between;
}
.menu-list-item { height: 100%;
display: flex;
align-items: center;
}
.menu-list { display: flex;
flex-direction: column;
}
.menu-list-item {
flex: 1 0 auto; display: flex;
align-items: center;
}
justify-content version flex version
Full-height menu with equal spacing
.menu-list { display: flex;
flex-direction: column;
justify-content: space-between;
}
.menu-list-item { height: 100%;
display: flex;
align-items: center;
}
.menu-list { display: flex;
flex-direction: column;
}
.menu-list-item {
flex: 1 0 auto; display: flex;
align-items: center;
}
justify-content version flex version
order integer to specify flow order of flex items
0 0 0 default source order 0 0
1 0 0 re-ordered 0 0
0 0 -1 re-ordered 0 0
2 1 0 re-ordered 1 0
Use flexbox order in mobile styles .recipe { display: flex; flex-direction: column; } .recipe figure { order: -1; /* before all items with default order: 0 */ } .recipe figure img { width: 100%; }
Turn off flexbox in desktop styles @media screen and (min-width:800px) { .recipe { display: block; /* turn off flexbox */ } .recipe figure { float: right; width: 55%; } }
These examples don’t look wrong or broken without flexbox. �
�Flexbox just enhances their sizing
and spacing to look better.
Decide which versions of flexbox to support
standard, 2011/2012, and/or 2009 http://caniuse.com/#feat=flexbox
I recommend you skip the ‘09 syntax ¨ Slower to render than current syntax* ¨ Doesn’t support wrapping ¨ Small market share ¨ Its browsers can get same fallback you give
to non-supporting browsers
* http://updates.html5rocks.com/2013/10/Flexbox-layout-isn-t-slow
Let tools add browser variants for you Which variants do you want? Best tool to handle that
All the things! Autoprefixer Bourbon (Sass)
Only the standard syntax, with and without prefixes
Compass (Sass)
Some other combination (such as everything except 2009)
Sass or LESS mixins, such as https://github.com/mastastealth/ sass-flex-mixin
Add Modernizr as needed with flexbox Flexbox and fallback styles can often co-exist, but sometimes need to isolate them
http://zomigi.com/blog/using-modernizr-with-flexbox/
Or use @supports .gallery-item { display: inline-block; } @supports (flex-wrap: wrap) { .gallery { display: flex; flex-wrap: wrap; } }
https://developer.mozilla.org/en-US/docs/Web/CSS/@supports
But IE 10-11, which do support flexbox but don’t support @supports, won’t get these styles
Things to consider Do I need content blocks to wrap? not table-cell
Do I want to prevent blocks from wrapping? floats, inline-block, but table-cell best
Do I need content-driven sizes? floats, but table-cell or inline-block best
Do I need vertical alignment? inline-block, table-cell
Do I need horizontal alignment? floats, table-cell, inline-block only with preset sizes
Pick your starter layout CSS
¨ Floats ¨ table-cell ¨ inline-block
¨ Absolute positioning
Flexbox will override: Flexbox will not override:
Just use whatever you normally would; flexbox plays nicely with most of them.
Split left-right layout Task: lay out review score and price, on opposite sides of same line Needs: ¨ content-driven sizing ¨ horizontal alignment ¨ wrapping
score price or “sold out”
Adding the starter CSS .iw_mini_review_score_wrapper { float: left; } .iw_mini_price_wrapper { float: right; }
Creating the block flex container .iw_mini_details_wrapper { display: flex; } .iw_mini_review_score_wrapper { float: left;
} .iw_mini_price_wrapper { float: right; }
Flex container sits on a new row below, like a block element
Things to consider Lay out horizontally or vertically? flex-direction:row or
column
Allow boxes to wrap? flex-wrap:wrap, wrap-reverse or nowrap
Order different than source? order values; flex-direction: row-reverse or column-reverse
Allowing wrapping .iw_mini_details_wrapper { display: flex; flex-wrap: wrap; } .iw_mini_review_score_wrapper {
float: left; } .iw_mini_price_wrapper { float: right; }
Allows second block to wrap down if needed
Decide which items can �grow to fill space, �
shrink to avoid overflow, �or must stay at a certain size
Tips for setting flex values ¨ Avoid single-digit and keyword values
¤ flex: 1 1 0% instead of flex: 1 ¤ Hidden default values can lead to mistakes ¤ Avoids IE 10-11 bugs
¨ Think about it backwards ¤ First decide flex-basis ¤ Then decide flex–shrink and flex-grow
Tips for setting flex-basis values ¨ Acts like min-width when wrapping on ¨ Acts like max-width when flex-shrink
on and flex-grow off ¨ Be careful with flex-basis:0 when
wrapping ¨ Use flex-basis:auto whenever possible
Setting flex-shrink ¨ Always have at least 1 item per line that
can shrink (or wrap, or both) ¨ Yes, always
Setting flex-grow ¨ Decide what to do with extra space
¤ Fill it up? (flex-grow: 1, 2, etc.) ¤ Leave it? (flex-grow: 0)
Setting flex values .iw_mini_details_wrapper { display: flex; flex-wrap: wrap; } .iw_mini_review_score_wrapper {
float: left; flex: 0 1 auto; } .iw_mini_price_wrapper { float: right;
flex: 0 1 auto; }
Size to content, shrink smaller if you have to, don’t grow bigger (default value)
Controlling alignment .iw_mini_details_wrapper { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline;
} .iw_mini_review_score_wrapper { float: left; } .iw_mini_price_wrapper {
float: right; }
Moves first item to left, last item to right
Flexbox with float fallback .iw_mini_details_wrapper { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline;
} .iw_mini_review_score_wrapper { float: left; } .iw_mini_price_wrapper {
float: right; }
Flexbox properties on container override floating automatically in supporting browsers
Floating gets used by old browsers
Testing your flexbox ¨ If using Modernizr: Too Flexy bookmarklet
for toggling Modernizr flexbox classes: http://chriswrightdesign.github.io/tooflexy/
¨ If reordering: check tabbing and screen reading order to make sure it’s still logical
Fixing browsers’ flexbox bugs ¨ Read explanations and workarounds by
Philip Walton: https://github.com/philipwalton/flexbugs
¨ Let PostCSS fix some for you: https://github.com/luisrudge/postcss-flexbugs-fixes
Summing up the process 1. Decide which browser versions of flexbox to use 2. Choose and add starter layout CSS 3. Choose and add flexbox CSS
1. Block or inline-block container 2. Flow 3. Flex to control sizing 4. Alignment
4. Test and fix bugs