CSS Flexbox Fundamentals Visual Guide (2024)

CSS Flexbox Fundamentals Visual Guide (1)

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

Flexbox is short for Flexible Box Module. 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 display property defaults to block.

CSS Flexbox Fundamentals Visual Guide (4)

When display: flex is applied to the .container div, all direct child divs become flex-items, and gain new behavior [2]:

  • they will be displayed in a single row, since flex-direction defaults to row
  • they will be display from left to right
CSS Flexbox Fundamentals Visual Guide (5)
  • items won’t stretch to fit the entire width (main axis), but they do shrink in order to do that.
CSS Flexbox Fundamentals Visual Guide (6)
  • item stretches to fit cross axis (height in this example). If items have different heights they will stretch to the tallest one height
  • flex-basis defaults to auto (item width will be set by its contents)
  • flex-wrap defaults to 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.

CSS Flexbox Fundamentals Visual Guide (7)

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

There are four values for the flex-direction property: row, row-reverse, column and column-reverse.

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 [1][2].

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

CSS Flexbox Fundamentals Visual Guide (8)

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 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 [1][3].

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

CSS Flexbox Fundamentals Visual Guide (9)

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

CSS Flexbox Fundamentals Visual Guide (10)

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 [1]:

CSS Flexbox Fundamentals Visual Guide (11)

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

CSS Flexbox Fundamentals Visual Guide (12)

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

CSS Flexbox Fundamentals Visual Guide (13)

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

CSS Flexbox Fundamentals Visual Guide (14)

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-direction and flex-wrap can be declared in a single property: flex-flow: [direction] [wrap] [2].

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

CSS Flexbox Fundamentals Visual Guide (15)

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

CSS Flexbox Fundamentals Visual Guide (16)

That can be solved by calc() CSS function [1]:

CSS Flexbox Fundamentals Visual Guide (17)

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

CSS Flexbox Fundamentals Visual Guide (18)

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

In the example below, there are three ordinal groups, -1, 0 and 1, laid out in that order.

CSS Flexbox Fundamentals Visual Guide (19)

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

CSS Flexbox Fundamentals Visual Guide (20)

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

  • 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
CSS Flexbox Fundamentals Visual Guide (21)

Applied to container, justify-content handles items across the main axis. The six most-used options for its value are: flex-start, flex-end, center, space-around, space-between, space-evenly, being flex-start the default.

CSS Flexbox Fundamentals Visual Guide (22)

Also applied to container, the align-items property handles alignment along the cross axis. Its default value is stretch and the other option are flex-start, flex-end, center and baseline [5].

The stretch 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 100vh, in the second one height not set.

CSS Flexbox Fundamentals Visual Guide (23)

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: flex-start, flex-end, center, space-around, space-between, space-evenly [5].

CSS Flexbox Fundamentals Visual Guide (24)

The 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’ [5].

The auto option resets the align-self to the value defined globally for the container by align-items [5].

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

  • 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

The flex grow factor 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].

CSS Flexbox Fundamentals Visual Guide (25)

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

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

CSS Flexbox Fundamentals Visual Guide (26)

By appling flex-grow: 2 to the third item, it gets twice the amount of positive free space available, 286px than the remaining items, 173px [7].

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

CSS Flexbox Fundamentals Visual Guide (27)

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

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 196px.

CSS Flexbox Fundamentals Visual Guide (28)

By setting a ratio of 2 for the third item, it becomes two times smaller than the rest.

CSS Flexbox Fundamentals Visual Guide (29)

The last picture in this section shows each item holding its content value as flex shrink ratio.

CSS Flexbox Fundamentals Visual Guide (30)

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

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.

CSS Flexbox Fundamentals Visual Guide (31)

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.

CSS Flexbox Fundamentals Visual Guide (32)

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 0.

flex is the shorthand property for flex-grow, flex-shrink and flex-basis, in that order [2].

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-basis is 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 [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 package.json 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 package.json file under devDependencies key.

Create a gulpfile.js file:

🌹 touch gulpfile.js

Add the following [9]:

gulp extracts the content out of styles.css and passes it through gulp-autoprefixer. The result is placed under build folder.

CSS Flexbox Fundamentals Visual Guide (2024)
Top Articles
Latest Posts
Article information

Author: Ray Christiansen

Last Updated:

Views: 5508

Rating: 4.9 / 5 (69 voted)

Reviews: 84% of readers found this page helpful

Author information

Name: Ray Christiansen

Birthday: 1998-05-04

Address: Apt. 814 34339 Sauer Islands, Hirtheville, GA 02446-8771

Phone: +337636892828

Job: Lead Hospitality Designer

Hobby: Urban exploration, Tai chi, Lockpicking, Fashion, Gunsmithing, Pottery, Geocaching

Introduction: My name is Ray Christiansen, I am a fair, good, cute, gentle, vast, glamorous, excited person who loves writing and wants to share my knowledge and understanding with you.