Как работает css flexbox
Перейти к содержимому

Как работает css flexbox

  • автор:

Как работает CSS Flexbox: наглядное введение в систему компоновки элементов на веб-странице

CSS Flexbox — это технология для создания сложных гибких макетов за счёт правильного размещения элементов на странице. О самой технологии пишут здесь. Мы же решили объяснить возможности CSS Flexbox с использованием гифок.

263 показа
300 открытий

Вначале flex-grow каждого блока равен 1, в сумме получится 6. Значит, наш контейнер разделён на 6 частей. Каждый блок будет занимать 1/6 часть доступного пространства в контейнере. Когда flex-growтретьего блока становится равным 2, контейнер делится на 7 частей: 1 + 1 + 2 + 1 + 1 + 1. Теперь третий блок занимает 2/7 пространства, остальные — по 1/7. И так далее.

flex-grow работает только для главной оси, пока мы не изменим её направление.

flex-shrink

Прямая противоположность flex-grow. Определяет, насколько блоку можно уменьшиться в размере. flex-shrinkиспользуется, когда элементы не вмещаются в контейнер. Вы определяете, какие элементы должны уменьшиться в размерах, а какие — нет. По умолчанию значение flex-shrink для каждого блока равно 1. Это значит, что блоки будут сжиматься, когда контейнер будет уменьшаться.

Зададим flex-grow и flex-shrinkравными 1:

Basic concepts of flexbox

The flexible box layout module, usually referred to as flexbox, was designed as a one-dimensional layout model, and as a method that could offer space distribution between items in an interface and powerful alignment capabilities. This article gives an outline of the main features of flexbox, which we will be exploring in more detail in the rest of these guides.

When we describe flexbox as being one-dimensional we are describing the fact that flexbox deals with layout in one dimension at a time — either as a row or as a column. This can be contrasted with the two-dimensional model of CSS Grid Layout, which controls columns and rows together.

The two axes of flexbox

When working with flexbox you need to think in terms of two axes — the main axis and the cross axis. The main axis is defined by the flex-direction property, and the cross axis runs perpendicular to it. Everything we do with flexbox refers back to these axes, so it is worth understanding how they work from the outset.

The main axis

The main axis is defined by flex-direction , which has four possible values:

  • row
  • row-reverse
  • column
  • column-reverse

Should you choose row or row-reverse , your main axis will run along the row in the inline direction.

If flex-direction is set to row the main axis runs along the row in the inline direction.

Choose column or column-reverse and your main axis will run from the top of the page to the bottom — in the block direction.

If flex-direction is set to column the main axis runs in the block direction.

The cross axis

The cross axis runs perpendicular to the main axis, therefore if your flex-direction (main axis) is set to row or row-reverse the cross axis runs down the columns.

If flex-direction is set to row then the cross axis runs in the block direction.

If your main axis is column or column-reverse then the cross axis runs along the rows.

If flex-direction is set to column then the cross axis runs in the inline direction.

Start and end lines

Another vital area of understanding is how flexbox makes no assumption about the writing mode of the document. In the past, CSS was heavily weighted towards horizontal and left-to-right writing modes. Modern layout methods encompass the range of writing modes and so we no longer assume that a line of text will start at the top left of a document and run towards the right-hand side, with new lines appearing one under the other.

You can read more about the relationship between flexbox and the Writing Modes specification in a later article; however, the following description should help explain why we do not talk about left and right and top and bottom when we describe the direction that our flex items flow in.

If the flex-direction is row and I am working in English, then the start edge of the main axis will be on the left, the end edge on the right.

Working in English the start edge is on the left.

If I were to work in Arabic, then the start edge of my main axis would be on the right and the end edge on the left.

The start edge in a RTL language is on the right.

In both cases the start edge of the cross-axis is at the top of the flex container and the end edge at the bottom, as both languages have a horizontal writing mode.

After a while, thinking about start and end rather than left and right becomes natural, and will be useful to you when dealing with other layout methods such as CSS Grid Layout which follow the same patterns.

The flex container

