Introduction to CSS Flexbox
Flexbox allows us to organize content inside a container, flowing either in the main axis (line) or the cross axis (column). The elements will be flexible, and shrink or extend according to the size of the container.
Flex-direction: Enabling Flexbox and controling the axis
To enable flexbox, first we need to use the display
property. We then will be able to control wether the obejects will flow from left to right (default), right to left (reverse), top to bottom, or bottom to top.
It is important to note that all elements inside a flexbox container will be shrunken in order to fit the size of the container, but will only stretch until the defined value set. So if the user defines a width: 200px
, the element will stretch until it reaches 200px.
When using Flexbox, we work with two axis: main and cross. The default setting is row
, in which the elements will be distributed along a horizontal line. This horizontal line will be considered the main-axis, and the vertical line would be the cross-axis. If whe define the flexbox to be a column, then the main-axis will be the vertical, and the cross will be the horizontal line.
Flex-direction: row - the default value
Here, we created a few div
inside a section
container, then we specify a width and height. We will then enable flexbox in CSS by typing display: flex
on the container.
Flex-direction: row-reverse
With the code flex-direction: row-reverse
, we now see the div elements being aligned from right to left. Their order come inverted as well.
Flex-direction: column
Another way to use flexbox is to organize the elements in a column. The property flex-direction: column
was used to achieve this.
Note how the div
elements are compressed. They still have the same height wnd width as the previous examples, but flexbox will use those set values as a maximum width/height and will try to fit the elements inside the container.
Flex-direction: column-reverse
Finally, the flex-direction: column-reverse
is similar to the previous one, but will begin at the bottom left of the container. As in the previous value, the main-axis is now the vertical line, but they will be arranged from bottom to top.
Note that the order os the div
elements is also reversed, begining from the bottom and going up.
Justify-content: defining the distribution across the main-axis
While flex-direction
changes the flow in which the elements are being display, justify-content
will change where the content will be aligned in the main-axis. It might be a little confusing, as the first will change from which side the content begins being arranged, but justify-content
will simply place the elements at one side or another, in spite of how they are originally arranged. It can also distibute the element evenly across the space, or center them.
One way to thiknk about it is that flex-direction
defines from which side of the main-axis it will start distributing the elements, while justify-content
will first distribute the content and then distribute it across the main-axis.
justify-content: flex-start - the default value
When enabling flexbox, the elements will receive this value as default. It will align the elements from the top-left of the container. The exemples shown above in flex-direction: row
and flex-direction: column
both use this default value.
justify-content: end
Using justify-content: end
the elements will be aligned at the right side of the container if in a row. If in a column, it will be aligned at the bottom.
Here's an example of this property use with the column. Note the difference between this and flex-direction: column-reverse
with the order of the blocks.
justify-content: center
In this example we used flex-direction: row-reverse
and then justify-content: center
.
justify-content: space-between, space-around and space-evenly
These setting are similar in the way theys distribute the elements evenly across the entire space of the container.
The first value, space-between
, is used to take all the extra space in the container and distribute evenly between the elements while ignoring the edges. In other words, no space will be add to the left of the first element nor to the right of the last element. If column
is being used, then no space will be added to the top em bottom.
space-around
is similar, but distributes the space evenly around both side of the element, including the borders. Note that it creates a larger gap between the elements than between the outer elements and the edge of the container, as the space is added to both sides of all elements. That means the space between two elements is the sum of both values.
If the larger gap between the elements is undesired, then the best option is to use space-evenly
.
Just to demonstrate, let's have three columns (which will be created using flexbox and space-between) and then apply these three values for comparison.
Flex-wrap: controlling overflow
By default, flexbox will squish the elements to fit inside the container, but only using the same row or column. If we want the contents to break into a new line or column, we must specify the value flex-wrap: wrap
.
Let's make our original containers smaller to illustrate the concept. Below are three containers. The one on the left is using the default wrap value (i.e. not wrapping), while the middle one sets flex-wrap: wrap
. The last of the three will receive the value flex-wrap: wrap-reverse
.
As we can see, warp-reverse
will change the order at which the line breaks. If the elements overflow in a row, they will push the first elements down and a new line will be added above. But if it were a column, then the new line would be added to the left, pushing the initial content to the right.
That logic won't change even if using row-reverse
and column-reverse
.
Finally, if flexbox was applied globally with a value of wrap, the user might decide to prevent some containers from inheriting the wrap value. In this case, the property flex-wrap: nowrap
can be used. That is the default value and is not necessary, except in order to override inherited wrap values.
Align-items: defining the distribution across the cross-axis
So far, we have seen how to define the axis at which the elements will be distributed, and some of the ways to control the flow of distribution. By default, flexbox will define the main-axis as the row, but we can change that with flex-direction: column
. We can also do a reverse row and a reverse column to change the order and direction at which the elements are distributed. With justify-content
, we are able to distribute those elementes across the main-axis.
To control the placement and distribution of elements on a different axis we need to use aling-items
. This property allows us to distribute the content on the cross-axis. In other words, if we're dealing with a row, then we can arrange elements vertically, and if we're dealing with a cloumn we can arrange them horizontally.
In the example below, we are using justify-content: space-evenly
for the row, and the align-items: center
to place them in the middle (vertically) of the container.
Note that items with different heights will be aligned by their center as well. This is very useful to place obejects neatly in a page.
There are other values for this property. Some of the most useful are end
, which will place at the end of the axis, and baseline
. The last one is different, as it will use the baseline of the content inside them as the alignment. Let's put some text inside the divs to illustrate that, and one of the text will have a larger font-size.
Align-content & align-self
When using wrap to break rows and columns into multiple lines, we can define how these new lines will be arranged by using align-content
. This porperty will only work if we have wrap turned on.
align-content: flex-start, flex-end, space-between, etc.
Tere are many values to this property, and they are similar to the ones already seen in justify-content
and align-items
. Let's see some quick examples. The first one below (left) is a row, with wrap and align-content: center
. The second one is a little more interesting: row with wrap, justify-content: space-evenly
and align-content: space-evenly
.
Now let's try it with columns. The first will receive the properties of column, wrap and align-content: end
. The second example will be a column, wrap, justify-content: space-evenly
and align-content: space-evenly
. Note how it loos similar to the row above, but the order of the blocks are different, going from top to bottom.
Align-self - for individual elements' alignment
This will be the first property that is applied to an individual element within a flexbox container. It is used to change the alignment of a single element. The example bellow have the property align-self: flex-end
to the second box, so it will be aligned to the bottem of the container.
Let's try another one with columns. We will have two examples. The first will be a column, nowrap, space-between, with align-self: center
applied to the two middle boxes. The second will have be a column, nowrap, space-evenly, and align-self: flex-end
to the first box.
Final considerations
As we can see, Flexbox give us a lot more flexibility when styling a plancing elements on a page. It is an important tool, and mastering it will be very useful.
We will continue this section by studiyng some ways we can make the website more responsive, with growing and shrinking elements, as well as responsive layouts that change acoording to screen size.