CSS Flexbox Fundamentals Visual Guide
Overview on CSS Flexible Box Module
Flexbox is short for
Flexible Box Module. A layout model that allows easy control of space distribution and alignment between html elements .
Flexbox controls positioning in just one dimension at time (row or column). For two dimension control CSS Grid Layout comes in place .
Given the following template:
The default behavior for the above divs, respecting the normal html document flow, is to be rendered from top to bottom, left to right and to take the entire body width, since its
display property defaults to
display: flex is applied to the
.container div, all direct child divs become
flex-items, and gain new behavior :
- they will be displayed in a single row, since
- they will be display from left to right
- items won’t stretch to fit the entire width (main axis), but they do shrink in order to do that.
- item stretches to fit cross axis (height in this example). If items have different heights they will stretch to the tallest one height
auto(item width will be set by its contents)
nowrap(if the container is not wide enough to fit the items, they won’t wrap, they will overflow instead)
For visualization purposes let’s stretch the container to take the entire height.
display: flex makes the container expand the whole width available. As opposed to
display: inline-flex, which makes the container collapse to the content’s width.
Once declared as a flex container, that element can be thought of in two axis. The main axis, defined by the
flex-direction property. And the cross axis, which is perpendicular to the first .
There are four values for the
The default value is
row, and it sets the main axis horizontally, from left to right and the cross axis intercepts it vertically, from top to bottom. Analogously, the
column value sets the axis vertically, from top to bottom and the cross axis from left to right. The
reverse property on both options reverses main axis 180°. The cross axis remains the same .
The flex-items behavior for those values can be observed below:
flex-wrap is the property that deals with the flex items when space in the container isn’t big enough to fit them all .
flex-wrap is set to
nowrap, which means that if the container cannot fit the items in a row with their original width, they will shrink to fit. If for some reason they are not able to shrink they will then, overflow the container .
By setting a 300px width to the items, the
nowrap option outputs this result:
in which, each item has shrank to approximately 70px to fit the container.
When the property is updated to
wrap, items’ width will now actually have their original value,
300px. Instead of overflowing the container, when the first row is not wide enough to fit
300px, the item will wrap to a new line . Each line should be thought of as an individual flex container. The space distribution in one container does not affect the other ones neighboring it .
But why are flex items taking the whole screen height? In the first section, container height was set to
100vh, so the space available is divided equally by the four rows necessary to fit the
300px items. Hadn’t we set the
100vh, container height would then respect the item content height, as in the image below :
Another option is
wrap-reverse, that inverts the cross axis. Set from top to bottom by the
wrap-reverse transforms it into bottom to top .
By inverting the main axis with
flex-direction: column, the elements that don’t fit wrap to another column and remaining space is evenly divided .
wrap-reverse option along with
column direction inverts the cross axis from right to left, producing the following output:
Since flexbox is a single dimension layout, on reversing the wrap, items are laid out from bottom to top (for row direction), but keep the left to right structure. Only the cross axis is altered.
flex-wrap can be declared in a single property:
flex-flow: [direction] [wrap] .
Gutter Between Items
Back to row/wrap. The entirety of the container can be filled by Applying
width: 33.3333% to items:
But if you wish to have a gap between the child divs, they won’t wrap as expected:
That can be solved by
calc() CSS function :
To get rid of the space in the edge of the container use negative margin on the container :
order property allows change to the visual order items appear in. Order is assigned to groups. By default all flex items are set to
order: 0, which means that all items belong to the same group, and they will be positioned by source order. In case of two or more groups, groups are ordered relatively to their integer values .
In the example below, there are three
1, laid out in that order.
This property redistributes items visually, but keeps their original source position on interactions like traversing them with tab key. That may be taken under consideration if items order matter for accessibility. the same goes for
In Flexbox, items alignment and space distribution along axis can be controlled by four properties :
justify-content: aligns all items in the main axis
align-items: aligns all items in the cross axis
align-self: aligns single items in the cross axis
align-content: controls space between flex lines on the cross axis
Applied to container,
justify-content handles items across the main axis. The six most-used options for its value are:
flex-start the default.
Also applied to container, the
align-items property handles alignment along the cross axis. Its default value is
stretch and the other option are
stretch option makes all items stretch either to the container height, if set, or to the height of the tallest item . The first picture shows container height set to
100vh, in the second one height not set.
The last of the four properties applied to flex container,
align-content distributes spaces between flex lines in the cross axis. As the latter, its initial value is
stretch and similarly
justify-content, accepts the following options:
align-items property actually works by setting
align-self on all flex items inside a container. By setting
align-self individually, it’s possible to override the general value. It accepts the same values as
align-items and ‘auto’ .
auto option resets the
align-self to the value defined globally for the container by
Sizing and flexibility of items can be controlled by three properties:
flex-basis. All three act on the main axis .
flex-grow: if there is extra space, how each item should be enlarged
flex-shrink: if there is not enough space, how each item should be reduced
flex-basis: before setting both properties above, what size should the item be
flex grow factor set by this property is a ratio that handles items size in relation to each other .
The default value is 0, which means that if there is available space, place it after the last item .
In the above example,
direction is set to
row, and each flex item
width is set to
60px. Since the container is
980px wide, there is
680px of available space. That space is called
positive free space .
1, the amount of positive free space is equally divided between flex items. Each item will get its width increased by
flex-grow: 2 to the third item, it gets twice the amount of positive free space available,
286px than the remaining items,
The picture below shows items with the
flex-grow property set to its content value.
flex-shrink handles items size, when there is not enough available space to fit them all in a container. So, it divides the
negative free space among items by shrinking them .
The next picture shows the
980px container, which holds five
300px wide items. Since there is no room to accommodate the
1500px needed, the default
flex shrink factor value of
1 makes every item shrink evenly to
By setting a ratio of
2 for the third item, it becomes two times smaller than the rest.
The last picture in this section shows each item holding its content value as flex shrink ratio.
flex-basis is the property that checks what is the size each item should have before it actually setting how much space available there will be. The default value is
auto, and the item width is either explicitly set by
width property, or it takes the content width. It also accepts pixels values .
The gif below shows a
800px wide container and five flex items set to
flex-basis: 160px. This tells the browser: ideally there is enough room to place all items, respecting their
160px width, and there is no positive/negative free space. In case there is not enough space, since
flex-shrink defaults to
1, all items are shrunk evenly. In case there is extra space,
flex-grow defaults to
0 and the empty space is place after the last item.
Next gif shows item 1 set to
flex-shrink: 10 and item 4 set to
flex-grow: 10. For negative free space, item 1 get 10 times less width. And for positive free space item 4 gets 10 times more width than others.
flex-basis also accepts the value
content, which regardless of
width being set or not, the width considered for free space calculation is the item’s content. If you do not want to consider item width for that calculation set basis to
flex is the shorthand property for
flex-basis, in that order .
It accepts the following predefined values:
initial: resets to flexbox defaults, same as flex: 0 1 auto
auto: flex-items have the ability to grow/shrink as needed, same as flex: 1 1 auto
none: makes items inflexible, same as flex: 0 0 auto
flex: 1: flex-items have the ability to grow/shrink and
flex-basisis set to zero, same as flex: 1 1 0
For cross browser compatibility is important to set properties with all necessary prefixes, in order to assure full support .
Auto prefixing every property by hand can be a very tedious task, besides making the styles very hard to maintain. Gulp is an alternative for automating those tasks.
In order to use Gulp, we have to add it to the project as a dependency. That’s done in the
package.json file, responsible for tracking dependencies and its versions. To create the file type in the terminal :
🌹 npm init
You will be prompted for project’s info. Just hit enter until it’s done. Output file will be something like this:
Install gulp globally:
🌹 npm install gulp -g
Install gulp and gulp-autoprefixer as a project dependencies:
🌹 npm install gulp --save-dev
🌹 npm install gulp-autoprefixer --save-dev
They should appear in
package.json file under
🌹 touch gulpfile.js
Add the following :
gulp extracts the content out of
styles.css and passes it through
gulp-autoprefixer. The result is placed under
-  What the Flexbox Course
-  Basic concepts of flexbox — 25/03/2018
-  Mastering Wrapping of Flex Items — 26/03/2018
-  Ordering Flex Items — 26/03/2018
-  Aligning Items in a Flex Container — 26/03/2018
-  StackOverflow — 27/03/2018
-  Controlling Ratios of Flex Items Along the Main Axis — 28/03/2018
-  Gulp
-  Gulp Autoprefixer