An area of a document laid out using flexbox is called a flex container. To create a flex container, we set the value of the area’s container’s display property to flex or inline-flex . As soon as we do this the direct children of that container become flex items. As with all properties in CSS, some initial values are defined, so when creating a flex container all of the contained flex items will behave in the following way.

  • Items display in a row (the flex-direction property’s default is row ).
  • The items start from the start edge of the main axis.
  • The items do not stretch on the main dimension but can shrink.
  • The items will stretch to fill the size of the cross-axis.
  • The flex-basis property is set to auto . This means that, in each case, it will be equal to the flex item width in horizontal writing mode, and the flex item height in vertical writing mode. If the corresponding width / height is also set to auto , the flex-basis content value is used instead.
  • The flex-wrap property is set to nowrap . This means that the flex items will always remain in a single row or column, overflowing their container if their combined width / height exceeds the containing element width / height .

The result of this is that your items will all line up in a row, using the size of the content as their size in the main axis. If there are more items than can fit in the container, they will not wrap but will instead overflow. If some items are taller than others, all items will stretch along the full length of the cross-axis.

You can see in the live example below how this looks. Try editing the items or adding additional items to test the initial behavior of flexbox.

Changing flex-direction

Adding the flex-direction property to the flex container allows us to change the direction in which our flex items display. Setting flex-direction: row-reverse will keep the items displaying along the row, however the start and end lines are switched.

If we change flex-direction to column the main axis switches and our items now display in a column. Set column-reverse and the start and end lines are again switched.

The live example below has flex-direction set to row-reverse . Try the other values — row , column and column-reverse — to see what happens to the content.

Multi-line flex containers with flex-wrap

While flexbox is a one dimensional model, it is possible to cause our flex items to wrap onto multiple lines. In doing so, you should consider each line as a new flex container. Any space distribution will happen across that line, without reference to the lines on either side.

To cause wrapping behavior add the property flex-wrap with a value of wrap . Now, should your items be too large to all display in one line, they will wrap onto another line. The live sample below contains items that have been given a width, the total width of the items being too wide for the flex container. As flex-wrap is set to wrap , the items wrap. Set it to nowrap , which is also the initial value, and they will instead shrink to fit the container because they are using initial flexbox values that allows items to shrink. Using nowrap would cause an overflow if the items were not able to shrink, or could not shrink small enough to fit.

Find out more about wrapping flex items in the guide Mastering Wrapping of Flex Items.

The flex-flow shorthand

You can combine the two properties flex-direction and flex-wrap into the flex-flow shorthand. The first value specified is flex-direction and the second value is flex-wrap .

In the live example below try changing the first value to one of the allowable values for flex-direction — row , row-reverse , column or column-reverse , and also change the second to wrap and nowrap .

Properties applied to flex items

To have more control over flex items we can target them directly. We do this by way of three properties:

We will take a brief look at these properties in this overview, and you can gain a fuller understanding in the guide Controlling Ratios of Flex Items on the Main Axis.

Before we can make sense of these properties we need to consider the concept of available space. What we are doing when we change the value of these flex properties is to change the way that available space is distributed amongst our items. This concept of available space is also important when we come to look at aligning items.

If we have three 100 pixel-wide items in a container which is 500 pixels wide, then the space we need to lay out our items is 300 pixels. This leaves 200 pixels of available space. If we don’t change the initial values then flexbox will put that space after the last item.

This flex container has available space after laying out the items.

If we instead would like the items to grow and fill the space, then we need to have a method of distributing the leftover space between the items. This is what the flex properties that we apply to the items themselves, will do.

The flex-basis property

The flex-basis is what defines the size of that item in terms of the space it leaves as available space. The initial value of this property is auto — in this case the browser looks to see if the items have a size. In the example above, all of the items have a width of 100 pixels and so this is used as the flex-basis .

If the items don’t have a size then the content’s size is used as the flex-basis. This is why when we just declare display: flex on the parent to create flex items, the items all move into a row and take only as much space as they need to display their contents.

The flex-grow property

With the flex-grow property set to a positive integer, flex items can grow along the main axis from their flex-basis . This will cause the item to stretch and take up any available space on that axis, or a proportion of the available space if other items are allowed to grow too.

If we gave all of our items in the example above a flex-grow value of 1 then the available space in the flex container would be equally shared between our items and they would stretch to fill the container on the main axis.

The flex-grow property can be used to distribute space in proportion. If we give our first item a flex-grow value of 2, and the other items a value of 1 each, 2 parts of the available space will be given to the first item (100px out of 200px in the case of the example above), 1 part each the other two (50px each out of the 200px total).

The flex-shrink property

