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 —
- Flexbox adds a plethora of new properties for layout configuration. Here's a list of all
17
properties — CSS Propertiesflex
,flex-direction
,order
,flex-wrap
,flex-basis
,flex-grow
,flex-shrink
,flex-flow
. Alignment Propertiesjustify-content
,align-content
,align-items
,align-self
,place-content
,place-items
,row-gap
,column-gap
,gap
.
- 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).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 integersWith
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 —- If a flex item has
flex-grow: 1
, that item stretches to fill up the free space in container.
- If a flex item A has
flex-grow: 1
and another item B hasflex-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 integersIf 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 aswrap
, 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.