A complete guide to CSS Flexbox with practical examples

Hello! This is the first article in a series on HTML&CSS. And I decided to start with Flexbox. There are already quite a few guides on Flexbox in CSS on the Internet. But most often these are cheat sheets that don’t really help you understand how everything actually works. I will try to cover the topic using real examples. And at the end of the article I will share life hacks that I myself constantly use in my work.

If you prefer to perceive information in video format, you can watch the video on YouTube:

What is Flexbox and why is it used?

Flexbox in CSS is a special tool that helps you control the arrangement of elements on a web page.

Basic example

Basic example

Flexbox is especially useful for creating flexible and responsive layouts because the flex grid configuration can be easily changed across different device sizes.

Main application - creating an adaptive mesh

Main application – creating an adaptive mesh

Sandbox

Later in the article I will talk about all the properties using the example of a block with several elements.

Div with class container – this is the element with a white outline from the example. It will act as a flex container. And inside this block there will be the elements themselves with the class item. Initially, our example without special flex styles looks like this.

<div class="container">
  <div class="item item-1">item 1</div>
  <div class="item item-2">item 2</div>
  <div class="item item-3">item 3</div>
</div>
Example without styles

Example without styles

The example will be available in the sandbox on Codepen. You can simultaneously repeat all the steps from the article yourself, so the information will be absorbed even better.

display:flex

Meaning flex for the container is set via the property display. By default this property has the value display: block.

We write down the meaning display: flex. And then our block turns into a flex container.

.container {
  display: flex;
}
Example using display: flex

Example using display: flex

We will immediately notice how the values ​​line up.

flex-direction

In general, a flex container can arrange values ​​both horizontally and vertically. By default, as you can see from the previous example, the main axis is the horizontal axis. But we can change the direction using the property flex-direction.

If you write the value column at flex-directionthen the direction of the elements will change.

.container {
  display: flex;
  flex-direction: column;
}
flex-direction: column

flex-direction: column

U flex-direction Reversible properties are also available. For example, row-reverse displays values ​​horizontally in reverse order.

.container {
  display: flex;
  flex-direction: row-reverse;
}
flex-direction: row-reverse

flex-direction: row-reverse

A column-reverse sets values ​​in reverse vertical order.

.container {
  display: flex;
  flex-direction: column-reverse;
}

flex-direction: column-reverse

flex-wrap

If we add more elements to the example, we will see that they are compressed into 1 row and do not go to a new line.

<div class="container">
  <div class="item item-1">item 1</div>
  <div class="item item-2">item 2</div>
  <div class="item item-3">item 3</div>
  <div class="item item-4">item 4</div>
  <div class="item item-5">item 5</div>
  <div class="item item-6">item 6</div>
  <div class="item item-7">item 7</div>
  <div class="item item-8">item 8</div>
  <div class="item item-9">item 9</div>
</div>
flex-wrap: no-wrap

flex-wrap: no-wrap

The property is responsible for moving elements to a new line flex-wrap. If we indicate flex-wrap: wrapthen the elements will be moved to a new line.

.container {
  display: flex;
  flex-wrap: wrap; /* default - flex-wrap: no-wrap */
}
flex-wrap: wrap

flex-wrap: wrap

If you specify a value wrap-reversethen the elements will begin to line up starting from the bottom line and then move from the top to a new line.

.container {
  display: flex;
  flex-wrap: wrap-reverse;
}
flex-wrap: wrap-reverse

flex-wrap: wrap-reverse

justify-content

Property justify-content allows you to control the distance between elements along the main axis.

If you set the property to flex-endthen all elements will be pressed to the right edge.

.container {
  display: flex;
  justify-content: flex-end;
}
justify-content: flex-end

justify-content: flex-end

If we change to flex-start, then we will see how the elements are pressed to the left edge. And this, by the way, is the default value.

.container {
  display: flex;
  justify-content: flex-start; /* default */
}
justify-content: flex-start

justify-content: flex-start

Let's look at the other possible values ​​below.

Meaning center compresses all elements into the center.

.container {
  display: flex;
  justify-content: center;
}
justify-content: center

justify-content: center

Meaning space-beetwen sets the same distance between elements, but presses them along the edges.

.container {
  display: flex;
  justify-content: space-between;
}
justify-content: space-between

justify-content: space-between

Meaning space-around sets the same distance around each element. The effect of double indentation between elements is created, because the indents from each element are added.

.container {
  display: flex;
  justify-content: space-around;
}
justify-content: space-around

justify-content: space-around

Meaning space-evenly Creates equal spacing along the edges and between elements.

.container {
  display: flex;
  justify-content: space-evenly;
}
justify-content: space-evenly

justify-content: space-evenly

align-items

The next important property for a flex container is the property align-items. It sets the rules for how to align elements vertically, that is, along an additional axis.

But to see how it works, we need to make the elements of different heights. To do this, we will add a different number of lines in each item.

<div class="item item-1">
    item 1
    <div>text</div>
    <div>text</div>