Where the flex-grow property deals with adding space in the main axis, the flex-shrink property controls how it is taken away. If we do not have enough space in the container to lay out our items, and flex-shrink is set to a positive integer, then the item can become smaller than the flex-basis . As with flex-grow , different values can be assigned in order to cause one item to shrink faster than others — an item with a higher value set for flex-shrink will shrink faster than its siblings that have lower values.

The minimum size of the item will be taken into account while working out the actual amount of shrinkage that will happen, which means that flex-shrink has the potential to appear less consistent than flex-grow in behavior. We’ll therefore take a more detailed look at how this algorithm works in the article Controlling Ratios of items along the main axis.

Note: These values for flex-grow and flex-shrink are proportions. Typically if we had all of our items set to flex: 1 1 200px and then wanted one item to grow at twice the rate, we would set that item to flex: 2 1 200px . However you could also use flex: 10 1 200px and flex: 20 1 200px if you wanted.

Shorthand values for the flex properties

You will very rarely see the flex-grow , flex-shrink , and flex-basis properties used individually; instead they are combined into the flex shorthand. The flex shorthand allows you to set the three values in this order — flex-grow , flex-shrink , flex-basis .

The live example below allows you to test out the different values of the flex shorthand; remember that the first value is flex-grow . Giving this a positive value means the item can grow. The second is flex-shrink — with a positive value the items can shrink, but only if their total values overflow the main axis. The final value is flex-basis ; this is the value the items are using as their base value to grow and shrink from.

There are also some predefined shorthand values which cover most of the use cases. You will often see these used in tutorials, and in many cases these are all you will need to use. The predefined values are as follows:

  • flex: initial
  • flex: auto
  • flex: none
  • flex:

Setting flex: initial resets the item to the initial values of flexbox. This is the same as flex: 0 1 auto . In this case the value of flex-grow is 0, so items will not grow larger than their flex-basis size. The value of flex-shrink is 1, so items can shrink if they need to rather than overflowing. The value of flex-basis is auto . Items will either use any size set on the item in the main dimension, or they will get their size from the content size.

Using flex: auto is the same as using flex: 1 1 auto ; everything is as with flex:initial but in this case the items can grow and fill the container as well as shrink if required.

Using flex: none will create fully inflexible flex items. It is as if you wrote flex: 0 0 auto . The items cannot grow or shrink but will be laid out using flexbox with a flex-basis of auto .

The shorthand you often see in tutorials is flex: 1 or flex: 2 and so on. This is as if you used flex: 1 1 0 or flex: 2 1 0 and so on, respectively. The items can grow and shrink from a flex-basis of 0.

Try these shorthand values in the live example below.

Alignment, justification and distribution of free space between items

A key feature of flexbox is the ability to align and justify items on the main- and cross-axes, and to distribute space between flex items. Note that these properties are to be set on the flex container, not on the items themselves.

align-items

The align-items property will align the items on the cross axis.

The initial value for this property is stretch and this is why flex items stretch to the height of the flex container by default. This might be dictated by the height of the tallest item in the container, or by a size set on the flex container itself.

You could instead set align-items to flex-start in order to make the items line up at the start of the flex container, flex-end to align them to the end, or center to align them in the center. Try this in the live example — I have given the flex container a height in order that you can see how the items can be moved around inside the container. See what happens if you set the value of align-items to:

  • stretch
  • flex-start
  • flex-end
  • center

justify-content

The justify-content property is used to align the items on the main axis, the direction in which flex-direction has set the flow. The initial value is flex-start which will line the items up at the start edge of the container, but you could also set the value to flex-end to line them up at the end, or center to line them up in the center.

You can also use the value space-between to take all the spare space after the items have been laid out, and share it out evenly between the items so there will be an equal amount of space between each item. To cause an equal amount of space on the right and left of each item use the value space-around . With space-around , items have a half-size space on either end. Or, to cause items to have equal space around them use the value space-evenly . With space-evenly , items have a full-size space on either end.

Try the following values of justify-content in the live example:

  • flex-start
  • flex-end
  • center
  • space-around
  • space-between
  • space-evenly

In the article Aligning Items in a Flex Container we will explore these properties in more depth, in order to have a better understanding of how they work. These simple examples however will be useful in the majority of use cases.

justify-items

The justify-items property is ignored in flexbox layouts.

Next steps

