Flexbox examples. Layout using CSS Flexbox. flex – shorthand for the flex-grow, flex-shrink and flex-basis properties

💖 Do you like it? Share the link with your friends

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 markup model is associated with a specific value of the CSS display property of the parent HTML element containing child blocks within it. 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 height 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 among its children (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" 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 calculation margin values and flex-grow . 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 start line, the last flex item is placed flush with the edge of the end line, and the remaining flex items on the line are spaced so that the distance between any two adjacent items is 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 adjacent to the flex line (or at a distance, taking into account the specified margins and borders of the element) passing through the beginning of the cross 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 were 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; )

I would like to talk about FlexBox. Flexbox-layout module (flexible box - “flexible block”, on this moment W3C Candidate Recommendation aims to offer more effective method layout, alignment, and distribution of free space between elements in a container, even when their size is unknown and/or dynamic (hence the word "flexible").

The main idea of ​​flex layout is to give the container the ability to change the width/height (and order) of its elements to better fill the space (in most cases, to support all types of displays and screen sizes).A flex container stretches elements to fill space or compresses them to prevent them from overflowing.

Most importantly, flexbox layout does not depend on direction, unlike conventional layouts (blocks arranged vertically and inline elements arranged horizontally).While the regular layout is great for web pages, it lacks the flexibility to support large or complex applications (especially when it comes to changing screen orientation, resizing, stretching, shrinking, etc.).

Because flexbox is a whole module, not just a single property, it combines many properties.Some of them must be applied to the container (the parent element, called the flex container), while other properties are applied to the child elements, or flex elements.

While a regular layout is based on the flow directions of block and inline elements, a flex layout is based on “flex flow directions”.

Flexbox

Basically, elements will be distributed either along the main axis (from main-start to main-end) or along the transverse axis (from cross-start to cross-end).

main-axis — the main axis along which flex elements are located.Please note that it must be horizontal, it all depends on the quality of the justify-content.
main-start | main-end - flex elements are placed in the container from the main-start position to the main-end position.
main size — width or height of the flex element depending on the selected main size.The base quantity can be either the width or height of the element.
cross axis - transverse axis perpendicular to the main one.Its direction depends on the direction of the main axis.
cross-start | cross-end - flex lines are filled with elements and placed in the container from the cross-start position and the cross-end position.
cross size — the width or height of the flex element, depending on the selected dimension, is equal to this value.This property is the same as the width or height of the element depending on the selected dimension.


Properties
display: flex | inline-flex;

Defines a flex container (inline or block depending on the selected value), connects a flex context for all its immediate descendants.

display: other values ​​| flex | inline-flex;

Keep in mind:

CSS columns don't work with flex containerfloat, clear and vertical-align don't work with flex items

flex-direction

Applies before the flex container's parent element.

Sets the main-axis, thereby defining the direction for flex items placed in the container.

flex-direction: row | row-reverse | column | column-reverse

row (default): left to right for ltr, right to left for rtl;
row-reverse: right to left for ltr, left to right for rtl;
column: similar to row, from top to bottom;
column-reverse: similar to row-reverse, from bottom to top.

flex-wrap

Applies before the flex container's parent element.

Determines whether the container is single-line or multi-line, as well as the direction of the cross axis, determines the direction in which new lines will be located.

flex-wrap: nowrap | wrap | wrap-reverse

nowrap (default): single line / left to right for ltr, right to left for rtl;
wrap: multiline / left to right for ltr, right to left for rtl;
wrap-reverse: multiline / right to left for ltr, left to right for rtl.

flex-flow

Applies before the flex container's parent element.

This is shorthand for the flex-direction and flex-wrap properties, which together define the major and cross axes.The default value is row nowrap.

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

justify-content

Applies before the flex container's parent element.

Defines the alignment relative to the major axis.Helps distribute free space in the case when line elements do not “stretch”, or stretch, but have already reached their maximum size.Also allows some control over the alignment of elements when they go beyond the line.

justify-content: flex-start | flex-end | center | space-between | space-around

flex-start (default): items move to the beginning of the line;
flex-end: elements move to the end of the line;
center: elements are aligned to the middle of the line;
space-between: elements are distributed evenly (first element at the beginning of the line, last at the end)
space-around: elements are distributed evenly with equal distance between each other and outside the line.

justify-content
align-items

Applies before the flex container's parent element.

Defines the default behavior for how flex items are positioned relative to the cross axis on the current line.Think of it as a version of justify-content for the cross axis (perpendicular to the main one).

align-items: flex-start | flex-end | center | baseline | stretch

flex-start: cross-start border for elements located at cross-start position;
flex-end: cross-end border for elements located at cross-end position;
center: elements are aligned to the center of the cross axis;
baseline: elements are aligned to their baseline;
stretch (default): elements are stretched to fill the container (taking into account min-width / max-width).


align-items
align-content

Applies before the flex container's parent element. Aligns the rows of a flex container when there is free space on the cross axis, similar to how justify-content does on the main axis. Note: This property does not work with single-line flexboxes.

align-content: flex-start | flex-end | center | space-between | space-around | stretch

flex-start: lines are aligned relative to the start of the container;
flex-end: lines are aligned relative to the end of the container;
center: lines are aligned to the center of the container;
space-between: lines are distributed evenly (first line at the beginning of the line, last at the end)
space-around: lines are distributed evenly with equal distance between each other;
stretch (default): Lines are stretched to fill the available space.

align-content
order

By default, flex items are arranged in their original order.However, the order property can control the order in which they appear in the container.

order 1

flex-grow

Applies to the child element/flex element. Defines the ability for a flex element to “grow” if necessary.Takes on a dimensionless value and serves as a proportion.It determines how much free space an element can take up inside a container. If all elements have the flex-grow property set to 1, then each child will receive the same size inside the container.If you set one of the children to 2, it will take up twice as much space as the others.

flex-grow (default 0)

flex-shrink

Applies to the child element/flex element.

Defines the ability for a flex item to shrink when needed.

flex-shrink (default 1)

Negative numbers are not accepted.
flex-basis

Applies to the child element/flex element. Defines the default size for an element before allocating space in the container.

flex-basis | auto (default auto)

flex

Applies to the child element/flex element. This is shorthand for flex-grow, flex-shrink and flex-basis.The second and third parameters (flex-shrink, flex-basis) are optional.The default value is 0 1 auto.

flex: none | [< ‘Flex-grow «> <» flex-shrink’>? || < ‘Flex-basis’>]

align-self

Applies to the child element/flex element. Allows you to override the default or align-items alignment for individual flex items. Refer to the description of the align-items property for a better understanding of the available values.

align-self: auto | flex-start | flex-end | center | baseline | stretch

Examples
Let's start with a very, very simple example that occurs almost every day: aligning exactly to the center.Nothing could be easier if you use flexbox.

Parent ( display: flex; height: 300px; ) .child ( width: 100px; / * Whatever * / height: 100px; / * Whatever * / margin: auto; / * Magic! * / )

This example relies on the fact that the margin under the flex container, set to auto, eats up extra space, so the task of indenting this way will align the element exactly centered on both axes. Now let's use some properties.Imagine a set of 6 elements of a fixed size (for beauty), but with the ability to resize the container.We want to distribute them evenly horizontally so that when we resize the browser window everything looks good (no @media queries!).

Flex-container (
/ * First, let's create a flex context * /
display: flex;

/* Now let's determine the direction of flow and whether we want the elements
moved to a new line
*Remember that this is the same as:
* Flex-direction: row;
* Flex-wrap: wrap;
* /
flex-flow: row wrap;

/ * Now let’s determine how the space will be distributed * /
}

Ready. Everything else is a matter of registration. Let's try something else.Imagine we want a right-aligned navigation at the very top of our site, but we want it to be center-aligned on medium-sized screens and become a single column on small ones.Everything is quite simple.

/*Large screens*/
.navigation(
display: flex;
flex-flow: row wrap;
/* Shifts elements to the end of the line along the main axis * /
justify-content: flex-end;
}

media all and (max-width: 800px) (
.navigation(
/* For medium screens, we center the navigation,
evenly distributing free space between elements * /
justify-content: space-around;
}
}

/*Small Screens*/
media all and (max-width: 500px) (
.navigation(
/ * On small screens, instead of a row, we arrange elements in a column * /
flex-direction: column;
}
}

Let's play with the flexibility of flex items!How about a mobile-friendly three-column layout with a full-width header and footer?And in a different order of arrangement.

Wrapper (
display: flex;
flex-flow: row wrap;
}

/ * Set all Elements to 100% width * /
.header, .main, .nav, .aside, .footer (
flex 1100%;
}

/* In this case we rely on the original order to guide us
* Mobile devices:
* 1 header
* 2 nav
* 3 main
* 4 aside
* 5 footer
* /

/*Medium screens*/
media all and (min-width: 600px) (
/ * Both sidebars are located on the same line * /
.aside (flex: 1 auto; )
}

/*Large screens*/

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 a container: direction, order, width, height, alignment along and across, distribution of free space, stretching 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.

Another important feature of Flexbox is the presence of rows in the transverse direction. To understand what we're talking about, let's imagine that there is a main horizontal axis, there are a lot of elements and they don’t “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 the 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 with the simplest example - vertical and horizontal alignment at the same time 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 the 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.

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 CSS property direction with the value ltr ) is located from left to right, and the cross one is from top to bottom (this is the default value), for the value rtl it is displayed mirrored accordingly.

Using the example of a form from a real test task, I'll show you how to typeset BEM using flexbox. You may ask: “Why is it necessary to typeset according to BEM + Flexbox?" This requirement comes from the employer. Quote from the statement of work: "Try to typesetting without frameworks (preferably on flexbox), simple and clear: avoid cumbersome structures and unnecessary code, use the methodology BEM."

Fragment of a section layout with a form

My layout rules

  1. Divide the layout into logical sections
  2. Start each section with a tag section
  3. Separate sections and CSS ruled from each other, empty line
  4. Assign a class to each tag
  5. The name of the class for a block or element, answers the question - What is this?
  6. The modifier name answers the question - Which?

HTML markup

First, I make the markup, determine the nesting of blocks and come up with names for classes. In the code below, we have two inline tags - h2 And input. Inline tags are a headache and a cause of stress for beginning layout designers. Why? They behave very badly - they try to take up the entire available width, and do not allow you to set the background color and dimensions of the entire block.



personal information











What does a bad layout designer do in this case? It wraps inline elements in block tags div and sets all the necessary properties to the wrapper tag. Child inline elements inherit these properties. Is it worth making a fuss of extra code? What would a competent layout designer do? It will redefine the inline element to block or inline-block, in CSS rules

Display: block; // for the input tag
display: inline-block; // for h2 tag

Nesting logic and block names

We see a section with personal information, so we call the section class - info. A section consists of three child elements:

Icon // class name info__icon
title // info__title
form // info__form

The point is in the names of the classes BEM, consists of belonging child element to the parent. The element cannot be named icon. This is not just any icon, but an icon from the section info.

Daughter and parent rolled into one

Block info__form, we have a special one - it is nested in the section info, but at the same time, contains form fields. The name of this phenomenon is multi-level nesting. The block with the form has a purely wrapper function for inputs, so that you can easily set external margins. After all, lowercase inputs behave like children (which they are), they don’t obey at all. Moreover, the second input is shorter than all the others and differs only in width.

We set one class for all inputs with the same properties, except width - info__input. For regular inputs, add a modifier info__input_long, and the short input is given a modifier info__input_short. Let me remind you that the modifier BEM, should answer the question - Which?









CSS rules for modifiers

.info__input_long(
width: 520px;
}

Info__input_short(
width: 320px;
}

CSS code

IN HTML markup creates a rough structure of the site, in CSS, we are already placing the elements according to the layout. Today, we will not touch on the appearance, but will focus on the positioning of elements. In our section, there are two flex containers. It must be said that the use of flexes, when all elements are located one at a time on a line, is very doubtful. The only benefit received is the property justify-content, center aligned, flex elements. I can say in my defense that the idea of ​​flexes is pointless in the context of this section only. A real layout for layout usually has more variety.

Info (
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin-top: 77px;
height: 100%;
}

Info__form(
display: flex;
justify-content: center;
flex-direction: column;
height: 100%;
margin-top: 50px;



tell friends