Flexbox examples. Layout using CSS Flexbox

In this article, we'll introduce CSS Flexbox technology, designed to create flexible web page layouts.

Purpose of CSS Flexbox

CSS Flexbox is for creating flexible layouts. Using this technology, you can very simply and flexibly arrange elements in a container, distribute the available space between them, and align them in one way or another, even if they do not have specific dimensions.

CSS Flexbox makes creating responsive designs much easier than using Float and positioning.

Flexbox can be used both for CSS markup of an entire page and its individual blocks.

Browser support for CSS Flexbox

CSS Flexbox is supported by all modern browsers currently in use (using prefixes: IE10+, Edge12+, Firefox 2+, Chrome 4+, Safari 3.1+, Opera 12.1+, iOS Safari 3.2, Opera mini, Android 2.1+, Blackberry 7+) .

CSS Flexbox Basics

Creating CSS markup using Flexbox starts with setting the necessary HTML element CSS display properties with the value flex or flex-inline .

After this, this element becomes a flex container, and all of its immediate child elements are flex elements. Moreover, when we talk about flexbox, we mean only an element with display:flex or display:flex-inline and all elements directly located in it. Thus, in CSS Flexbox there are only two types of elements: a flex container and a flex element.


Prefix and max-width properties have been added to CSS to support layout in most browsers.

To “turn” a block into a flex container, use the row class. Setting the width of the .col__article and .col__aside flex elements inside a flex container is done using the flex CSS property.

As an example, let's mark up another footer using flexbox and create a block consisting of three elements in the .col__article element (the minimum width of one element is 300px). We will place four blocks in the footer (the minimum width of one block is 200px).


Nothing stands still, technologies and standards are developing, new techniques and methods for website layout are appearing, for example, layout with tabular elements, which we did not consider for objective reasons, has been replaced by layout with floating elements.

Many code editors have a convenient quick markup plugin built in or available for download by default, Emmet, which allows you to do the basic markup of this example as follows: section>div*3>lorem+ Tab (value lorem generates the text that appears in the image below).

Please note that without any special effort, we got the columns of our layout to be the same height regardless of their content, and this is great. Elements

are not flex elements by default and are located in the flow third element

like regular block elements. If there is a need for this, then to make them flex elements, as you can guess, you need to set their parent to be a block (flex) or inline (inline-flex) flex container, but more on that in the next example.

The result of our example:

Inline flex container

By analogy with block elements, flex containers can be inline. Let's look at the difference between inline flex containers and block ones. In the previous example, we looked at the use of a block-level container, like a regular block-level element it occupies the entire width of the screen, and behaves like a regular block-level element. As for inline flex containers, they become regular inline elements, while maintaining the flexibility of the elements.

In the next example we will look at this difference, since the previous example would not be indicative, for the reason that the child flex elements were not explicitly given a size, and as a result, our container, whether it was inline or block, would behave the same and take up would be the entire width of the screen.

The difference between inline-flex containers and flex containers.

In this example we have placed two lowercase and two block flex containers, inside them we placed five elements

, which automatically became flex elements. In addition, for them we specified a width and height equal to 50 pixels.

To quickly generate a similar layout using Emmet type the following in the editor: div.inline-flex*2>div*5 + Tab , and the same thing only with another class div.flex*2>div*5 + Tab .

Taking a look at the result of our example, the difference between inline and block flex containers should now be obvious to you. An inline container behaves like an inline element and occupies the width required only by its child flex elements, while a block flex container, despite the size of its child flex elements, occupies the entire width of the screen.

The result of our example:

Rice. 205 An example of the difference between inline-flex containers and flex containers.

Direction? Which direction?

The direction of flex elements is formed based on the position of two axes: main axis flex container and its transverse axis, which is always located perpendicular to the main. Main axis in direction ltr (global HTML attribute dir , or the CSS direction property with the value ltr ) is positioned from left to right, and the cross one is from top to bottom (this is the default value), for the rtl value it is displayed in a mirror accordingly.

In short, layout with Flexbox gives us simple solutions once difficult tasks. For example, when you need to align an element vertically, or press the footer to the bottom of the screen, or simply insert several blocks in one row so that they occupy all the free space. Similar problems can be solved without flex. But as a rule, these solutions are more like “crutches” - techniques for using CSS for purposes other than their intended purpose. Whereas with flexbox such tasks are solved exactly as the flex model is intended.

CSS Flexible Box Layout Module (CSS module for layouts with flexible blocks), flexbox for short, was created to eliminate the shortcomings when creating a wide variety of HTML designs, including those adapted to different widths and heights, and make the layout logical and simple. And a logical approach, as a rule, works in unexpected places, where the result has not been checked - logic is everything!

Flexbox allows you to elegantly control a variety of parameters of elements inside the container: direction, order, width, height, longitudinal and cross alignment, distribution free space, tension and compression of elements.

Basic knowledge

A FlexBox consists of a Container and its Items (flexible elements).

To enable flexbox, any HTML element just needs to assign the CSS property display:flex; or display:inline-flex; .

1
2

