Chapter 7 - A true CSS developer & flexible boxes

Chrome — What's up, Lulu?
Lulu — Nothing, I'm arranging my boxes. There's one problem, though!
Chrome — What's that?
Lulu — I want all of them centered. But they don't stay that way.
Chrome — Now you're talking like a CSS developer. One only becomes a true CSS developer after facing the problem of centering. But, there's a good news. Flexbox can solve your problem of centering.
Lulu — Oh, Flexbox. Yep, let's do this!

 
Flexbox (officially: Flexible Box Layout) is a new method of creating page layouts. It's a one-dimensional layout model i.e., items are placed along a single line - a row or a column.
It also solves some big, old CSS problems like —
  • Equal height columns
  • Holy Grail layout and grid systems
  • Vertical centering
 
However, flexbox is not all cakes and ale. It comes with 2 big problems —
  1. Flexbox adds a plethora of new properties for layout configuration. Here's a list of all 17 properties — CSS Properties flex, flex-direction, order, flex-wrap, flex-basis, flex-grow, flex-shrink, flex-flow. Alignment Properties justify-content, align-content, align-items, align-self, place-content, place-items, row-gap, column-gap, gap.
  1. Using flexbox can quickly become overwhelming and you may find yourself using it everywhere. That better be avoided and you must try to build layouts, as much as possible, in normal flow of document.
 

Lulu — So how do I deal with these problems?
Chrome — Well, I'll help you with the first problem and you gotta help yourself with the second.
Lulu — Copy that. Do I get a treat after lesson?
Chrome — Lulu, you really need to stop asking that.

 

Understanding Flexbox

The key to mastering Flexbox is to understand the core concepts that lay the foundation of flex layout. Once you understand how flexbox works, you do not need to remember all the properties. Just look 'em up when you need them! However, I promise, you'll memorize most of them by end of lesson.
We're going to start with Flex Container, Flex Items, the Main Axis, the Cross Axis and once done with these 4 things, everything else becomes as smooth as tuna gravy.

Flex Container & Flex Items

Any element on the page can be made a Flex Container by assigning display: flex or display: inline-flex; to it. The only difference between the two being — former is a block element and latter is an inline(-block). The flex container is basically your "flexbox".
As soon as you make an element a flex container, all of its direct children (including pseudo elements ::before and ::after) become Flex Items.
 

Lulu — Okay, but what does that mean to me? How do I confirm that I have flex container and flex items?
Chrome — To you, it means that you've just created a flex layout. You can confirm the activation of a flex layout by looking at the flex items. They must all be sitting in a line, next to each other.
Lulu — Wow. That simple?! Okay what if need my items all stacked vertically?
Chrome — Wait, Lulu! We are coming to it.

 
Let's jump to the two axes of Flexbox. All you need to do when working with flexbox is think in terms of these two axes.

Main Axis

A flex container's Main Axis is defined by the property flex-direction. It has 4 valid keyword values — row (default), row-reverse, column, column-reverse.
If you assign row or row-reverse to flex-direction, the main axis runs along the inline direction, i.e., horizontally. If you assign column or column-reverse, the main axis runs along the block direction, i.e., vertically.

Cross Axis

Cross Axis runs perpendicular to the Main Axis. Always.
 

Lulu — Wait, wait. I didn't quite get that. Also, where do the axes start and where they end?
Chrome — Wow. That's a nice question there! Many developers using flexbox don't understand that well! Okay, let me explain it to you.

 
When flex-direction is row, the start point of the Main Axis is left for ltr languages (like English) and right for rtl languages (like Arabic). The end point, then, takes the opposite side.
When flex-direction is row-reverse, the start and end points are reversed. Right becomes the start point of main axis for ltr languages and left for rtl languages.
However, when Main Axis is running vertically, i.e. when flex-direction is column, start point is always at top and end point at bottom. When flex-direction is switched to column-reverse, the start and end points of main axis are again reversed.
Figures below show how the main axis aligns when flex-direction is row(for ltr and rtl languages respectively).
Source: MDN
Source: MDN
Source: MDN
Source: MDN
 

