Flexbox is a display property in CSS which lets us do some interesting things very easily like positioning single or multiple elements, creating column layouts, automatically managing spacing between items inside a div. The size of items can be fixed or dynamic, flex layout is flexible enough to work with either hence the term “flex”.
Every thing in flex box starts with a container. The container is just a div element which we make into a flexbox element so that we can start using all the wonderful features of flexbox.
We’ll take the following basic example to see how flexbox works and what we can do with it.
<div class="container">
<div class="item">Item #1</div>
<div class="item">Item #2</div>
<div class="item">Item #3</div>
</div>
.container {
display: flex;
}
.item {}
Applied to the container div, it defines the primary direction in which the items in the container will be layed out. Either vertically or horizontally and their reverse directions.
You can think of a flex container as having two axis like x-axis and y-axis. The flex-direction
property defines which of these axis will act as the primary axis for its items.
For example if we give flex-direction: row
, this makes the x-axis of the flex container its primary axis and all its items will be laid out horizontally from left to right.
If we do flex-direction: column-reverse
lets, this makes the y-axis its primary axis but in reverse order and the items will be laid out vertically from bottom to top.
default: row
.container{
...
flex-direction: row | row-reverse | column | column-reverse;
}
This property manages how the items are placed horizontally inside the container if the container has flex-direction
as row or row-reverse and how the items are placed vertically if the container’s flex-direction
property is column or column-reverse.
default: flex-start
.container{
...
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}
Similar to justify-content, this property manages the vertical spacing/position of the items inside the container if the container’s flex-direction
property is row or row-reverse and the horizontal spacing/position of the items if the container’s flex-direction
is column or column-reverse.
You can think of justify-content
and align-items
as the properties that manages the spacing/position of items along the x-axis and y-axis based on what the flex-direction
property of the container is.
default: stretch
.container{
...
align-items: flex-start | flex-end | center | stretch | baseline;
}
What happens when there are more child elements or items
than there is width of the container?
By default, all the items will try to be in one line, we can make them “wrap” according to the container width and the number of items.
default: nowrap
.container{
...
flex-wrap: nowrap | wrap | wrap-reverse;
}
Consider a case where there are enough items in a container that they don’t fit into a single line and you’re wrapping the items using the flex-wrap
property explained above into multiple rows.
The align-content
property then helps manage the vertical spacing/position between those ‘wrapped’ rows.
Think of align-content
as a justify-content
or align-items
but for rows of flex-items instead of just individual items.
And similar to justify-content
, behaviour of align-content
changes according to flex-direction
that is it’ll manage horizontal spacing/position if flex-direction of the container is set to column or column-reverse. Try out the various combinations in the playground in the last section.
default: normal
.container{
...
align-content: flex-start | flex-end | center | stretch | space-between | space-around;
}
This is used to override the align-items
property for a particular item otherwise dictated by the container.
.item{
...
align-self: auto | flex-start | flex-end | center | stretch | baseline;
}
You can make the items in your flex container expand and occupy the available space inside a container. Values are unitless and act as a ratio in respect to flex-grow
values of other items.
If all items have flex-grow:0
, then each item will have it’s default or set width.
If all items have flex-grow:1
, then each of the item will expand to fill the available space and have the same width.
If two items have flex-grow:1
and one item has flex-grow:2
lets say, then the item with flex-grow
value 2 will take up twice the amount of space (if available) as that of items with flex-grow
value 1.
default: 0
.item{
...
flex-grow: 3;
}
Same as flex-grow
but to shrink the space occupied by items insted of expanding to occupy the available space.
default: 1
.item{
...
flex-shrink: 3;
}
By default, all items inside a container that have order
value 0 will appear in the container in the order they’re laid out in the code. But we can dynamically change the position of items inside a container by changing this property.
default: 0
.item{
...
order: 3;
}
The items that don’t have the order field appear as they would have normally appeared in the DOM. But if you give order: -1
to item #3 it’ll come before item #2.
This property defines the default size of an item before the rest of the available space is distributed to the items.
default: auto
.item{
...
flex-basis: 50px; /* or 50rem or 50% */
}
Shorthand for:
default: 0 1 auto
.item{
...
flex: 2 1 30%;
}
Shorthand for:
default: row nowrap
.container{
...
flex-flow: row-reverse wrap;;
}