After reading this article you should have an understanding of the basic features of flexbox. In the next article, we will look at how this specification relates to other parts of CSS.

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on Sep 18, 2023 by MDN contributors.

Your blueprint for a better internet.

Flexbox

Flexbox is a one-dimensional layout method for arranging items in rows or columns. Items flex (expand) to fill additional space or shrink to fit into smaller spaces. This article explains all the fundamentals.

Prerequisites: HTML basics (study Introduction to HTML), and an idea of how CSS works (study Introduction to CSS.)
Objective: To learn how to use the Flexbox layout system to create web layouts.

Why Flexbox?

For a long time, the only reliable cross-browser compatible tools available for creating CSS layouts were features like floats and positioning. These work, but in some ways they’re also limiting and frustrating.

The following simple layout designs are either difficult or impossible to achieve with such tools in any kind of convenient, flexible way:

  • Vertically centering a block of content inside its parent.
  • Making all the children of a container take up an equal amount of the available width/height, regardless of how much width/height is available.
  • Making all columns in a multiple-column layout adopt the same height even if they contain a different amount of content.

As you’ll see in subsequent sections, flexbox makes a lot of layout tasks much easier. Let’s dig in!

Introducing a simple example

In this article, you’ll work through a series of exercises to help you understand how flexbox works. To get started, you should make a local copy of the first starter file — flexbox0.html from our GitHub repo. Load it in a modern browser (like Firefox or Chrome) and have a look at the code in your code editor. You can also see it live here.

Image showing the starting point of Flexbox tutorial

Specifying what elements to lay out as flexible boxes

To start with, we need to select which elements are to be laid out as flexible boxes. To do this, we set a special value of display on the parent element of the elements you want to affect. In this case we want to lay out the elements, so we set this on the :

section  display: flex; > 

This causes the element to become a flex container and its children to become flex items. The result of this should be something like so:

A two row container that includes a single column in the first row and a 3-column layout in the second row that shows how a webpage can be divided into different layouts depending on the contents

So, this single declaration gives us everything we need. Incredible, right? We have our multiple column layout with equal-sized columns, and the columns are all the same height. This is because the default values given to flex items (the children of the flex container) are set up to solve common problems such as this.

To be clear, let’s reiterate what is happening here. The element we’ve given a display value of flex to is acting like a block-level element in terms of how it interacts with the rest of the page, but its children are laid out as flex items. The next section will explain in more detail what this means. Note also that you can use a display value of inline-flex if you wish to lay out an element’s children as flex items, but have that element behave like an inline element.

The flex model

When elements are laid out as flex items, they are laid out along two axes:

Three flex items in a left-to-right language are laid out side-by-side in a flex container. The main axis — the axis of the flex container in the direction in which the flex items are laid out — is horizontal. The ends of the axis are main-start and main-end and are on the left and right respectively. The cross axis is vertical; perpendicular to the main axis. The cross-start and cross-end are at the top and bottom respectively. The length of the flex item along the main axis, in this case, the width, is called the main size, and the length of the flex item along the cross axis, in this case, the height, is called the cross size.

  • The main axis is the axis running in the direction the flex items are laid out in (for example, as a row across the page, or a column down the page.) The start and end of this axis are called the main start and main end.
  • The cross axis is the axis running perpendicular to the direction the flex items are laid out in. The start and end of this axis are called the cross start and cross end.
  • The parent element that has display: flex set on it (the in our example) is called the flex container.
  • The items laid out as flexible boxes inside the flex container are called flex items (the elements in our example).

Bear this terminology in mind as you go through subsequent sections. You can always refer back to it if you get confused about any of the terms being used.

Columns or rows?

Flexbox provides a property called flex-direction that specifies which direction the main axis runs (which direction the flexbox children are laid out in). By default this is set to row , which causes them to be laid out in a row in the direction your browser’s default language works in (left to right, in the case of an English browser).

Try adding the following declaration to your rule:

flex-direction: column; 

You’ll see that this puts the items back in a column layout, much like they were before we added any CSS. Before you move on, delete this declaration from your example.

Note: You can also lay out flex items in a reverse direction using the row-reverse and column-reverse values. Experiment with these values too!

Wrapping

One issue that arises when you have a fixed width or height in your layout is that eventually your flexbox children will overflow their container, breaking the layout. Have a look at our flexbox-wrap0.html example and try viewing it live (take a local copy of this file now if you want to follow along with this example):