Default Flexbox Behaviour

Every CSS property has an initial (or default) value, we know that. The case is no different for flexbox properties. Let's try to understand how flex elements behave by default.
  • Flex items always fall in a row, next to each other. (flex-direction: row).
  • Flex items "stretch" to take up entire space along cross axis. (align-content: normal, align-items: stretch).
  • Flex items do not "stretch" to fill space along main axis. (flex-grow: 0).
  • Flex items do not wrap. (flex-wrap: nowrap).
  • The base size of any flex item is determined either by its content or by dimensions assigned to it. (flex-basis: auto).
 

Size of Flexbox Items

To understand how browsers calculate the size of flexbox items and how you can control it, you need to understand 3 properties — flex-basis, flex-grow and flex-shrink.

flex-basis

initial value – auto • keyword values – fill, max-content, min-content, fit-content, content
It defines the size of a flex item. By default, if width is specified, it is used as flex-basis (size of element). If not, content size of element is used as flex-basis.

flex-grow

initial value 0 • valid values – positive integers
With flex-grow defined to a positive integer, flex item(s) can grow from its base size to fill up the remaining space along the main axis. Understand this with examples —
  1. If a flex item has flex-grow: 1, that item stretches to fill up the free space in container.
  1. If a flex item A has flex-grow: 1 and another item B has flex-grow: 2, the free space of container will be shared between the two such that B takes 2/3rd of free space and A takes 1/3rd.

flex-shrink

initial value 1 • valid values – positive integers
If the size of all flex items combined exceeds the size of container, then items can shrink to fit based on integer value assigned to flex-shrink. It is logically opposite of flex-grow.
 

Properties acting along Main Axis

flex-wrap

It tells browsers if flex items can wrap onto multiple lines or not. Has 3 valid keyword values —
  • nowrap (default) – Items are forced to stay in a single line.
  • wrap – Items can wrap onto multiple lines.
  • wrap-reverse – Same as wrap, but in reversed or opposite direction.

justify-content

It tells browsers how to distribute space among flex items along main axis.
justify-content comes with a big bag of valid keyword values and all all self explanatory. However, few most commonly used ones are — start (default), center, space-between, space-around, space-evenly.
 

Properties acting along Cross Axis

align-items

It controls the alignment of flex items along the cross axis. Technically, setting it on flex container automatically sets align-self on all flex items with same value.
Most common keyword values for align-items include — center, start, end, flex-start, flex-end.

align-self

By setting the property on a flex item, you can override the value of align-items set on flex container. It uses the same keyword values as align-items.

align-content

It distributes space of content items along cross axis. Although very commonly confused with align-items, it's actually more like justify-content.
To understand it better, think of a scenario where you have multiple lines in a flex container. Maybe because you applied flex-wrap: wrap. Now align-items will help position items in a single line and align-content will help distribute space around the lines.
It uses keyword values similar to justify-content such as — start (default), center, space-between, space-around, space-evenly.
 

Other Properties

order

It helps set the order of flex items. The flex items are always laid in ascending order value. You can assign any integer value to a flex item.

row-gap and column-gap

As the name suggests, the properties are used to set "gutters" between rows and columns respectively.
 

Shorthand properties

  • flex-flow : <flex-direction> | <flex-wrap>
  • gap : <row-gap> | <column-gap>
  • place-items : <align-items> | <justify-items>
  • place-content : <align-content> | <justify-content>
 
 

Lulu — Hmm, that was nice. I can see how flexbox can help me. But...
Chrome — Yes?
Lulu — I don't think I understand how all values work.
Chrome — I know. I told you flexbox is overwhelming. You need to play with flexbox and properties to get a hold on it. So I suggest you to go and try this Flexbox Playground.