This document discusses using flexbox for responsive web design. It begins with an overview of problems with other layout methods like floats and tables. Flexbox solves many of these issues by allowing boxes to automatically grow and shrink, be proportionally sized, and be laid out in any direction. The document demonstrates several uses of flexbox properties like flex-direction, justify-content, align-items and order to create responsive navigation bars, stacked icons, equal height columns, and reordering content. It emphasizes using flexbox now for progressive enhancement and discusses techniques for providing non-flexbox fallbacks.
5. I even wrote a
book about it
in 2008.
Then I got into CSS âliquidâ layout5
6. Problems with float layout
ď¨ Difficulty with containment
ď¨ Wrapping/float drop
ď¨ Difficulty with equal-height columns
ď¨ No float:center
ď¨ No vertical centering
ď¨ Visual location somewhat tied to HTML
order
6
7. The alternatives have problems, too
ď¨ Source-order
dependent
ď¨ Whitespace in source
appears visually
ď¨ Source-order
dependent
ď¨ No wrapping
ď¨ No IE 7 support
7
Issues with inline-block Issues with table-cell
8. Flexbox solves a lot of these issues
ď¨ Make boxes automatically grow to fill
space or shrink to avoid overflow
ď¨ Give boxes proportional measurements
ď¨ Lay out boxes in any direction
ď¨ Align boxes on any side
ď¨ Place boxes out of order from HTML
8
16. 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
16
25. Wide variation: two-piece main nav
1. Add media query for wide width:
@media (min-width:860px) {
}
2. Add link to Modernizr, because weâre going
to need to feed styles to only flexbox
browsers in this case
25
26. Add Modernizr as needed
ď¨ Flexbox and fallback styles can often co-
exist, but sometimes need (or want) to
isolate them
ď¨ Modernizr can add flexbox, no-flexbox,
and flexboxlegacy classes to do this
26
27. Wide variation: two-piece main nav
3. Move nav bar up to overlap logoâs line:
@media (min-width:860px) {
.flexbox .list-nav {
position: relative;
top: -70px;
}
}
27
28. Wide variation: two-piece main nav
4. Stop distributing links across full width:
@media (min-width:860px) {
.flexbox .list-nav {
justify-content: flex-start;
position: relative;
top: -70px;
}
}
28
29. Wide variation: two-piece main nav
5. Add margins to control extra space in line:
.flexbox .link-party {
margin-left: auto;
}
.flexbox .link-home { margin-right: 15px; }
.flexbox .link-tumblr { margin-left: 15px; }
29
39. Combining units of measurement across
a line can make RWD tricky.
ems + % + px = ?39
40. Demo: responsive form40
ď¨ Inspired by http://jobs.theguardian.com/,
which uses floats and percentage widths
41. But it would be nicer ifâŚ41
ď¨ The drop-down and button were sized
automatically by their content, so this
doesnât happen:
ď¨ The fields and button all matched each
other exactly in height
42. Enhance with flexbox42
1. Let the fields wrap when needed:
.jobs-form {
display: flex;
flex-wrap: wrap;
}
2. Fields become flex items with row
orientation, but are allowed to form multiple
rows (so it looks like 1 column when
narrow)
43. Enhance with flexbox43
3. Override the % widths and let fields size to
their content:
.flexbox .jobs-form_field-wrapper {
width: auto; /* hide from non-flex browsers */
flex: 1 1 100%;
}
@media (min-width:40em) {
.jobs-form_field-wrapper {
flex: 1 0 auto;
}
}
44. Defining the flex property
ď¨ Makes flex items change their main size
(width or height) to fit available space
44
45. 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)
45
46. Breaking it down
. jobs-form_field-wrapper {
flex: 1 0 auto;
}
flex-grow = 1
give each item 1
share of extra
width
flex-shrink = 0
donât let items
shrink at all from
their starting width
flex-basis = auto
start items at âmain
sizeâ value (in this
case, width) or
content size if main
size not set
46
47. What flex-basis: auto will do47
ď¨ Browser looks at main size value, width
ď¨ width:auto, so field sizes to its content
ď¨ Thus, content size=starting size/flex-basis
ď¨ Wrapping= no reason to shrink lower than
starting size
ď¨ flex-basis=min-width when wrapping on
ď¨ Thus, content size=minimum field width
ď¨ So, this canât happen:
50. Enhance with flexbox50
5. Turn each field wrapper into flex container:
.flexbox .jobs-form_field-wrapper {
display: flex; /* sets align-items:stretch */
width: auto;
flex: 1 1 100%;
}
6. Input/button inside stretches to match
height of its line, thanks to default align-
items:stretch on flex containers, so all
fields are equal height on their line
56. Enhance with flexbox56
1. Make photo and text block automatically sit side-
by-side when they can fit (320px + 20em):
.article-header {
display: flex;
flex-wrap: wrap;
margin-left: -20px;
}
.article-header-image {
flex: 1 1 320px;
padding: 0 0 20px 20px;
}
.article-header-text {
flex: 1 1 20em;
padding: 0 0 20px 20px;
}
57. Enhance with flexbox57
2. Enhance alignment of text within the text block:
...
.article-header-text {
display: flex;
flex-wrap: wrap;
align-items: baseline;
align-content: space-between;
flex: 1 1 20em;
padding: 0 0 20px 20px;
}
.article-title {
flex: 1 1 100%;
}
.article-category {
flex: 1 1 auto;
}
63. Use order property to move logo
1. Divide nav bar into order groups:
.link-home, .link-builder {
order: 0; /* default, and first here */
}
.logo {
order: 1; /* second */
}
.link-party, .link-tumblr {
order: 2; /* last */
}
63
64. Use order property to move logo
2. Split extra space on line to center logo:
.logo {
margin-left: auto;
}
.link-party {
margin-left: auto;
}
64
65. Order only works on siblings65
To move logo to middle of list, it needs to be
part of list
<div class="logo"><img src="images/logo.png"></div>
<ul class="list-nav">
<li class="logo"><img src="images/logo.png"></li>
<li class="link-home"><a>home</a></li>
<li class="link-builder"><a>s'mores builder</a></li>
<li class="link-party"><a>throw a party</a></li>
<li class="link-tumblr"><a>tumblr</a></li>
</ul>
66. Accessibility implications
Pro
Can keep content in
logical order in HTML
instead of structuring
HTML just to achieve a
visual layout.
Cons
If HTML order is illogical,
screen reader users still
hear it.
Focus/tab order wonât
always match expected
order, may jump around
seemingly randomly.
66
67. If youâre using it for progressive
enhancement, the content should make
sense in both the HTML and visual order.
Use the order property sparingly67
68. Reordering mobile content
In RWD, narrow-view
(mobile) stacking order
doesnât always match
needed HTML order for
wide-view (desktop)
layout
Keep HTML order needed
for desktop and use
order property only on
mobile, since browser
support is great there
Problem Solution
68
69. Jeremy Churchâs mobile example
@media screen and (max-width: 767px) {
.media_xs_order_one { order: 0; }
.media_xs_order_two { order: 1; }
.media_xs_order_three { order: 2; }
}
See Jeremyâs write-up at http://j.eremy.net/flexbox-for-mobile-content/
HTML order (no flexbox) Reordered with flexbox
69
70. Be careful with accessibility
ď¨ Reading order
wonât match
visual order. This
may or may not
be bad.
ď¨ Tabbing order
wonât match
visual order. This
is bad. (And yes,
tabbing matters
even on mobile.)
1
3
2
4
5
70
71. Demo: moving a photo on mobile
Desktop: HTML order (no flexbox)Mobile: reordered
71
72. 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%;
}
Inspired by Jonathan Cutrellâs example at http://webdesign.tutsplus.com/
tutorials/tricks-with-flexbox-for-better-css-patterns--cms-19449
72
73. Turn off flexbox in desktop styles
@media screen and (min-width:800px) {
.recipe {
display: block; /* turn off flexbox */
}
.recipe figure {
float: right;
width: 55%;
}
}
73
74. Demo: moving a photo on mobile
Flexbox version Non-flexbox version
74
75. The Guardian: opposite approach75
Stacking order you
see when narrow
is the HTML order,
unchanged
1
2
3
4
5
6
76. The Guardian: opposite approach76
Reordered when
wide, but not
using order 12 3
4 56
flex-direction: row-reverse
flex-direction: row-reverse
79. I recommend you skip the â09 syntax79
ď¨ Itâs slower to render than current syntax*
ď¨ Its browsers have tiny market share
ď¨ You should be using flexbox in progressive
enhancement sort of way regardless, so its
browsers will just get same fallback you
provide to non-supporting browsers
* http://updates.html5rocks.com/2013/10/Flexbox-layout-isn-t-slow
80. Set up your tools
ď¨ Let Autoprefixer, Sass, or LESS add the
browser variants for you:
ď¤ https://github.com/ai/autoprefixer
ď¤ https://github.com/mastastealth/sass-flex-mixin
ď¤ https://gist.github.com/cimmanon/4461470
ď¤ https://github.com/thoughtbot/bourbon/blob/mas
ter/app/assets/stylesheets/css3/_flex-box.scss
ď¤ https://github.com/annebosman/FlexboxLess
ď¨ Keep Modernizr on hand to help feed
different styles to different browsers:
http://modernizr.com/download/
80
84. Pick your starter/fallback layout CSS
ď¨ Floats
ď¨ table-cell
ď¨ inline-block
ď¨ Absolute positioning
84
Flexbox will override: Flexbox will not override:
No single right/best answer. Use whatever
you normally would.