The Sample flexbox example has all the flex items laid out in a single row of the flex container. The eighth flex item overflows the browser window, and the page has visible horizontal and vertical scroll bars as it cannot be accommodated within the width of the window as the previous seven flex items have taken the space available within the viewport. By default, the Browser tries to place all the flex items in a single row if the flex-direction is set to row or a single column if the flex-direction is set to column.

Here we see that the children are indeed breaking out of their container. One way in which you can fix this is to add the following declaration to your rule:

flex-wrap: wrap; 

Also, add the following declaration to your rule:

flex: 200px; 

Try this now. You’ll see that the layout looks much better with this included:

Flex items are laid out in multiple rows in the flex container. The flex-wrap property is set to

We now have multiple rows. Each row has as many flexbox children fitted into it as is sensible. Any overflow is moved down to the next line. The flex: 200px declaration set on the articles means that each will be at least 200px wide. We’ll discuss this property in more detail later on. You might also notice that the last few children on the last row are each made wider so that the entire row is still filled.

But there’s more we can do here. First of all, try changing your flex-direction property value to row-reverse . Now you’ll see that you still have your multiple row layout, but it starts from the opposite corner of the browser window and flows in reverse.

flex-flow shorthand

At this point it’s worth noting that a shorthand exists for flex-direction and flex-wrap : flex-flow . So, for example, you can replace

flex-direction: row; flex-wrap: wrap; 
flex-flow: row wrap; 

Flexible sizing of flex items

Let’s now return to our first example and look at how we can control what proportion of space flex items take up compared to the other flex items. Fire up your local copy of flexbox0.html, or take a copy of flexbox1.html as a new starting point (see it live).

First, add the following rule to the bottom of your CSS:

article  flex: 1; > 

Now add the following rule below the previous one:

article:nth-of-type(3)  flex: 2; > 

You can also specify a minimum size value within the flex value. Try updating your existing article rules like so:

article  flex: 1 200px; > article:nth-of-type(3)  flex: 2 200px; > 

This basically states, «Each flex item will first be given 200px of the available space. After that, the rest of the available space will be shared according to the proportion units.» Try refreshing and you’ll see a difference in how the space is shared.

The Sample flexbox example flex container has three flex items. All the flex items have a minimum width of 200 pixels—set using

The real value of flexbox can be seen in its flexibility/responsiveness. If you resize the browser window or add another element, the layout continues to work just fine.

flex: shorthand versus longhand

flex is a shorthand property that can specify up to three different values:

  • The unitless proportion value we discussed above. This can be specified separately using the flex-grow longhand property.
  • A second unitless proportion value, flex-shrink , which comes into play when the flex items are overflowing their container. This value specifies how much an item will shrink in order to prevent overflow. This is quite an advanced flexbox feature and we won’t be covering it any further in this article.
  • The minimum size value we discussed above. This can be specified separately using the flex-basis longhand value.

We’d advise against using the longhand flex properties unless you really have to (for example, to override something previously set). They lead to a lot of extra code being written, and they can be somewhat confusing.

Horizontal and vertical alignment

You can also use flexbox features to align flex items along the main or cross axis. Let’s explore this by looking at a new example: flex-align0.html (see it live also). We’re going to turn this into a neat, flexible button/toolbar. At the moment you’ll see a horizontal menu bar with some buttons jammed into the top left-hand corner.

Five buttons with labels Smile, Laugh, Wink, Shrug and Blush are laid out in a row in a flex container. The buttons are jammed into the top left-hand corner that doesn

First, take a local copy of this example.

Now, add the following to the bottom of the example’s CSS:

div  display: flex; align-items: center; justify-content: space-around; > 

Five buttons with labels Smile, Laugh, Wink, Shrug & Blush are laid out in a row in a flex container. The flex items are positioned at the center of the cross-axis by setting the align-items property to center. The flex items are spaced evenly along the main-axis by setting the justify-content property to space-around.

Refresh the page and you’ll see that the buttons are now nicely centered horizontally and vertically. We’ve done this via two new properties.

align-items controls where the flex items sit on the cross axis.

  • By default, the value is stretch , which stretches all flex items to fill the parent in the direction of the cross axis. If the parent doesn’t have a fixed height in the cross axis direction, then all flex items will become as tall as the tallest flex item. This is how our first example had columns of equal height by default.
  • The center value that we used in our above code causes the items to maintain their intrinsic dimensions, but be centered along the cross axis. This is why our current example’s buttons are centered vertically.
  • You can also have values like flex-start and flex-end , which will align all items at the start and end of the cross axis respectively. See align-items for the full details.

