CSS Flexbox Fundamentals Visual Guide

Overview on CSS Flexible Box Module

Marina Ferreira
Aug 16, 2018 · 11 min read

Notes from MDN web docs taken while following What The Flexbox course from Wes Bos.

Introduction

Flexbox is short for . A layout model that allows easy control of space distribution and alignment between html elements [2].

Flexbox controls positioning in just one dimension at time (row or column). For two dimension control CSS Grid Layout comes in place [2].

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 property defaults to .

Normal Flow

Flex Items

When is applied to the div, all direct child divs become , and gain new behavior [2]:

  • they will be displayed in a single row, since defaults to
  • they will be display from left to right
Flex Items
  • 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
  • defaults to (item width will be set by its contents)
  • defaults to (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.

Flex Container

makes the container expand the whole width available. As opposed to , which makes the container collapse to the content’s width.

Flex Container

Flex Direction

Once declared as a flex container, that element can be thought of in two axis. The main axis, defined by the property. And the cross axis, which is perpendicular to the first [2].

There are four values for the property: , , and .

The default value is , and it sets the main axis horizontally, from left to right and the cross axis intercepts it vertically, from top to bottom. Analogously, the value sets the axis vertically, from top to bottom and the cross axis from left to right. The property on both options reverses main axis 180°. The cross axis remains the same [1][2].

The flex-items behavior for those values can be observed below:

Main Axis / Cross Axis

Flex Wrap

is the property that deals with the flex items when space in the container isn’t big enough to fit them all [3].

By default is set to , 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 [1][3].

By setting a 300px width to the items, the option outputs this result:

Flex Wrap — No Wrap

in which, each item has shrank to approximately 70px to fit the container.

When the property is updated to , items’ width will now actually have their original value, . Instead of overflowing the container, when the first row is not wide enough to fit , the item will wrap to a new line [3]. 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 [2].

Flex Wrap — Wrap

But why are flex items taking the whole screen height? In the first section, container height was set to , so the space available is divided equally by the four rows necessary to fit the items. Hadn’t we set the , container height would then respect the item content height, as in the image below [1]:

Container height not set

Another option is , that inverts the cross axis. Set from top to bottom by the property, transforms it into bottom to top [1].

Flex Wrap — Wrap Reverse

By inverting the main axis with , the elements that don’t fit wrap to another column and remaining space is evenly divided [1].

Flex Wrap — Column

And the option along with direction inverts the cross axis from right to left, producing the following output:

Wrap Reverse — Column

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 Flow

and can be declared in a single property: [2].

Gutter Between Items

Back to row/wrap. The entirety of the container can be filled by Applying to items:

No Gap

But if you wish to have a gap between the child divs, they won’t wrap as expected:

Non accounted gap

That can be solved by CSS function [1]:

calc()

To get rid of the space in the edge of the container use negative margin on the container [3]:

Flex container edge removed with negative margin

Order

The property allows change to the visual order items appear in. Order is assigned to groups. By default all flex items are set to , 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 [4].

In the example below, there are three , , and , laid out in that order.

Order property

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 [4].

Order — Source Position

Alignment

Alignment Digest

In Flexbox, items alignment and space distribution along axis can be controlled by four properties [5]:

  • : aligns all items in the main axis
  • : aligns all items in the cross axis
  • : aligns single items in the cross axis
  • : controls space between flex lines on the cross axis

justify-content

Justify Content

Applied to container, handles items across the main axis. The six most-used options for its value are: , , , , , , being the default.

align-items

Align Items

Also applied to container, the property handles alignment along the cross axis. Its default value is and the other option are , , and [5].

The option makes all items stretch either to the container height, if set, or to the height of the tallest item [5]. The first picture shows container height set to , in the second one height not set.

align-content

Align Content

The last of the four properties applied to flex container, distributes spaces between flex lines in the cross axis. As the latter, its initial value is and similarly , accepts the following options: , , , , , [5].

align-self

Align Self

The property actually works by setting on all flex items inside a container. By setting individually, it’s possible to override the general value. It accepts the same values as and ‘auto’ [5].

The option resets the to the value defined globally for the container by [5].

Flexbox Sizing

Sizing and flexibility of items can be controlled by three properties: , and . All three act on the main axis [2].

  • : if there is extra space, how each item should be enlarged
  • : if there is not enough space, how each item should be reduced
  • : before setting both properties above, what size should the item be

flex-grow

The set by this property is a ratio that handles items size in relation to each other [7].

The default value is 0, which means that if there is available space, place it after the last item [1].

Flex Grow — Default

In the above example, is set to , and each flex item is set to . Since the container is wide, there is of available space. That space is called [7].

By setting to , the amount of positive free space is equally divided between flex items. Each item will get its width increased by , totaling [7].

Flex Grow: 1

By appling to the third item, it gets twice the amount of positive free space available, than the remaining items, [7].

The picture below shows items with the property set to its content value.

Flex Grow: Content

flex-shrink

handles items size, when there is not enough available space to fit them all in a container. So, it divides the among items by shrinking them [7].

The next picture shows the container, which holds five wide items. Since there is no room to accommodate the needed, the default value of makes every item shrink evenly to .

By setting a ratio of 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 , and the item width is either explicitly set by property, or it takes the content width. It also accepts pixels values [7].

The gif below shows a wide container and five flex items set to . This tells the browser: ideally there is enough room to place all items, respecting their width, and there is no positive/negative free space. In case there is not enough space, since defaults to , all items are shrunk evenly. In case there is extra space, defaults to and the empty space is place after the last item.

Flex Basis — Default

Next gif shows item 1 set to and item 4 set to . 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.

also accepts the value , which regardless of 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 , and , in that order [2].

It accepts the following predefined values:

  • : resets to flexbox defaults, same as flex: 0 1 auto
  • : flex-items have the ability to grow/shrink as needed, same as flex: 1 1 auto
  • : makes items inflexible, same as flex: 0 0 auto
  • : flex-items have the ability to grow/shrink and is set to zero, same as flex: 1 1 0

Autoprefixer

For cross browser compatibility is important to set properties with all necessary prefixes, in order to assure full support [1].

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 file, responsible for tracking dependencies and its versions. To create the file type in the terminal [1]:

🌹 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 file under key.

Create a file:

🌹 touch gulpfile.js

Add the following [9]:

extracts the content out of and passes it through . The result is placed under folder.

References

Originally published at marina-ferreira.github.io on August 16, 2018.

This story is published in The Startup, Medium’s largest entrepreneurship publication followed by +393,714 people.

Subscribe to receive our top stories here.

The Startup

Get smarter at building your thing. Join The Startup’s +793K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Marina Ferreira

Written by

Software Engineer from São Paulo, Brazil.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +793K followers.

Marina Ferreira

Written by

Software Engineer from São Paulo, Brazil.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +793K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store