</div>
<div class="item item-2">
    item 2
    <div>text</div>
</div>
<div class="item item-3">
    item 3
</div>
align-items: stretch

align-items: stretch

Initially, we see that all values ​​are stretched to the same height. This happens because align-items has the meaning stretch default.

Next, let's look at other available properties.

Meaning flex-start presses all elements up.

.container {
  display: flex;
  align-items: flex-start;
}
align-items: flex-start

align-items: flex-start

If you write the value flex-endthen all the elements will be pressed down.

.container {
  display: flex;
  align-items: flex-end;
}
align-items: flex-end

align-items: flex-end

Meaning center will align all elements to the center.

.container {
  display: flex;
  align-items: center;
}
align-items: center

align-items: center

Meaning baseline at first glance it looks like flex-start.

.container {
  display: flex;
  align-items: baseline;
}
align-items: baseline

align-items: baseline

But, if we set different font sizes in all elements, we will see that the elements move a little.

.item-1 {
  font-size: 32px;
}

.item-2 {
  font-size: 64px;
}

.item-3 {
  font-size: 16px;
}
align-items: baseline (with different font sizes)

align-items: baseline (with different font sizes)

Meaning baseline aligns elements along the bottom border of the first line of the font, the so-called baseline. Pay attention to the yellow line in the screenshot.

gap

The last property for a flex container is the property gap. It sets the distance between elements. Let's add more elements to the example and pass it to the property gap meaning 16px.

.container {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
gap: 16px

gap: 16px

We see that 16 pixels of padding have been added between elements.

But we can set different indents horizontally and vertically – to do this we need to pass 2 values ​​in a row. Let's try to convey 16px And 32px. And we will see that the first property will set the vertical margins, and the second property will set the horizontal margins.

.container {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 32px;
}
gap: 16px 32px

gap: 16px 32px

While this is all you need to know about the flex container, we have studied all its properties. Next, let's look at the properties for the elements themselves, which are inside the flex container.

order

And we can start with the property order. This property specifies the display order of a particular element. By default, all elements have order: 0 and then the elements are simply displayed in the order in which they are declared in the HTML.

Let's try to change the value order by 1 for the second element.

.item-2 {
  order: 1;
}
"order: 1" at "item 2"

“order: 1” for “item 2”

We immediately see that the second element went to the very end. Because the first element has a value order: 0the third element has the value order: 0and the second element has the value order: 1 and he accordingly goes to the very end.

Now let's try to change order for all elements.

.item-1 {
  order: 5;
}

.item-2 {
  order: 3;
}

.item-3 {
  order: 1;
}
Example with different orders

Example with different orders

By the way, order does not have to be 1 to 1 in a row. We can specify any values, and CSS simply compares which is greater and which is less.

align-self

Property align-self similar to align-items at the container, but only it is now set to the child element and is responsible only for its alignment.

For clarity, let’s make different heights for the elements and set align-items: center at the container. After this, the first element in the property align-self indicate the value flex-start.

.container {
  display: flex;
  align-items: center;
}

.item-2 {
  align-self: flex-start;
}
align-self: flex-start

align-self: flex-start

The second element is now aligned to the top border, although the remaining values ​​are aligned to the center.

If we change the value to flex-endthen the element will jump down.

.item-2 {
  align-self: flex-end;
}
align-self: flex-end

align-self: flex-end

And so you can change each element separately. For property align-self the same values ​​are available as for the property align-items for a flex container – flex-start, flex-end, center, baseline, stretch.

Next we move on to a series of the most complex properties. It is with them that beginners most often have problems.

flex-grow

And we'll start with the property flex-grow. This property allows you to specify the enlargement factor of the element relative to the free space inside the flex container. Free space is the remaining unfilled space inside the flex container, which is highlighted in yellow below.

Free container space

Free container space

Please note that the value flex-grow – this is not the ratio of elements to each other.

Default flex-grow has a value of 0. This is why initially the elements do not share space with each other. If we specify 1, then all elements become the same, because they evenly divided this free space among themselves.

.item {
  flex-grow: 1;
}
flex-grow: 1

flex-grow: 1

Now let's try to overwrite the value flex-grow the very first element by 0, and we will see that it has decreased again.

.item {
  flex-grow: 1;
}

.item-1 {
  flex-grow: 0;
}
Dividing free space

Dividing free space

Here the area of ​​potential free space is highlighted in yellow if all elements had flex-grow: 0. A value of 0 means that the first element does not participate in the division of free space in any way. And the remaining 2 elements divide the space between themselves, as can be seen from the lower scale in the screenshot above.

Now let's try to write different values flex-grow for all elements.

.item-1 {
  flex-grow: 1;
}

.item-2 {
  flex-grow: 2;
}

.item-3 {
  flex-grow: 3;
}

I would like to point out once again that these properties do not mean that the second element will be 2 times larger than the first, and the third element will be 3 times larger than the first. All elements will precisely divide the free space among themselves in equal proportions.

Dividing free space

Dividing free space

Relatively speaking, the first element will get 1 share of the yellow block, the second element will get 2 shares, and the third element will get 3 shares.

By the way, this property will stop working if the content doesn’t fit on the screen anyway. For example, let's add more elements and try to specify for .item-1 meaning flex-grow more than 0.

.item-1 {
  flex-grow: 2;
}
Example with an overflowing container

Example with an overflowing container

Nothing changes. This happens because there is no free space and, accordingly, there is nothing to divide.

Values ​​other than 0 and 1 are rarely used in practice. Therefore, the most important thing is to work out how exactly 0 and 1 interact with each other.

flex-basis

The next property is the property flex-basis. This is a super important property and is very often used in practice.

Property flex-basis indicates how wide the element will be by default. It may seem that flex-basis is a replacement width, But actually it is not. Property flex-basis establishes only optimal width, that is, if we pass flex-basis: 200pxthen it’s not at all a fact that the element will be width 200px – it can be either more or less. Let's figure out why this happens.

First, let's indicate for all elements flex-basis 200px:

.item {
  flex-basis: 200px;
flex-basis: 200px

flex-basis: 200px

We can make sure that it really became 200px. Let's try to substitute other values. For example, let's specify 50px.

.item {
  flex-basis: 50px;
}
flex-basis: 50px

flex-basis: 50px

Now we see that the elements actually occupy a larger width, 86px to be exact. This happens because they have been compressed to the smallest possible width, then the word item It just doesn't fit in the container.

A similar story will happen if you specify too large a value. For example, let's try in flex-basis hand over 300px.

.item {
  flex-basis: 300px;
}
flex-basis: 300px

flex-basis: 300px

And now we see that the elements, on the contrary, occupy a smaller width – 262px instead of 300px. Otherwise they simply would not fit in the container.

Very often in practice flex-basis use percentages. For example, let's write 25%:

.item {
  flex-basis: 25%;
}
flex-basis: 25%

flex-basis: 25%

We see that all the elements took up 1/4 of the part. This creates a grid on the sites. An example of such a grid will be shown at the end of the article.

flex-shrink

flex-shrink helps distribute space if there is not enough space in the container. Let's create a situation where there is not enough space. Let's try to indicate a big one flex-basis for the elements so that they do not fit. We will also add a fixed width to 600px for a flex container.

.container {
  display: flex;
  width: 600px;
}

.item {
  flex-basis: 300px;
}
flex-basis: 300px;

flex-basis: 300px;

In fact, the elements took on the width 200pxbut not 300px, as can be seen in the screenshot. Although ideally all three elements should occupy the width 900pxif only the container were larger.

If we specify flex-shrink: 0, then we will see the width of the content 900px. The elements will simply fall outside the container.

.item {
  flex-basis: 300px;
  flex-shrink: 0;
}
flex-basis: 300px;  flex-shrink: 0;

flex-basis: 300px; flex-shrink: 0;

This happens because flex-shink: 0 prevents elements from shrinking. And they strictly occupy the optimal width that we indicated in flex-basis. If we change the value to 1then we will return to the original state. 1 – this is the default value of the property flex-shrink.

Now let's try to give different flex-shrink for all the elements and let's see what comes of it.

.item {
  flex-basis: 300px;
}

.item-1 {
  flex-shrink: 1;
}

.item-2 {
  flex-shrink: 2;
}

.item-1 {
  flex-shrink: 3;
}
Example with different flex-shrink values

Example with different flex-shrink values

Pay attention to the actual width of the elements. The first element has a width 250pxthe second 200pxand the third 150px. Why did this happen?

Our container was conditionally overfilled by 300pxif there was an optimal width everywhere flex-basis. As a result, these 300px lost for all elements in proportion to the coefficient flex-shrink. The first one became smaller by 50pxthe second element became smaller by 100pxand the third element became smaller by 150px.

Shorthand notation

For these three properties (flex-grow, flex-shrink And flex-basis) there is a shorter notation. We can write like this:

.item {
  flex:  1 1 200px;
}

The first value is responsible for flex-growsecond for flex-shrinkand the third for flex-basis. You can write as you prefer, both options are correct – full and shortened.

Lifehacks

We have looked at all the flex properties of both the container and child elements. And now I will show you some examples from real practice. These are my life hacks that I constantly use at work.

On my YouTube video These examples are discussed in more detail. And here you can look at the code and try to experiment.

Centering an element

The first life hack is to center a single element in a flex container. A very simple hack that will also come in handy during interviews when they ask about centering methods.

Net

The next example is a little more complicated. But I don’t have a single project where I haven’t written such a grid for myself.

Stretching to available space

And the last example that I use very often in my work is a component with a fixed part. This fixed part should take up as much space as the content it contains. In this case, it is the “Submit” button. As you can see, it is always the same width. And the second part of the component should stretch to the entire available space.

Bottom line

You and I have learned to use flexes to the fullest. I also showed you some useful examples that you can safely use in your work. All examples from the article are available at link in github.


Subscribe to telegram channel Vaitishnaya — I post useful materials there and write honestly about IT

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *