CSS Flexbox
Flexible, Robust Line-Based Layout
R. Scott Granneman r Jans Carton
© 2017 R. Scott Granneman
Last updated 2023-10-23
You are free to use this work, with certain restrictions.
3.7 For full licensing information, please see the last slide/page.
❶ ❷ ❸ ❹ ❺ ❻ ❼
❽ ❾ ❿
Flexbox is for laying out elements in a particular
direction along a (sometimes wrapped) line
Terms
Flex Container
Flex Items
Main Axis: primary axis on which ßex
items are laid out (↔ or !)
Cross Axis: perpendicular
to the main axis (! or ↔)
Assumes flex-direction: row
Cross Start
Main Start Main End
Cross End
Flex Container Cross Size Flex Container Main Size
Flex Item Main Size Flex Item Cross Size
Main Axis: primary
axis on which ßex
items are laid out
(! or ↔)
Cross Axis:
perpendicular
to the main axis
(↔ or !)
Main Start
Cross End
Cross Start
Main End
Assumes flex-direction: column
Flex Container
Main Size
Flex Item
Main Size
Flex Item
Cross Size
Flex Container
Cross Size
Flex container
Flex items
Main axis
Cross axis
On the following slides, youÕll see these symbols
↔
↔
display: flex column-gap
display: inline-flex row-gap
gap
flex-direction
flex-wrap
flex-flow
justify-content
align-content
place-content
align-items
order
align-self
flex-grow
flex-shrink
flex-basis
flex
Triggering
Flexbox Layout
display: flex (<inside>)
display: block flex (<outside> <inside>)
Triggers flex layout for the container box:
È Flex container box stacks (because block)
È Immediate children become flex items
display: inline-flex
Generates an inline box that behaves according to
the flexbox model:
È Generates atomic inline box Ñ an inline box that does
not break across lines (just like display: inline-
block)
È Immediate children become flex items
È Changes the layout mode inside it
display:
flex 8* 12 28 9 9 29 4.4
inline-flex 11 12 28 9 9 29 4.4
* Uses -ms-flexbox 8Ð10 use -ms-inline-flexbox
Direction,
Wrapping,
& Order
flex-direction
flex-wrap
flex-flow
order
flex-direction
SpeciÞes how flex items are laid out in the flex
container by settingÉ
È the main axis: ↔ !
È the direction of the ßow along the main axis
flex-direction
Values:
È row (default) !
È row-reverse !
È column !
È column-reverse !
flex-direction: row
Flex items are stacked in a row !: from left-to-right
(If the default for your locale is direction: rtl, then
itÕs the opposite)
flex-direction: row-reverse
Flex items are stacked in a row !: from right-to-left
(If the default for your locale is direction: rtl, then
itÕs the opposite)
flex-direction: column
Flex items are stacked !: in a column from top-to-
bottom
flex-direction: column-reverse
Flex items are stacked !: in a column from bottom-to-
top
You can apply display: flex on ßex items
Add flex-direction to the mix & you can really have
something
Each card is both a ßex item & a ßex container
flex-direction: row for the outer container;
flex-direction: column for each card
On a mobile device,
responsive layout
aligns them
vertically & their
height is now sized
to their content
flex-wrap
SpeciÞes if ßex container lays out flex items in single or
multiple lines, & the direction new lines are stacked in
Only applies if the ßex container is too small to contain
the ßex items
flex-wrap
Values:
È nowrap (default)
È wrap
È wrap-reverse
flex-wrap: nowrap
Flex items are displayed in one row
These are not 200px wide because ßex
items do not wrap by default
flex-wrap: wrap
Flex items are displayed in multiple rows, from left-to-
right and top-to-bottom
These are 200px wide
flex-wrap: wrap-reverse
Flex items are displayed in multiple rows, from left-to-
right but from bottom-to-top
flex-flow
Shorthand for setting flex-direction & flex-wrap
flex-flow: <flex-direction> <flex-wrap>
Default is row nowrap
order
SpeciÞes order in which flex items appear inside the
ßex container
Default is 0, which orders ßex items according to order
in HTML
Value: <integer>
flex-direction 11 12 28 9 9 29 4.4
flex-wrap 11* 12 28 9 9 29 4.4
flex-flow 11 12 28 9 9 29 4.4
order 11 12 28 9 9.2 29 4.4
* Very buggy; see chnsa.ws/1ik for more
Aligning
Items & Lines
justify-content safe
align-content
start
place-content end
align-items column-gap
align-self row-gap
gap
Remember that distributed alignment focuses on
distributing space among aligned boxes, e.g., stretch,
space-around, space-between, & space-evenly
Flex items Flex lines*
Main axis justify-content
align-items
Cross axis align-self align-content
This table shows the relationship between box align-
ment keywords in ßexbox layout**
justify-self & justify-items do not apply with ßex
* Requires flex-wrap: wrap ** Alas, these terms have different relationships in grid layout
!PRO TIP
Never use width & height with ßexbox layout! Instead of
width & height, size items using these for the cross axis:
È align-items: stretch
È align-content: stretch
È align-self: stretch
And this for the main axis:
È flex-basis
WeÕre going to cover align-* in this section
Aligning
Flex Items
on the Main Axis
justify-content
DeÞnes how space is distributed between & around flex
items along the main axis of their container
Values for justify-content:
È flex-start (default)
È flex-end
È center
È space-between
È space-around
È space-evenly
È start
È end
justify-content: flex-start
Aligns ßex items to the start of the main axis of the flex
container
Default value for justify-content
justify-content: flex-end
Aligns ßex items to the end of the main axis of the flex
container
justify-content: center
Aligns ßex items at the center of the main axis of the
flex container
justify-content: space-between
Flex items have equal spacing between them, with Þrst
& last ßex items aligned to edges of the main axis of the
ßex container
No space before Þrst ßex item
(or after last ßex item), but
equal space between ßex items
justify-content: space-around
Flex items have equal spacing around them, with Þrst
& last ßex items getting half-sized spaces on the ends of
the main axis of the ßex container
Empty space before the Þrst, and after the last, ßex
items equals half of the space between two adjacent
items
Space before 1st ßex item (&
after last ßex item) is 1/2 of
space between ßex items
justify-content: space-evenly
Flex items have equal spacing around them, with Þrst
& last ßex items getting equal spaces on the ends of the
main axis of the ßex container
Empty space before the Þrst, and after the last, ßex
items equals the space between two adjacent items
Space before Þrst ßex item &
after last ßex item equal to
space between ßex items
justify-content:* 11 12 29 9 9.2 29 4.4
space-evenly Ð 79 52 11 11 60 Y
* Includes support for flex-start, flex-end, center, space-between, & space-around
Aligning
Flex Items
on the Cross Axis
align-items
Aligns flex items in the cross axis of the current ßex line
Values for align-items:
È stretch (default)
È flex-start
È flex-end
È center
È baseline
È start
È end
align-items: stretch
Flex items fill the whole height (or width) from cross
start to cross end of the ßex container
Obviously the ßex item cannot have height set
Default value for align-items
align-items: flex-start
Flex items stack from the cross start of the ßex
container
align-items: flex-end
Flex items stack from the cross end of the ßex container
align-items: center
Flex items stack from the center of the cross axis of the
ßex container
Horizontally
and vertically
centered!
" # $ %&
align-items: baseline
Flex items stack so that the baselines are aligned inside
the ßex container
align-items 11 12 27 9 9 52 4.4
align-self
Allows the default alignment, or the one speciÞed for
the ßex container by align-items, to be overridden for
individual flex items
Values for align-self:
È auto (default)
È flex-start
È flex-end
È center
È baseline
È stretch
È start
È end
align-self: auto
Uses the value of align-items on the flex container
If align-items isnÕt set on the ßex container,
remember that it defaults to stretch
align-self: flex-start/start
Flex item stacks from the cross start of the ßex
container
flex-start is well-supported; the future is start
align-self: flex-end/end
Flex item stacks from the cross end of the ßex container
flex-end is well-supported; the future is end
align-self: center
Flex item stacks from the center of the cross axis of the
ßex container
align-self: baseline
Flex item stacks so that the baselines are aligned inside
the ßex container
align-self: stretch
Flex item fills the whole height (or width) from cross
start to cross end of the ßex container
Default value for align-items on the ßex container
align-self: 11 12 27 9 9 36 4.4
baseline Ð 79 45 Ð Ð 57 Y
stretch 11 79 52 Ð Ð 57 Y
Aligning
Flex Lines
on the Cross Axis
align-content
Aligns multiple lines of ßex items within the ßex
container when there is extra space in the cross axis
Similar to how justify-content aligns individual
items within the main axis
What about all this extra space?
align-content only effects layout when there are
multiple lines of ßex items inside the ßex container &
flex-wrap is set to wrap or wrap-reverse
If there is only a single line of ßex items, align-
content has no effect on the layout
Values for align-content:
È stretch (default)
È flex-start
È flex-end
È center
È space-between
È space-around
È space-evenly
È start
È end
align-content: stretch
Flex items display with distributed space after every
line of ßex items
Default for align-content
align-content: flex-start
Flex items begin at the cross start of the ßex container
based on ßex-direction
align-content: flex-end
Flex items are stacked at the cross end of the ßex
container, but not starting there
align-content: center
Flex items are stacked in the center of the cross axis of
the ßex container
align-content: space-between
Rows of ßex items have equal spacing between them,
with first & last rows aligned to the top & bottom edges
of the ßex container
No space after last row (or before 1st
row), but equal space between rows
align-content: space-around
Rows of ßex items have equal spacing between them,
but space before the Þrst row & after the last row equals
half of the space between adjacent rows
Similar to justify-content: space-around, but
focuses on rows instead of ßex items
Space after last row (& before 1st row) is
1/2 of space between rows
align-content: space-evenly
Rows of ßex items have equal spacing around them,
even the first & last rows
Space after last row (& before 1st row) is
equal to space between rows
' SIDE NOTE
place-content
Shorthand for align-content (which aligns lines on
the cross axis, or block direction) & justify-content
(which aligns items on the main axis, or inline
direction)
Values: <align-content> <justify-content>
If only 1 value is provided, it applies to both
' SIDE NOTE
Nice quick way to center ßex items if & only if flex-
wrap: wrap is enabled:
place-content: center;
align-content: 11 12 28 9 9.2 29 4.4
stretch Ð 79 52 9 9 57 &
space-evenly Ð 79 52 11 11 60 Y
place-content Ð 79 45 9 9.2 59 59
Scooby-Doo
& The Dangers
of Data Loss
Every property previously covered in this section Ñ
justify-content, align-content, place-content,
align-items, & align-self Ñ also supports 2 values
that work in conjunction with the other values: safe &
unsafe, e.g.:
div {
display: flex;
align-items: safe center;
justify-content: safe center;
}
The viewport is
easily big enough for
our centered image
Now make the viewport smaller than the centered
image
The image is still centered, therefore all 4 edges go
outside the viewport
LetÕs see what happensÉ
Uh oh Ñ the top & left of the image is completely out of reach,
so that we canÕt even scroll to it!
But we can scroll to the bottom & right without a problem
Why?
Since we were unable to scroll past the top or left of the
viewport to see the top or left of the image, you
experience what the W3C calls Òdata lossÓ
You can still scroll right & down, however, thanks to the
left-to-right direction & top-to-bottom writing mode of
English
LetÕs enable safe center for align-items & justify-
content
Now when scrolling is triggered, the image is no longer
centered & is now aligned as though it was:
align-items: start;
justify-content: start;
Now we can see the top & left of the image (before, it was out
of reach)É
& the bottom & right, like we always could
align-items:
Ð 115 63 Ð Ð 115 115
safe & unsafe
justify-content:
Ð 115 63 Ð Ð 115 115
safe & unsafe
Since Safari doesnÕt support safe & unsafe for now, make
sure your design handles the problem via other responsive
behaviors such as image resizing & word wrapping
Marathon Man (1976)
Aligning
via Writing Mode
Every property previously covered in this section Ñ
justify-content, align-content, place-content,
align-items, & align-self Ñ also supports 2 values:
start & end, e.g.:
div {
display: flex;
justify-content: start;
}
start
Flex items are aligned at the logical start edge of the
ßex container relative to reading direction or writing
mode
end
Flex items are aligned at the logical end edge of the ßex
container relative reading direction or writing-mode
Latin- & Han-based Mongolian-based
Block start Inline start
Inline start
Block start
Inline end
Block end
Block end Inline end
Arabic-based Han-based
Block start Inline start
Inline start
Block start
Inline end
Block end
Block end Inline end
justify-content:
Ð Ð 45 9 9 Ð Ð
start & end
align-items:
Ð Ð 45 Ð Ð Ð Ð
start & end
align-self:
Ð 79 45 Ð Ð 57 Y
start & end
align-content:
Ð Ð 45 Ð Ð Ð Ð
start & end
place-content:
? ? ? ? ? ? ?
start & end
Gutters
column-gap
DeÞnes minimum size of space (the gutter) between
items
row-gap
DeÞnes minimum size of gutter between wrapped lines
gap
DeÞnes minimum size of gutter between rows &
columns
Shorthand for setting column-gap & row-gap
column-gap Ð 84 63 14.1 14.6 84 84
row-gap Ð 84 63 14.1 14.6 84 84
gap Ð 84 63 14.1 14.6 84 84
!PRO TIP
Due to lack of support, for now use Þxed-length margins Ñ
e.g., margin-left: 20px; Ñ but understand that this brings
with them limitations & complications
Limitations: since you canÕt do a Þrst or last line selector,
you cannot exclude margins from the Þrst or last line if
wrapping occurs
Complications: if wrapping is not going to occur, you need to
use :nth-child, :first-child, or :last-child, as needed
Or just use grid if the design allows
margin: auto
margin: auto
Takes all available space (horizontally & vertically)
within a ßex line
Helpful since justify-self property isnÕt available in
Flexbox
Sizing
Flex Items
flex-grow
flex-shrink
flex-basis
flex
By default, ßex items are sized to their content,
similarly to table cells
!PRO TIP
Never use width & height with ßexbox layout! Instead of
width & height, size items using these for the cross axis:
È align-items: stretch
È align-content: stretch
È align-self: stretch
And this for the main axis:
È flex-basis
WeÕre going to cover flex-basis in this section
flex-grow
SpeciÞes if a flex item can grow if necessary to take
up available space inside its ßex container
Value: <number>
È 0: do not grow (default)
È Positive <number>: ßex item can grow
Any positive number for flex-grow allows the ßex item
to grow to Þll all available space
All ßex items that have the same number grow the same
amount
If those numbers differ, ßex items grow proportionally
based upon those numbers, with larger numbers
growing more
flex-shrink
SpeciÞes if a flex item can shrink if necessary to fit
inside its ßex container
Value: <number>
È 1: all ßex items can shrink to Þt (default)
È 0: do not shrink below the original size
È Positive <number>: ßex item can shrink
Any positive number for flex-shrink allows the ßex
item to shrink to Þt within its ßex container
All ßex items that have the same number shrink the
same amount
If those numbers differ, ßex items shrink propor-
tionally based upon those numbers, with larger
numbers shrinking more
Note thatÉ
È the default for flex-grow is 0: do not grow
È the default for flex-shrink is 1: shrink as necessary
!PRO TIP
We have said not to use width or height Ñ & we mean
that
You will, however, need to use max-width & min-width
on ßex items to limit their maximum growth or
shrinking
flex-basis
DeÞnes initial main size of a flex item before changes
caused by flex-grow or flex-shrink are applied
Values:
È auto (default)
È content
È max-content
È min-content
È <width>
What about width/height? Why use flex-basis
instead?
È flex-basis avoids content overßow problems
È flex-basis works along the main axis, so you donÕt
need to worry about flex-direction vs width/
height
È flex-basis is designed to work together with flex-
grow & flex-shrink
È flex-basis is part of the flex shorthand, which the
W3C recommends you use
flex-basis: auto
Sizes ßex items based on their content
Warning: this assumes you have not used width/
height, which we told you not to do!
If you do have width/height set, auto uses that value
instead (see why we told you not to use it?)
flex-basis: content
Sizes ßex items according to content while ignoring
width/height
Only supported in a few browsers!
You wonÕt need this because you wonÕt use width/
height, right? Right? Riiiiiiight?
flex-basis: max-content
Sizes ßex items to longest the content can be (if it were
not wrapped)
flex-basis: min-content
Sizes ßex items to narrowest the content can be, e.g.,
the longest word or image
flex-basis: <length>|<percentage>
Overrides the CSS height or width properties of a ßex
item (as if you were to disobey us & use them! Never!)
Can be either a <length> (e.g., px, em, rem, vh) or
<percentage> of the ßex container
flex-basis: 0
Do not base initial size on content, so growing &
shrinking occur without content in mind
flex-grow & flex-shrink
flex-basis (not auto)
width or height (No!)
Content (aka flex-basis: auto, the default)
Order of sizing effect for ßex items
flex
Instead of flex-grow, flex-shrink, & flex-basis, the
W3C encourages the use of the shorthand flex instead
Why?
È flex-grow, flex-shrink, & flex-basis always work
together when it comes to sizing ßex items, & flex
combines them intelligently
È flex sets values that make sense for common uses
flex values:
È <flex-grow> <flex-shrink> <flex-basis>
È initial (default)
È auto
È none
È <number>
È <length>|<percentage>
flex takes 1, 2, or 3 values
1 is a keyword or <number>
2 (e.g., 1 25px), but this is really confusing
3 for <flex-grow> <flex-shrink> <flex-basis>
Of these, we recommend 1 or 3
Single value <flex-grow> <flex-shrink> <flex-basis>
initial 0 1 auto
auto 1 1 auto
none 0 0 auto
<number> <number> 1 0
<length> 1 1 <length>
<percentage> 1 1 <percentage>
flex: initial
Equivalent to 0 1 auto
È Do not grow
È Shrink if not enough space in container
È Size based on content
Default for flex
flex: auto
Equivalent to 1 1 auto
È Grow to absorb free space
È Shrink if not enough space } Fully ßexible!
È Size based on content
flex: none
Equivalent to 0 0 auto
È Do not grow
È Do not shrink } Inßexible!
È Size based on content
flex: <number>
Equivalent to <number> 1 0
È Grow to absorb free space
È Shrink if not enough space in container
È Base size is not based on content, so growing &
shrinking occur without content in mind
Typically this will results in all ßex items having the
same size
flex-grow 11 12 28 9 9.2 29 4.4
flex-shrink 11 12 28 9 9.2 29 4.4
flex-basis 11* 12 28 9 9.2 29 4.4
flex 11 12 28 9 9.2 29 4.4
* See note at chnsa.ws/1ii
flex-basis:
auto 11 12 18 7 7 22 Y
content Ð 12* 61 Ð Ð Ð Ð
max-content Ð Ð 66 Ð Ð Ð Ð
min-content Ð Ð 66 Ð Ð Ð Ð
* No longer supported as of 79!
References
Click on a declaration to select it
Select multiple declarations
Now click on .container (or .item)
⌘C/Ctrl+C (click anywhere to reset)
Techniques
Tag Cloud
By using Flexbox, items grow to Þll the width of the
container so you can avoid a ragged edge on the right
What if each of the terms is linked?
We set display: contents on the <li>
because we only care about placing the
<a>s
Sticky Footer
Media Objects
WeÕre
going to
make
this in
class if
we have
time
Cards
WeÕre going to make this in class if we have time
Thank you!
scott@granneman.com
www.granneman.com
ChainsawOnATireSwing.com
@scottgranneman
jans@websanity.com
websanity.com
CSS Flexbox
Flexible, Robust Line-Based Layout
R. Scott Granneman r Jans Carton
© 2017 R. Scott Granneman
Last updated 2023-10-23
You are free to use this work, with certain restrictions.
3.7 For full licensing information, please see the last slide/page.
Changelog
2023-10-23 3.7: Updated compatibility table for safe &
unsafe
Changelog
2022-10-14 3.6: Added Flexbox cheatsheet to
References; added screenshots for column-gap, row-gap,
& gap
2021-05-07 3.5: Updated W3C spec screenshot; in initial
diagrams of terms, added diagrams assuming flex-
direction: column; created Terms section; updated
Triggering Flexbox Layout section; added example for
flex: 1 1 0; few more details about place-content
Changelog
2021-05-07 3.4: Converted theme to Granneman 1.7;
Þxed minor formatting issues
2020-07-23 3.3: Added dotted line to screenshot for
justify-content: space-around; updated
screenshots for Sticky Footer; converted to Granneman
1.6; Þxed all formatting errors; added slides on using
ßexbox with items using <a> in Tag Cloud
Changelog
2020-07-21 3.2: Moved some slides from Examples to
References; changed Examples to Techniques; added new
examples to Techniques
2020-07-13 3.1: Changed subtitle
2020-07-10 3.0: (conÕt. from ↓) added new section
Scooby-Doo & The Dangers of Data Loss covering safe;
added new section Aligning via Writing Mode covering
start & end
Changelog
2020-07-10 3.0: Moved Flexbox out of CSS Layout into its
own slide deck; added diagram explaining basic Flexbox
ßow; completely re-did all screenshots; re-did almost all
compatibility charts; added new section Direction,
Wrapping, & Order; better examples for using multiple
flex-direction; created new section Aligning Lines &
Items; lots of warnings not to use width & height;
renamed Sources to References; added CSS-TricksÕ ÒA
Complete Guide to FlexboxÓ; added 2 assignments to
Examples; (conÕt. ↑)
Licensing of this work
This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/.
You are free to:
È Share Ñ copy and redistribute the material in any medium or format
È Adapt Ñ remix, transform, and build upon the material for any purpose, even commercially
Under the following terms:
Attribution. You must give appropriate credit, provide a link to the license, and indicate if changes were made.
You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your
use. Give credit to:
Scott Granneman • www.granneman.com • scott@granneman.com
Share Alike. If you remix, transform, or build upon the material, you must distribute your contributions under
the same license as the original.
No additional restrictions. You may not apply legal terms or technological measures that legally restrict others
from doing anything the license permits.
Questions? Email scott@granneman.com