You can override the align-items behavior for individual flex items by applying the align-self property to them. For example, try adding the following to your CSS:

button:first-child  align-self: flex-end; > 

Five buttons with labels Smile, Laugh, Wink, Shrug & Blush are laid out in a row in a flex container. All the flex items except the first one are positioned at the center of the cross-axis, or vertically centered, by setting the align-items property to center. The first item is flush against the bottom of the flex container, at the end of the cross-axis, with the align-self property set to flex-end. The flex items are spaced evenly along the main-axis, or width, of the container.

Have a look at what effect this has and remove it again when you’ve finished.

justify-content controls where the flex items sit on the main axis.

  • The default value is flex-start , which makes all the items sit at the start of the main axis.
  • You can use flex-end to make them sit at the end.
  • center is also a value for justify-content . It’ll make the flex items sit in the center of the main axis.
  • The value we’ve used above, space-around , is useful — it distributes all the items evenly along the main axis with a bit of space left at either end.
  • There is another value, space-between , which is very similar to space-around except that it doesn’t leave any space at either end.

The justify-items property is ignored in flexbox layouts.

We’d like to encourage you to play with these values to see how they work before you continue.

Ordering flex items

Flexbox also has a feature for changing the layout order of flex items without affecting the source order. This is another thing that is impossible to do with traditional layout methods.

The code for this is simple. Try adding the following CSS to your button bar example code:

button:first-child  order: 1; > 

Refresh and you’ll see that the «Smile» button has moved to the end of the main axis. Let’s talk about how this works in a bit more detail:

  • By default, all flex items have an order value of 0.
  • Flex items with higher specified order values will appear later in the display order than items with lower order values.
  • Flex items with the same order value will appear in their source order. So if you have four items whose order values have been set as 2, 1, 1, and 0 respectively, their display order would be 4th, 2nd, 3rd, then 1st.
  • The 3rd item appears after the 2nd because it has the same order value and is after it in the source order.

You can set negative order values to make items appear earlier than items whose value is 0. For example, you could make the «Blush» button appear at the start of the main axis using the following rule:

button:last-child  order: -1; > 

Nested flex boxes

It’s possible to create some pretty complex layouts with flexbox. It’s perfectly OK to set a flex item to also be a flex container, so that its children are also laid out like flexible boxes. Have a look at complex-flexbox.html (see it live also).

The Sample flexbox example has three flex item children laid out in a row. The first two are the same width, the third is slightly wider. The third flex item is also a flex container. It has a set of buttons in two rows followed by text. The first row of buttons has 4 buttons that are laid out in a row; the buttons are the same width, taking up the full width of the container. The second row has a single button that takes up the entire width of the row on its own. This complex layout where few flex items are treated as flex containers.

section - article article article - div - button div button div button button button

Let’s look at the code we’ve used for the layout.

First of all, we set the children of the to be laid out as flexible boxes.

section  display: flex; > 
article  flex: 1 200px; > article:nth-of-type(3)  flex: 3 200px; display: flex; flex-flow: column; > 
article:nth-of-type(3) div:first-child  flex: 1 100px; display: flex; flex-flow: row wrap; align-items: center; justify-content: space-around; > 

Finally, we set some sizing on the button. This time by giving it a flex value of 1 auto. This has a very interesting effect, which you’ll see if you try resizing your browser window width. The buttons will take up as much space as they can. As many will fit on a line as is comfortable; beyond that, they’ll drop to a new line.

button  flex: 1 auto; margin: 5px; font-size: 18px; line-height: 1.5; > 

Cross-browser compatibility

Flexbox support is available in most new browsers: Firefox, Chrome, Opera, Microsoft Edge, and IE 11, newer versions of Android/iOS, etc. However, you should be aware that there are still older browsers in use that don’t support Flexbox (or do, but support a really old, out-of-date version of it.)

While you’re just learning and experimenting, this doesn’t matter too much; however, if you’re considering using flexbox in a real website, you need to do testing and make sure that your user experience is still acceptable in as many browsers as possible.

Flexbox is a bit trickier than some CSS features. For example, if a browser is missing a CSS drop shadow, then the site will likely still be usable. Not supporting flexbox features, however, will probably break a layout completely, making it unusable.

We discuss strategies for overcoming cross-browser support issues in our Cross browser testing module.

Test your skills!

You’ve reached the end of this article, but can you remember the most important information? You can find some further tests to verify that you’ve retained this information before you move on — see Test your skills: Flexbox.

Summary

That concludes our tour of the basics of Flexbox. We hope you had fun and will have a good play around with it as you proceed further with your learning. Next, we’ll have a look at another important aspect of CSS layouts: CSS Grids.

See also

  • CSS-Tricks Guide to Flexbox — an article explaining everything about Flexbox in a visually appealing way
  • Flexbox Froggy — an educational game to learn and better understand the basics of Flexbox
  • Previous
  • Overview: CSS layout
  • Next

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on Jul 17, 2023 by MDN contributors.

Your blueprint for a better internet.

Как работает CSS Flexbox: наглядное введение в систему компоновки элементов на веб-странице

Flexbox призван спасти нас от неприятных моментов чистого CSS (например, от вертикального выравнивания), и он отлично справляется со своей задачей. Но разобраться в принципах его работы порой бывает сложно, особенно, если вы новичок.

Основная задача Flexbox — сделать слои гибкими, а работу с ними — интуитивно понятными. Для достижения этой цели он позволяет контейнерам самим решать, как обращаться со своими дочерними элементами, в том числе изменять их размер и расстояние между ними.

Звучит неплохо, но давайте посмотрим, так ли оно гладко на практике. В этой статье мы изучим 9 самых популярных свойств Flexbox, разберемся, что они делают, и как они на самом деле работают.

СВОЙСТВО # 1 Display: Flex

Вот пример страницы:

У нас есть 4 разноцветных div’а разных размеров, которые находятся внутри серого div’а. У каждого div’а есть свойство display: block . Поэтому каждый квадрат занимает всю ширину строки.

Чтобы начать работать с Flexbox, нам нужно сделать наш контейнер flex-контейнером. Делается это так:

Вроде бы ничего особо и не изменилось — div’ы всего лишь встали в ряд. Но вы сделали что-то действительно мощное. Вы дали вашим квадратам классное свойство, называемое “flex-контекст”.

СВОЙСТВО # 2 Flex Direction

У flex-контейнера есть две оси: главная ось и перпендикулярная ей.

По умолчанию все предметы располагаются вдоль главной оси: слева направо. Поэтому наши квадраты выровнялись в линию, когда мы применили display: flex . Однако flex-direction позволяет вращать главную ось.

#container

Важно заметить, что flex-direction: column не выравнивает квадраты по оси, перпендикулярной главной. Главная ось сама меняет свое расположение и теперь направлена сверху вниз.

Есть еще парочка свойств для flex-direction: row-reverse и column-reverse .

600x258 flex 4

СВОЙСТВО # 3 Justify Content

Justify-content отвечает за выравнивание элементов по главной оси.

Вернемся к flex-direction: row .

Justify-content может принимать 5 значений:

  1. flex-start ;
  2. flex-end ;
  3. center ;
  4. space-between ;
  5. space-around .

Space-between задает одинаковое расстояние между квадратами, но не между контейнером и квадратами. Space-around также задает одинаковое расстояние между квадратами, но теперь расстояние между контейнером и квадратами равно половине расстояния между квадратами.

СВОЙСТВО # 4 Align Items

Если justify-content работает с главной осью, то align-items работает с осью, перпендикулярной главной оси.

Вернемся обратно к flex-direction: row и пройдемся по командам align-items :

  1. flex-start ;
  2. flex-end ;
  3. center ;
  4. stretch ;
  5. baseline .

Стоит заметить, что для align-items: stretch высота квадратов должна быть равна auto . Для align-items: baseline теги параграфа убирать не нужно, иначе получится вот так:

dIxrfoUa2r7vM62TGAlKN2KGOnIMmeNM Gwr

Чтобы получше разобраться в том, как работают оси, давайте объединим justify-content с align-items и посмотрим, как работает выравнивание по центру для двух свойств flex-direction :

600x313 flex 8

СВОЙСТВО # 5 Align Self

Align-self позволяет выравнивать элементы по отдельности.

#container  align-items: flex-start; > .square#one  align-self: center; > // Only this square will be centered.

