Flex Box
Resources
I. Introduction
Resources
Flexbox is a layout model that provides a more efficient way to arrange, align, and distribute space among items in a container. These items will flex (grow or shrink) based on rules you can define.
1. Flex Containers & Flex Items
- A flex container is the parent element that contains flex items and is styled with
display: flex
. - A flex item is a child element that lives directly inside of a flex container, they can be aligned and distributed inside this container. Most of the time, we can have nested flex boxes, so a flex item may be a flex container, containing other flex items.
2. The flex
property
The flex
declaration is a shorthand for 3 properties: flex-grow
, flex-shrink
, and flex-basis
that you can set on a flex item. These properties affect how flex items size themselves within their container.
The flex
property may be specified using one, two, or three values:
- One value: which can be of the following
- a value for
flex-grow
which is a positive number. - a value for
flex-basis
which can be a number, px, orauto
.
- a value for
- Two values:
- The first value must be a valid value for
flex-grow
- The second value must either be a valid value for
flex-shrink
orflex-basis
.
- The first value must be a valid value for
- Three values: the values must be in the following order:
flex-grow
,flex-shrink
,flex-basis
Example: The flex: 1
declaration equates to: flex-grow: 1
, flex-shrink: 1
, flex-basis: 0
= flex: 1 1 0
.
.flex-container{
display: flex;
}
.flex-item {
flex: 1;
}
flex-grow
: expects a single number (not negative) as its value, this value is used as the flex item’s “growth factor”. When we don’t specify the default value offlex-grow
is0
. Example:
- When we apply
flex: 1
to everydiv
, we’re telling everydiv
to grow the same amount. → everydiv
is the same size. - When we apply
flex: 2
to one of thedivs
, thatdiv
will grow to 2x the size of others.
<div class="flex-container">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
.flex-grow {
display: flex;
}
/* this selector selects all divs inside of .flex-container */
.flex-grow div {
background: peachpuff;
border: 4px solid brown;
height: 100px;
flex: 1 1 0%;
}
/* only div.two is selected here */
.flex-grow .two {
flex: 2 1 0%;
}
flex-shrink
: similar toflex-grow
, but sets the “shrink factor” of a flex item.flex-shrink
is only applied if the size of all flex items is larger than their parent container. → item will only shrink if the container is getting smaller than the item itself.- The default shrink value is
flex-shrink: 1
, which means all items will shrink evenly. - If you do not want an item to shrink, you must specify →
flex-shrink: 0
.
- The default shrink value is
<div class="flex-shrink">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div
.flex-shrink {
display: flex;
}
/* this selector selects all divs inside of .flex-container */
.flex-shrink div {
background: peachpuff;
border: 4px solid brown;
height: 100px;
width: 250px;
flex: 1 1 auto;
}
.flex-shrink .two {
flex-shrink: 0;
}
Note: When you specify
flex-grow
orflex-shrink
, the flex items don’t necessarily respect your given values forwidth
. When the parent container is big, the items may grow bigger to fill it, when the parent container is too small, the default behavior is to shrink to fit.
flex-basis
: sets the initial size of a flex item along the main axis, so any sort offlex-grow
orflex-shrink
starts from that baseline size.
In a Flex
row
,flex-basis
does the same thing aswidth
. In a Flexcolumn
,flex-basis
does the same thing asheight
.
- When you specify
flex: 1
on an element →flex-basis
defaults toflex-basis: 0%
. - When you don’t specify
flex-basis
, the default value isauto
. - When we declare
flex-basis: auto
, we’re asking the item to check for awidth
declaration. (The previous example offlex-shrink
does mention this.)
→ Like we saw with width
, flex-basis
is more of a suggestion than a hard constraint. At a certain point, there just isn't enough space for all of the elements to sit at their assigned size, so they have to compromise, to avoid an overflow.
3. flex
property’s values
initial
: the item is sized according to the specifiedwidth
andheight
properties.
- shrinks to its minimum size to fit the container, but does NOT grow to absorb any extra free space in the flex container.
- This is equivalent to setting
flex: 0 1 auto
.
auto
: the item is also sized according to the specifiedwidth
andheight
properties.
- grows to absorb any extra free space in the flex container, and shrinks to its minimum size to fit the container.
- This is equivalent to setting
flex: 1 1 auto
.
none
: the item is sized according to itswidth
andheight
properties.
- Fully inflexible: it neither shrinks nor grows in relation to the flex container.
- This is equivalent to setting
flex: 0 0 auto
.
II. Axes & Alignment
Resources
1. Axes
1. flex-direction
The orientation of items within a flex container can be controlled using the flex-direction
property. A flexbox can work either horizontally or vertically, the default direction for a flex container is horizontally (or row
) but you can always change this direction to vertical (or column
).
.flex-container{
display: flex;
flex-direction: column;
}
A flex-container contains 2 axes: the main axis and the cross axis. When we declare the flex-direction
, we are changing the direction of the main axis. The cross axis is always perpendicular to the main axis, hence, it changes direction with the main axis when we declare flex-direction
. ‘
Here are a few common values of flex-direction
:
flex-direction: row
: the main axis goes from left - right → the cross axis is now top - bottom.flex-direction: column
: the main axis goes from top - bottom → the cross axis is now left - right.flex-direction: row-reverse
: the main axis goes from right - left.flex-direction: column-reverse
: the main axis goes from bottom-top.
Note: By default, the
flex-direction: row
andflex-basis
value refers to thewidth
of an element. However, in acolumn
flex-container,flex-basis
refers to theheight
. This is becauseflex-basis
refers to the size of the item along the main axis. Try this piece of code to see howflex-direction: column
affectsflex: 1
..flex-container {
display: flex;
flex-direction: column;
}
.flex-item{
height: 80px;
flex: 1;
}→ Because
flex: 1
, that meansflex-basis: 0
→ the initialheight
of the item is now set to 0, and thediv
collapses because there’s noheight
orwidth
inside to fill thediv
.
Note:
flex-direction
technically changes the direction and orientation of the main axis, to change the direction of the cross axis (left → right, top → bottom), we can useflex-wrap: wrap-reverse
, which will be further discussed inflex-wrap
section.
2. order
In addition to reversing the order in which flex items are visually displayed, you can target individual items and change where they appear using order
.
- Source item 1:
order: 2
- Source item 2:
order: 3
- Source item 3:
order: 1
- Source item 4:
order: 3
- Source item 5:
order: 1
These items would be displayed on the page in the following order.
Flex items have a default order
value of 0
→ Items with an order
value greater than 0
will be displayed after any items that have not been given an explicit order
value.
order
can also take in negative values. As this is lower than 0, the item will always be displayed first, before any items that have not been given an explicit order
value.
2. Alignment
Resources
Using flex: 1
for the items makes each of the items grow to fill the available space in the flex container. But what if we want the flex items to stay with the width and height we give them, but distribute themselves differently within the container? We can use alignment properties for the flex-container.
1. justify-content
aligns and distributes space among items across the main axis. This property can have the following common values:
- Positional:
center
: aligns all items in the container to the center.start
,end
: aligns all items in the container to the start or end of the main axis.flex-start
,flex-end
: does the same thing asstart
orend
, but is affected byflex-direction: -reverse
, when the flex direction changesleft
,right
: aligns all items in the container to the left or right.
- Distributed Alignment:
space-between
: evenly distributes all items within the flex container along the main axis. The spacing between each pair of the adjacent items is the same, however, the first item has no space with the main-start edge, and the last item has no space with the main-end edge.space-around
: evenly distributes all items within the container along the main axis, just likespace-between
. However, the difference is, that the spacing between each pair of adjacent items is the same, AND the space between the first item and after the last item equals half of the space between each pair of adjacent items.space-evenly
: evenly distributes all items within the container along the main axis. However, the spacing between each pair of adjacent items, the main-start edge and the first item, and the main-end edge and the last item, are the same.stretch
: For flexbox, thestretch
value behaves asflex-start
orstart
. This is because, in flexbox, stretching is controlled using theflex-grow
property.
2. align-items
aligns and distributes items across the cross-axis. This property can have the following common values:
center
: the flex items' margin boxes are centered within the line on the cross-axis.start
,end
: the items are pushed to the start/end edge of the alignment container in the appropriate axis.flex-start
,flex-end
: does the same thing asstart
orend
, but is affected byflex-wrap: wrap-reverse
, when the flex-direction changes.self-start
,self-end
:stretch
: If the items are smaller than the alignment container, auto-sized items will be equally enlarged to fill the container, respecting the items' width and height limits.
Obvious Note: Because
justify-content
andalign-items
are based on the main and cross-axis of your container, their behavior changes when you change theflex-direction
of a flex-container.
3. Gap - the gap
property
The gap
on a flex container adds a specified space between flex items, similar to adding a margin to the items themselves.
.flex-container{
gap: 5px;
}
4. The flex-wrap
property
The flex-wrap
property sets whether flex items are forced onto one line or can wrap onto multiple lines. If wrapping is allowed, it sets the direction in which the lines are stacked. The flex-wrap
property can have the following values:
nowrap
: this is the default value. The flex items are laid out in a single line which may cause the flex container to overflow.wrap
: The flex items break into multiple lines.wrap-reverse
: Behaves the same aswrap
but cross-axis start and cross-axis end are permuted.