After enabling the flex property, two axes are created inside the container: main and transverse (perpendicular (⊥), cross axis). All nested elements (of the first level) are lined up along the main axis. By default, the main axis is horizontal and directed from left to right (→), and the cross axis is correspondingly vertical and directed from top to bottom (↓).

The main and cross axes can be swapped, then the elements will be located from top to bottom (↓) and when they no longer fit in height, they will move from left to right (→) - that is, the axes simply swapped places. In this case, the beginning and end of the arrangement of the elements does not change - only the directions (axes) change! This is why you need to imagine the axes inside the container. However, one should not think that there are some “physical” axes and they influence something. The axis here is just the direction of movement of the elements inside the container. For example, if we specified the alignment of elements to the center of the main axis and then changed the direction of this main axis, then the alignment will change: the elements were in the middle horizontally, but became in the middle vertically... See the example.

One more important feature Flex box is the presence of rows in the transverse direction. To understand what we are talking about, let's imagine that there is a main horizontal axis, there are many elements and they do not “fit” into the container, so they move to another row. Those. a container looks like this: a container with two rows inside it, each row containing several elements. Introduced? Now remember that we can vertically align not only elements, but also rows! How this works is clearly seen in the example for the property. And this is what it looks like schematically:

CSS properties that can affect the layout model: float, clear, vertical-align, columns do not work in flex design. Here a different model for constructing a layout is used and these CSS properties are simply ignored.

Flexbox CSS properties

Flexbox contains different css rules to control the entire flex design. Some need to be applied to the main container, and others to the elements of this container.

For container

display:

Enables the flex property for the element. This property covers the element itself and its nested elements: only first-level descendants are affected - they will become elements of the flex container.

  • flex- the element stretches its entire width and has its full space among the surrounding blocks. Line breaks occur at the beginning and end of the block.
  • inline-flex- an element is wrapped around other elements. In this case, its internal part is formatted as a block element, and the element itself is formatted as inline.

flex and inline-flex differ in that they interact differently with surrounding elements, similar to display:block and display:inline-block .

flex-direction:

Changes the direction of the main axis of the container. The transverse axis changes accordingly.

  • row (default)- direction of elements from left to right (→)
  • column- direction of elements from top to bottom (↓)
  • row-reverse- direction of elements from right to left (←)
  • column-reverse- direction of elements from bottom to top ()
flex-wrap:

Controls the transfer of elements that do not fit into the container.

  • nowrap (default)- nested elements are placed in one row (with direction=row) or in one column (with direction=column) regardless of whether they fit into the container or not.
  • wrap- includes moving elements to the next row if they do not fit into the container. This enables the movement of elements along the transverse axis.
  • wrap-reverse- the same as wrap, only the transfer will not be down, but up (in the opposite direction).
flex-flow: direction wrap

Combines both flex-direction and flex-wrap properties. They are often used together, so the flex-flow property was created to help write less code.

flex-flow accepts the values ​​of these two properties, separated by a space. Or you can specify a single value for any property.

/* flex-direction only */ flex-flow: row; flex-flow: row-reverse; flex-flow: column; flex-flow: column-reverse; /* flex-wrap only */ flex-flow: nowrap; flex-flow: wrap; flex-flow: wrap-reverse; /* both values ​​at once: flex-direction and flex-wrap */ flex-flow: row nowrap; flex-flow: column wrap; flex-flow: column-reverse wrap-reverse; justify-content:

Aligns elements along the main axis: if direction=row, then horizontally, and if direction=column, then vertically.

  • flex-start (default)- the elements will go from the beginning (there may be some space left at the end).
  • flex-end- elements are aligned at the end (the space will remain at the beginning)
  • center- in the center (space will remain on the left and right)
  • space-between- the outermost elements are pressed against the edges (the space between the elements is distributed evenly)
  • space-around- free space is evenly distributed between the elements (the outermost elements are not pressed against the edges). The space between the edge of the container and the outer elements will be half as much as the space between the elements in the middle of the row.
  • space-evenly
align-content:

Aligns rows containing elements along the transverse axis. Same as justify-content only for the opposite axis.

Note: Works when there are at least 2 rows, i.e. If there is only 1 row, nothing will happen.

Those. if flex-direction: row , then this property will align invisible rows vertically. It is important to note here that the height of the block must be set rigidly and must be greater than the height of the rows, otherwise the rows themselves will stretch the container and any alignment of them becomes meaningless, because there is no free space between them... But when flex-direction: column , then the rows move horizontally → and the width of the container is almost always greater than the width of the rows and aligning the rows immediately makes sense...

  • stretch (default)- rows stretch to fill the row completely
  • flex-start- rows are grouped at the top of the container (there may be some space left at the end).
  • flex-end- rows are grouped at the bottom of the container (space will remain at the beginning)
  • center- rows are grouped in the center of the container (space will remain at the edges)
  • space-between- the outer rows are pressed against the edges (the space between the rows is distributed evenly)
  • space-around- free space is evenly distributed between the rows (the outermost elements are not pressed against the edges). The space between the edge of the container and the outer elements will be half as much as the space between the elements in the middle of the row.
  • space-evenly- the same as space-around , only the distance between the outer elements and the edges of the container is the same as between the elements.
align-items:

Aligns elements along a transverse axis within a row (invisible row). Those. The rows themselves are aligned via align-content , and the elements within these rows (rows) are aligned via align-items and all along the transverse axis. There is no such division along the main axis, there is no concept of rows and elements are aligned through justify-content .

  • stretch (default)- elements are stretched to fill the line completely
  • flex-start- elements are pressed to the beginning of the row
  • flex-end- elements are pressed to the end of the row
  • center- elements are aligned to the center of the row
  • baseline- elements are aligned to the text baseline

For container elements

flex-grow:

Sets the element's magnification factor when there is free space in the container. Default flex-grow: 0 i.e. none of the elements should grow and fill the free space in the container.

Default flex-grow: 0

  • If you specify flex-grow:1 for all elements, then they will all stretch equally and fill all the free space in the container.
  • If you specify flex-grow:1 to one of the elements, then it will fill all the free space in the container and alignments via justify-content will no longer work: there is no free space to align...
  • With flex-grow:1 . If one of them has flex-grow:2 then it will be 2 times larger than all the others
  • If all flex boxes inside a flex container have flex-grow:3 then they will be the same size
  • With flex-grow:3 . If one of them has flex-grow:12 then it will be 4 times larger than all the others

How it works? Let's say a container is 500px wide and contains two elements, each with a base width of 100px. This means there are 300 free pixels left in the container. Now, if we specify flex-grow:2; , and the second flex-grow: 1; , then the blocks will occupy the entire available width of the container and the width of the first block will be 300px, and the second 200px. This is explained by the fact that the available 300px of free space in the container was distributed between the elements in a 2:1 ratio, +200px for the first and +100px for the second.

Note: the value can be specified fractional numbers, for example: 0.5 - flex-grow:0.5

flex-shrink:

Sets the element's reduction factor. The property is the opposite of flex-grow and determines how the element should shrink if there is no free space left in the container. Those. the property starts working when the sum of the sizes of all elements is greater than the size of the container.

Default flex-shrink:1

Let's say the container is 600px wide and contains two elements, each 300px wide - flex-basis:300px; . Those. two elements completely fill the container. Give the first element flex-shrink: 2; , and the second flex-shrink: 1; . Now let's reduce the width of the container by 300px, i.e. elements must shrink by 300px to fit inside the container. They will shrink in a ratio of 2:1, i.e. the first block will shrink by 200px, and the second by 100px and the new element sizes will become 100px and 200px.

Note: you can specify fractional numbers in the value, for example: 0.5 - flex-shrink:0.5

flex-basis:

Sets the base width of the element - the width before other conditions affecting the width of the element are calculated. The value can be specified in px, em, rem, %, vw, vh, etc. The final width will depend on the base width and the values ​​of flex-grow, flex-shrink and the content inside the block. With auto, the element gets a base width relative to the content inside it.

Default: auto

Sometimes it's better to set the width of an element hard through the usual width property. For example, width: 50%; will mean that the element inside the container will be exactly 50%, but the flex-grow and flex-shrink properties will still work. This may be necessary when the element is stretched by the content inside it, more than specified in flex-basis. Example.

flex-basis will be “rigid” if stretch and shrink are set to zero: flex-basis:200px; flex-grow:0; flex-shrink:0; . All this can be written like this: flex:0 0 200px; .

flex: (grow shrink basis)

A short summary of the three properties: flex-grow flex-shrink flex-basis .

Default: flex: 0 1 auto

However, you can specify one or two values:

Flex: none; /* 0 0 auto */ /* number */ flex: 2; /* flex-grow (flex-basis goes to 0) */ /* not a number */ flex: 10em; /* flex-basis: 10em */ flex: 30px; /* flex-basis: 30px */ flex: auto; /* flex-basis: auto */ flex: content; /* flex-basis: content */ flex: 1 30px; /* flex-grow and flex-basis */ flex: 2 2; /* flex-grow and flex-shrink (flex-basis goes to 0) */ flex: 2 2 10%; /* flex-grow and flex-shrink and flex-basis */ align-self:

Allows you to change the align-items property, only for a single element.

Default: from align-items container

  • stretch- the element is stretched to fill the line completely
  • flex-start- the element is pressed to the beginning of the line
  • flex-end- the element is pressed to the end of the line
  • center- the element is aligned to the center of the line
  • baseline- the element is aligned to the text baseline

order:

Allows you to change the order (position, position) of an element in the general row.

Default: order: 0

By default, elements have order: 0 and are placed in the order of their appearance in the HTML code and the direction of the row. But if you change the value of the order property, then the elements will be arranged in the order of values: -1 0 1 2 3 ... . For example, if you specify order: 1 for one of the elements, then all zeros will go first, and then the element with 1.

This way, for example, you can move the first element to the end without changing the direction of movement of the remaining elements or the HTML code.

Notes

What is the difference between flex-basis and width?

Below are the important differences between flex-basis and width/height:

    flex-basis only works for the main axis. This means that with flex-direction:row flex-basis controls the width, and with flex-direction:column controls the height. .

    flex-basis only applies to flex elements. This means that if you disable flex for a container, this property will have no effect.

    Absolute container elements do not participate in flex construction... This means that flex-basis does not affect the flex elements of a container if they are absolute position:absolute . They will need to specify width/height.

  • When using the flex property, 3 values ​​(flex-grow/flex-shrink/flex-basis) can be combined and written briefly, but for width grow or shrink you need to write separately. For example: flex:0 0 50% == width:50%; flex-shrink:0; . Sometimes it's just inconvenient.

If possible, still prefer flex-basis. Use width only when flex-basis is not appropriate.

The difference between flex-basis and width - a bug or a feature?

The content inside a flex element pushes it and cannot go beyond it. However, if you set the width using width or max-width rather than flex-basis , then an element inside a flex container will be able to extend beyond the bounds of that container (sometimes this is exactly the behavior you want). Example:

Flex layout examples

Nowhere in the examples are prefixes used for cross-browser compatibility. I did this for easy reading of the css. Therefore, see examples in latest versions Chrome or Firefox.

#1 Simple example with vertical and horizontal alignment

Let's start from the very beginning simple example- vertical and horizontal alignment simultaneously and at any block height, even rubber.

Text in the middle

Or like this, without a block inside:

Text in the middle

#1.2 Separation (break) between flex block elements

To position container elements along the edges and randomly select an element after which there will be a break, you need to use the margin-left:auto or margin-right:auto property.

#2 Adaptive menu on flex

Let's create a menu at the very top of the page. On a wide screen it should be on the right. On average, align in the middle. And on the small one, each element must be on a new line.

#3 Adaptive 3 columns

This example shows how to quickly and conveniently make 3 columns, which, when narrowed, will turn into 2 and then into 1.

Please note that this can be done without using media rules, everything is on flex.

1
2
3
4
5
6

Go to jsfiddle.net and change the width of the “result” section

#4 Adaptive blocks on flex

Let's say we need to output 3 blocks, one large and two small. At the same time, it is necessary that the blocks adapt to small screens. We do:

1
2
3

Go to jsfiddle.net and change the width of the “result” section

#5 Gallery with flex and transition

This example shows how quickly you can make a cute accordion with pictures using flex. pay attention to transition property for flex.

#6 Flex to Flex (just an example)

The task is to make a flexible block. So that the beginning of the text in each block is on the same line horizontally. Those. As the width narrows, the blocks grow in height. It is necessary that the image is at the top, the button is always at the bottom, and the text in the middle starts along one horizontal line...

To solve this problem, the blocks themselves are stretched with flex and set to the maximum possible width. Each internal block is also a flex structure, with a rotated axis flex-direction:column; and the element in the middle (where the text is) is stretched flex-grow:1; to fill all the free space, this is how the result is achieved - the text began with one line...

More examples

Browser support - 98.3%

Of course, there is no full support, but all modern browsers support flexbox designs. Some still require prefixes. For a real picture, let's look at caniuse.com and see that 96.3% of browsers used today will work without prefixes, with 98.3% using prefixes. This is an excellent indicator to confidently use flexbox.

To know which prefixes are relevant today (June 2019), I will give an example of all flex rules with with the necessary prefixes:

/* Container */ .flex ( display:-webkit-box; display:-ms-flexbox; display:flex; display:-webkit-inline-box; display:-ms-inline-flexbox; display:inline-flex; -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; -ms-flex-wrap:wrap; flex-wrap:wrap; -ms -flex-flow:column wrap; flex-flow:column wrap; -webkit-box-pack:justify; -ms-flex-pack:justify; justify-content:space-between; -ms-flex-line-pack: distribute; align-content:space-around; ) /* Elements */ .flex-item ( -webkit-box-flex:1; -ms-flex-positive:1; flex-grow:1; -ms-flex- negative:2; flex-shrink:2; -ms-flex-preferred-size:100px; flex-basis:100px; -ms-flex:1 2 100px; flex:1 2 100px; -ms-flex-item-align :center; align-self:center; -webkit-box-ordinal-group:3; -ms-flex-order:2; order:2; )

It is better if properties with prefixes go before the original property.
This list does not contain any prefixes that are unnecessary today (according to caniuse), but in general there are more prefixes.

Chrome Safari Firefox Opera I.E. Android iOS
20- (old) 3.1+ (old) 2-21 (old) 10 (tweener) 2.1+ (old) 3.2+ (old)
21+ (new) 6.1+ (new) 22+ (new) 12.1+ (new) 11+ (new) 4.4+ (new) 7.1+ (new)
  • (new) - new syntax: display: flex; .
  • (tweener) - old unofficial syntax from 2011: display: flexbox; .
  • (old) - old syntax from 2009: display: box;

Video

Well, don’t forget about the video, sometimes it’s also interesting and understandable. Here are a couple of popular ones:

Useful links on Flex

    flexboxfroggy.com - flexbox educational game.

    Flexplorer is a visual flex code builder.

Flexbox can rightfully be called a successful attempt to solve a huge range of problems when building layouts in CSS. But before we move on to its description, let's find out what's wrong with the layout methods we use now?

Any layout designer knows several ways to align something vertically or make a 3-column layout with a rubbery middle column. But let's admit that all these methods are quite strange, look like a hack, are not suitable in all cases, are difficult to understand and do not work if certain magical conditions that have developed historically are not met.

This happened because html and css developed evolutionarily. In the beginning, web pages were like single threaded text documents, a little later, dividing the page into blocks was done with tables, then it became fashionable to typeset with floats, and after the official death of ie6, techniques with inline-block were also added. As a result, we inherited an explosive mixture of all these techniques, used to build layouts for 99.9% of all existing web pages.

Multi-line organization of blocks inside a flex container.

flex-wrap

All the examples that we gave above were built taking into account the single-line (single-column) arrangement of blocks. It must be said that by default a flex container will always arrange the blocks inside itself in one line. However, the specification also supports multiline mode. The flex-wrap CSS property is responsible for multi-line content inside a flex container.

Available values flex-wrap:

  • nowrap (default value): blocks are arranged in one line from left to right (in rtl from right to left)
  • wrap: blocks are arranged in several horizontal rows (if they do not fit in one row). They follow each other from left to right (in rtl from right to left)
  • wrap-reverse: same as wrap, but the blocks are arranged in the reverse order.

flex-flow is a convenient shorthand for flex-direction + flex-wrap

In essence, flex-flow provides the ability to describe the direction of the main and multi-line transverse axis in one property. Default flex-flow: row nowrap .

flex-flow:<‘flex-direction’> || <‘flex-wrap’>

CSS

/* i.e. ... */ .my-flex-block( flex-direcrion:column; flex-wrap: wrap; ) /* this is the same as... */ .my-flex-block( flex-flow: column wrap; )

align-content

There is also an align-content property, which determines how the resulting rows of blocks will be vertically aligned and how they will divide the entire space of the flex container.

Important: align-content only works in multi-line mode (i.e. in the case of flex-wrap:wrap; or flex-wrap:wrap-reverse;)

Available values align-content:

  • flex-start: rows of blocks are pressed to the beginning of the flex container.
  • flex-end: rows of blocks are pressed to the end of the flex container
  • center: rows of blocks are in the center of the flex container
  • space-between: the first row of blocks is located at the beginning of the flex container, the last row of blocks is at the end, all other rows are evenly distributed in the remaining space.
  • space-around: rows of blocks are evenly distributed from the beginning to the end of the flex container, dividing all available space equally.
  • stretch (default value): The rows of blocks are stretched out to take up all the available space.

The CSS properties flex-wrap and align-content should be applied directly to the flex container, not to its children.

Demo of multi-line properties in flex

CSS rules for child elements of a flex container (flex blocks)

flex-basis – the basic size of a single flex block

Sets the initial major axis size for a flex block before transformations based on other flex factors are applied to it. Can be specified in any length units (px, em, %, ...) or auto (default). If set as auto, the block dimensions (width, height) are taken as a basis, which, in turn, can depend on the size of the content, if not specified explicitly.

flex-grow – “greed” of a single flex block

Determines how much larger an individual flex block can be than adjacent elements, if necessary. flex-grow accepts a dimensionless value (default 0)

Example 1:

  • If all flex boxes inside a flex container have flex-grow:1 then they will be the same size
  • If one of them has flex-grow:2 then it will be 2 times larger than all the others

Example 2:

  • If all flex boxes inside a flex container have flex-grow:3 then they will be the same size
  • If one of them has flex-grow:12 then it will be 4 times larger than all the others

That is, the absolute value of flex-grow does not determine the exact width. It determines its degree of “greediness” in relation to other flex blocks of the same level.

flex-shrink – the “compressibility” factor of a single flex block

Determines how much the flex block will shrink relative to adjacent elements inside the flex container if there is not enough free space. Defaults to 1.

flex – shorthand for the flex-grow, flex-shrink and flex-basis properties

flex: none | [<"flex-grow"> <"flex-shrink">? || <"flex-basis"> ]

CSS

/* i.e. ... */ .my-flex-block( flex-grow:12; flex-shrink:3; flex basis: 30em; ) /* this is the same as... */ .my-flex-block( flex: 12 3 30em; )

Demo for flex-grow, flex-shrink and flex-basis

align-self – alignment of a single flex block along the transverse axis.

Makes it possible to override the flex container's align-items property for an individual flex block.

Available align-self values ​​(same 5 options as align-items)

  • flex-start: the flex block is pressed to the beginning of the transverse axis
  • flex-end: the flex block is pressed against the end of the cross axis
  • center: flex block is located in the center of the cross axis
  • baseline: flex block is aligned to baseline
  • stretch (default value): The flex block is stretched to take up all available space along the cross axis, taking into account min-width / max-width if set.

order – the order of a single flex block inside a flex container.

By default, all blocks will follow each other in the order specified in the html. However, this order can be changed using the order property. It is specified as an integer and defaults to 0.

The order value does not specify the absolute position of the element in the sequence. It determines the weight of the element's position.

HTML

item1
item2
item3
item4
item5

In this case, the blocks will follow one after another along the main axis in the following order: item5, item1, item3, item4, item2

Demo for align-self and order

margin: auto vertically. Dreams Come True!

You can love Flexbox at least because the familiar horizontal alignment via margin:auto works here for verticals too!

My-flex-container ( display: flex; height: 300px; /* Or whatever */ ) .my-flex-block ( width: 100px; /* Or whatever */ height: 100px; /* Or whatever * / margin: auto; /* Magic! The block is centered vertically and horizontally! */ )

Things to Remember

  1. You should not use flexbox where it is not necessary.
  2. Defining regions and changing the order of content in many cases is still useful to make dependent on the page structure. Think it through.
  3. Understand flexbox and know the basics. This makes it much easier to achieve the expected result.
  4. Don't forget about margins. They are taken into account when setting axis alignment. It is also important to remember that margins in flexbox do not “collapse” as they do in a normal flow.
  5. The float value of flex blocks is not taken into account and has no meaning. This can probably somehow be used for graceful degradation when switching to flexbox.
  6. Flexbox is very well suited for the layout of web components and individual parts of web pages, but has not shown its best side when laying out basic layouts (position of article, header, footer, navbar, etc.). This is still a controversial point, but this article shows the shortcomings quite convincingly xanthir.com/blog/b4580

Finally

I think that flexbox, of course, will not supplant all other layout methods, but, of course, in the near future it will occupy a worthy niche in solving a huge number of tasks. And of course, you need to try working with him now. One of the following articles will be devoted to specific examples of working with flex layout. Subscribe to news;)

CSS flexbox (Flexible Box Layout Module)- flexible container layout module - is a way of arranging elements, based on the idea of ​​an axis.

Flexbox consists of flexible container And flexible items. Flexible elements can be arranged in a row or column, and the remaining free space is distributed between them in various ways.

The flexbox module allows you to solve the following tasks:

  • Arrange elements in one of four directions: left to right, right to left, top to bottom, or bottom to top.
  • Override the display order of elements.
  • Automatically size elements so that they fit into the available space.
  • Solve the problem with horizontal and vertical centering.
  • Move items inside a container without overflowing it.
  • Create columns of the same height.
  • Create pressed to the bottom of the page.

Flexbox solves specific problems - creating one-dimensional layouts, for example, a navigation bar, since flex elements can only be placed along one of the axes.

You can read a list of current module problems and cross-browser solutions for them in the article by Philip Walton.

What is flexbox

Browser support

IE: 11.0, 10.0 -ms-
Firefox: 28.0, 18.0 -moz-
Chrome: 29.0, 21.0 -webkit-
Safari: 6.1 -webkit-
Opera: 12.1 -webkit-
iOS Safari: 7.0 -webkit-
Opera Mini: 8
Android Browser: 4.4, 4.1 -webkit-
Chrome for Android: 44

1. Basic concepts

Rice. 1. Flexbox model

A specific set of terms is used to describe a Flexbox module. The flex-flow value and recording mode determine the correspondence of these terms to the physical directions: top / right / bottom / left, axes: vertical / horizontal, and dimensions: width / height.

Main axis— the axis along which flex elements are laid out. It extends into the main dimension.

Main start and main end— lines that define the start and end sides of the flex container, relative to which flex elements are laid out (starting from main start towards main end).

Main size) - the width or height of the flex container or flex items, depending on which of them is in the main dimension, determines the main size of the flex container or flex item.

Cross axis- axis perpendicular to the main axis. It extends in the transverse dimension.

Cross start and cross end— lines that define the starting and ending sides of the transverse axis, relative to which flex elements are laid out.

Cross size— the width or height of a flex container or flex items, whichever is in the cross dimension, is their cross dimension.


Rice. 2. Row and column mode

2. Flex container

A Flex container sets a new flexible formatting context for its content. A flex container is not a block container, so CSS properties such as float , clear , vertical-align do not work for child elements. Also, the flex container is not affected by the column-* properties that create columns in the text and the pseudo-elements::first-line and::first-letter .

The flexbox layout model is associated with a certain value CSS display properties of a parent HTML element containing child blocks. To control elements using this model, you need to set the display property as follows:

Flex-container ( /*generates a block-level flex container*/ display: -webkit-flex; display: flex; ) .flex-container ( /*generates a line-level flex container*/ display: -webkit-inline-flex; display: inline-flex; )

After setting these property values, each child element automatically becomes a flex element, lining up in one row (along the main axis). In this case, block and inline child elements behave the same, i.e. The width of the blocks is equal to the width of their content, taking into account the internal margins and borders of the element.


Rice. 3. Aligning elements in the flexbox model

If the parent block contains text or images without wrappers, they become anonymous flex items. The text is aligned to the top edge of the container block, and the height of the image becomes equal to the height of the block, i.e. it is deformed.

3. Flex elements

Flex items are blocks that represent the contents of a flex container in a flow. The Flex container establishes a new formatting context for its content, which causes the following features:

  • For flex items, their display property value is locked. Display value: inline-block; and display: table-cell; evaluated in display: block; .
  • The white space between items disappears: it does not become its own flex item, even if the interitem text is wrapped in an anonymous flex item. An anonymous flex item's content cannot be styled, but will inherit styles (such as font options) from the flex container.
  • An absolutely positioned flex element does not participate in the flex layout layout.
  • The margins of adjacent flex elements do not collapse.
  • Percentage margin and padding values ​​are calculated from the internal size of the block containing them.
  • margin: auto; expand, absorbing additional space in the corresponding dimension. They can be used to align or push adjacent flex items.
  • The default automatic minimum size of flex items is the minimum size of its content, i.e. min-width: auto; . For scrollable containers, the automatic minimum size is usually zero.

4. Flex Item Display Order and Orientation

The contents of a flex container can be laid out in any direction and in any order (rearranging flex items within the container only affects visual rendering).

4.1. Main axis direction: flex-direction

The property refers to the flex container. Controls the direction of the main axis along which flex items are stacked, in accordance with the current writing mode. Not inherited.

flex-direction
Values:
row The default value is left to right (in rtl, right to left). Flex elements are laid out in a row. The start (main-start) and end (main-end) of the main axis direction correspond to the start (inline-start) and end (inline-end) of the line axis (inline-axis).
row-reverse The direction is from right to left (in rtl from left to right). Flex elements are laid out in a line relative to the right edge of the container (in rtl - the left).
column Direction from top to bottom. Flex elements are laid out in a column.
column-reverse A column with elements in reverse order, from bottom to top.
initial
inherit

Rice. 4. Flex-direction property for left-to-right languages

Syntax

Flex-container ( display: -webkit-flex; -webkit-flex-direction: row-reverse; display: flex; flex-direction: row-reverse; )

4.2. Managing multi-line flex container: flex-wrap

The property determines whether the flex container will be single-line or multi-line, and also sets the direction of the cross axis, which determines the direction in which new lines of the flex container will be laid.

By default, flex items are stacked on one line, along the main axis. If they overflow, they will extend beyond the bounding box of the flex container. The property is not inherited.


Rice. 5. Multi-line control using the flex-wrap property for LTR languages

Syntax

Flex-container ( display: -webkit-flex; -webkit-flex-wrap: wrap; display: flex; flex-wrap: wrap; )

4.3. A short summary of direction and multi-line: flex-flow

The property allows you to define the directions of the main and transverse axes, as well as the ability to move flex elements, if necessary, onto several lines. This is a shorthand for the flex-direction and flex-wrap properties. Default value flex-flow: row nowrap; . the property is not inherited.

Syntax

Flex-container ( display: -webkit-flex; -webkit-flex-flow: row wrap; display: flex; flex-flow: row wrap; )

4.4. Display order of flex items: order

The property defines the order in which flex items are displayed and arranged within a flex container. Applies to flex items. The property is not inherited.

Initially all flex items have order: 0; . When you specify a value of -1 for an element, it is moved to the beginning of the timeline, and a value of 1 is moved to the end. If multiple flex items have the same order value, they will be rendered according to the original order.

Syntax

Flex-container ( display: -webkit-flex; display: flex; ) .flex-item ( -webkit-order: 1; order: 1; )
Rice. 6. Display order of flex items

5. Flexibility of flex elements

The defining aspect of a flex layout is the ability to "flex" flex items, changing their width/height (depending on what size is on the main axis) to fill the available space in the main dimension. This is done using the flex property. A flex container distributes free space between its child elements(proportional to their flex-grow ratio) to fill the container, or shrinks them (proportional to their flex-shrink ratio) to prevent overflow.

A flex element will be completely "inflexible" if its flex-grow and flex-shrink values ​​are zero, and "flexible" in otherwise.

5.1. Setting flexible dimensions with one property: flex

The property is shorthand for the flex-grow, flex-shrink, and flex-basis properties. Default value: flex: 0 1 auto; . You can specify one or all three property values. The property is not inherited.

Syntax

Flex-container ( display: -webkit-flex; display: flex; ) .flex-item ( -webkit-flex: 3 1 100px; -ms-flex: 3 1 100px; flex: 3 1 100px; )

5.2. Growth factor: flex-grow

The property determines the growth rate of one flex element relative to other flex elements in the flex container when distributing positive free space. If the sum of the flex-grow values ​​of flex items in a row is less than 1, they take up less than 100% of the free space. The property is not inherited.


Rice. 7. Manage Navigation Bar Space with Flex-Grow

Syntax

Flex-container ( display: -webkit-flex; display: flex; ) .flex-item ( -webkit-flex-grow: 3; flex-grow: 3; )

5.3. Compression ratio: flex-shrink

The property specifies the compression ratio of a flex item relative to other flex items when distributing negative free space. Multiplied by the flex-basis size. Negative space is allocated in proportion to how much the item can shrink, so, for example, a small flex item won't shrink to zero until a larger flex item is noticeably shrunk. The property is not inherited.


Rice. 8. Narrowing flex items in a row

Syntax

Flex-container ( display: -webkit-flex; display: flex; ) .flex-item ( -webkit-flex-shrink: 3; flex-shrink: 3; )

5.4. Basic size: flex-basis

The property sets the initial base size of a flex item before allocating free space according to flex factors. For all values ​​except auto and content , the base flex size is defined the same as width in horizontal writing modes. Percentage values ​​are defined relative to the size of the flex container, and if no size is specified, the value used for flex-basis is the dimensions of its contents. Not inherited.

Syntax

Flex-container ( display: -webkit-flex; display: flex; ) .flex-item ( -webkit-flex-basis: 100px; flex-basis: 100px; )

6. Alignment

6.1. Main axis alignment: justify-content

The property aligns flex items along the main axis of the flex container, distributing the free space unoccupied by flex items. When an item is converted to a flex container, flex items are grouped together by default (unless they have margins set). Gaps are added after calculating the margin and flex-grow values. If any elements have a non-zero flex-grow or margin: auto; , the property will have no effect. The property is not inherited.

Values:
flex-start Default value. Flex elements are laid out in a direction starting from the starting line of the flex container.
flex-end Flex items are laid out in the direction from the end line of the flex container.
center Flex items are aligned to the center of the flex container.
space-between Flex elements are distributed evenly along the line. The first flex item is placed flush with the edge of the starting line, the last flex item is placed flush with the edge of the ending line, and the remaining flex items on the line are spaced so that the distance between any two neighboring elements was the same. If the remaining free space is negative or there is only one flex item per line, this value is identical to the flex-start parameter.
space-around The flex items on the line are distributed so that the distance between any two adjacent flex items is the same, and the distance between the first/last flex items and the edges of the flex container is half the distance between the flex items.
initial Sets the property value to the default value.
inherit Inherits the property value from the parent element.

Rice. 9. Aligning elements and distributing free space using the justify-content property

Syntax

Flex-container ( display: -webkit-flex; -webkit-justify-content: flex-start; display: flex; justify-content: flex-start; )

6.2. Cross axis alignment: align-items and align-self

Flex elements can be aligned along the transverse axis of the current line of the flex container. align-items sets the alignment for all flex container items, including anonymous flex items. align-self allows you to override this alignment for individual flex items. If any of the flex element's cross margins are set to auto , align-self has no effect.

6.2.1. Align-items

The property aligns flex elements, including anonymous flex elements, along the transverse axis. Not inherited.

Values:
flex-start
flex-end
center
baseline The baselines of all flex items involved in alignment are the same.
stretch
initial Sets the property value to the default value.
inherit Inherits the property value from the parent element.
Rice. 10. Aligning elements in a container vertically

Syntax

Flex-container ( display: -webkit-flex; -webkit-align-items: flex-start; display: flex; align-items: flex-start; )

6.2.2. Align-self

The property is responsible for aligning a single flex element to the height of the flex container. Overrides the alignment specified by align-items . Not inherited.

Values:
auto Default value. A flex element uses the alignment specified in the align-items property of the flex container.
flex-start The top edge of the flex element is placed close to the flex line (or at a distance, taking into account the specified margin and frame border element) passing through the beginning of the transverse axis.
flex-end The bottom edge of the flex element is placed adjacent to the flex line (or at a distance, taking into account the specified margins and borders of the element) passing through the end of the cross axis.
center The margin of a flex element is centered along the cross axis within the flex line.
baseline The flex element is aligned to the baseline.
stretch If a flex item's cross-size is auto and none of the cross-margin values ​​are auto , the item is stretched. Default value.
initial Sets the property value to the default value.
inherit Inherits the property value from the parent element.

Rice. 11. Aligning individual flex items

Syntax

Flex-container ( display: -webkit-flex; display: flex; ) .flex-item ( -webkit-align-self: center; align-self: center; )

6.3. Aligning the lines of a flex container: align-content

The property aligns rows in a flex container when there is extra space on the cross axis, similar to justifying individual items on the main axis using the justify-content property. The property does not affect a single-line flex container. Not inherited.

Values:
flex-start Rows are stacked towards the beginning of the flex container. The edge of the first line is placed close to the edge of the flex container, each subsequent line is placed close to the previous line.
flex-end Rows are stacked towards the end of the flex container. The edge of the last line is placed close to the edge of the flex container, each previous line is placed close to the next line.
center Rows are stacked towards the center of the flex container. The rows are close together and aligned to the center of the flex container, with equal distance between the starting edge of the flex container's content and the first row, and between the ending edge of the flex container's content and the last row.
space-between The rows are evenly distributed in the flex container. If the remaining free space is negative or there is only one flex line in the flex container, this value is identical to flex-start . Otherwise, the edge of the first line is placed close to the start edge of the flex container's content, and the edge of the last line is placed close to the end edge of the flex container's content. The remaining lines are distributed so that the distance between any two adjacent lines is the same.
space-around The lines are evenly spaced in the flex container with half space on both ends. If the remaining free space is negative, this value is identical to center center . Otherwise, the lines are distributed so that the distance between any two adjacent lines is the same, and the distance between the first/last lines and the edges of the flex container's contents is half the distance between the lines.
stretch Default value. Rows of flex items stretch evenly to fill all available space. If the remaining free space is negative, this value is identical to flex-start . Otherwise, the free space will be divided equally between all rows, increasing their lateral size.
initial Sets the property value to the default value.
inherit Inherits the property value from the parent element.
Rice. 12. Multi-line alignment of flex elements

Syntax

Flex-container ( display: -webkit-flex; -webkit-flex-flow: row wrap; -webkit-align-content: flex-end; display: flex; flex-flow: row wrap; align-content: flex-end ; height: 100px; )

Internet