Давайте для двух квадратов применим align-self , а для остальных применим align-items: center и flex-direction: row .

СВОЙСТВО # 6 Flex-Basis

Flex-basis отвечает за изначальный размер элементов до того, как они будут изменены другими свойствами Flexbox:

Flex-basis влияет на размер элементов вдоль главной оси.

Давайте посмотрим, что случится, если мы изменим направление главной оси:

Заметьте, что нам пришлось изменить и высоту элементов. Flex-basis может определять как высоту элементов, так и их ширину в зависимости от направления оси.

СВОЙСТВО # 7 Flex Grow

Это свойство немного сложнее.

Для начала давайте зададим нашим квадратикам одинаковую ширину в 120px:

По умолчанию значение flex-grow равно 0. Это значит, что квадратам запрещено расти (занимать оставшееся место в контейнере).

Попробуем задать flex-grow равным 1 для каждого квадрата:

Квадраты заняли оставшееся место в контейнере. Значение flex-grow аннулирует значение ширины.

Но здесь возникает один вопрос: что значит flex-grow: 1 ?

Попробуем задать flex-grow равным 999:

И… ничего не произошло. Так получилось из-за того, что flex-grow принимает не абсолютные значения, а относительные.

Это значит, что не важно, какое значение у flex-grow , важно, какое оно по отношению к другим квадратам:

Вначале flex-grow каждого квадрата равен 1, в сумме получится 6. Значит, наш контейнер поделен на 6 частей. Каждый квадрат будет занимать 1/6 часть доступного пространства в контейнере.

Когда flex-grow третьего квадрата становится равным 2, контейнер делится на 7 частей (1 + 1 + 2 + 1 + 1 + 1).

Теперь третий квадрат занимает 2/7 пространства, остальные — по 1/7.

Стоит помнить, что flex-grow работает только для главной оси (пока мы не поменяем ее направление).

СВОЙСТВО # 8 Flex Shrink

Flex-shrink — прямая противоположность flex-grow . Оно определяет, насколько квадрату можно уменьшиться в размере.

Flex-shrink используется, когда элементы не вмещаются в контейнер.

Вы определяете, какие элементы должны уменьшиться в размерах, а какие — нет. По умолчанию значение flex-shrink для каждого квадрата равно 1. Это значит, что квадраты будут сжиматься, когда контейнер будет уменьшаться.

Зададим flex-grow и flex-shrink равными 1:

Теперь давайте поменяем значение flex-shrink для третьего квадрата на 0. Ему запретили сжиматься, поэтому его ширина останется равной 120px:

Стоит помнить что flex-shrink основывается на пропорциях. То есть, если у квадрата flex-shrink равен 6, а у остальных он равен 2, то, это значит, что наш квадрат будет сжиматься в три раза быстрее, чем остальные.

СВОЙСТВО # 9 Flex

Flex заменяет flex-grow , flex-shrink и flex-basis .

Значения по умолчанию: 0 (grow) 1 (shrink) и auto (basis) .

Создадим два квадрата:

.square#one  flex: 2 1 300px; > .square#two  flex: 1 2 300px; >

У обоих квадратов одинаковый flex-basis . Это значит, что они оба будут шириной в 300px (ширина контейнера: 600px плюс margin и padding).

Но когда контейнер начнет увеличиваться в размерах, первый квадрат (с большим flex-grow ) будет увеличиваться в два раза быстрее, а второй квадрат (с наибольшим flex-shrink ) будет сжиматься в два раза быстрее.

flex 15

Как вещи растут и сжимаются

Когда увеличивается первый квадрат, он не становится в два раза больше второго квадрата, и когда уменьшается второй квадрат, он не становится в два раза меньше первого. Это происходит из-за того, что flex-grow и flex-shrink отвечают за темп роста и сокращения.

Немного математики

Начальный размер контейнера: 640px. Вычтем по 20px с каждой стороны для padding, и у нас останется 600px, как раз для двух квадратов.

Когда ширина контейнера становится равной 430px (потеря в 210px), первый квадрат ( flex-shrink: 1 ) теряет 70px. Второй квадрат ( flex-shrink: 2 ) теряет 140px.

Когда контейнер сжимается до 340px, мы теряем 300px. Первый квадрат теряет 100px, второй — 200px.

Тоже самое происходит и с flex-grow .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *