The Flexible box layout model (flexible box layouts) is a new layout method proposed in the CSS3 specification. The purpose of this layout model is to provide a more efficient way to lay out, align, and allocate space for items in a container. This layout can also work when the item size is unknown or dynamic. This layout has been supported by mainstream browsers and can be used in WEB application development. This article describes the layout model in detail and how to apply the layout model in a specific development to simplify common page layout scenarios.
Layout is a very important part of the style design of WEB applications. Layouts are used to determine the size and position of different components and elements on a page. With the popularity of responsive user interfaces, Web applications generally require different device sizes and browser resolutions. The most important link in responsive user interface design is layout. You need to adjust the layout according to the size of the window to change the size and position of the component to achieve the best display results. This also complicates the layout logic. This article describes a new layout model introduced in the CSS3 specification: the Elastic box model (Flex box). Flexible box models can be used to meet many common complex layout requirements in a simple way. The advantage is that the developer simply declares the behavior that the layout should have, without having to give a concrete implementation. The browser is responsible for completing the actual layout. This layout model is supported in mainstream browsers.
Brief introduction
The purpose of introducing the flexible box layout model is to provide a more efficient way to arrange, align, and allocate white space for items in a container. Even if the size of the item in the container is unknown or dynamically changing, the flexible box layout model can work properly. In this layout model, the container adjusts the size and order of the entries contained in the layout to best populate all available space. When the size of a container changes due to screen size or window size, the items contained therein are also dynamically adjusted. For example, when the size of the container becomes larger, the items contained therein are stretched to fill the extra empty space, and when the container size becomes small, the entry is reduced to prevent the container from exceeding its range. The Flex box layout is independent of orientation. In the traditional layout, the block layout arranges the blocks in a vertical direction from top to bottom, while the inline layout is arranged horizontally. The flexible box layout does not have this inherent direction limitation and can be freely operated by the developer.
Before delving into the details of the Flex box layout model, let's look at a few related important concepts, as shown in 1.
Figure 1. Flexible box layout model-related concepts
A flexible box layout container (Flex container) refers to a DOM element with a flexible box layout, whereas an entry for a flexible box layout (Flex Item) refers to a child DOM element contained in a container. The outermost border of the diagram represents the container, while the Borders numbered 1 and 2 represent the entries in the container.
As you can see, there are two axes perpendicular to each other in the Flex box layout: One is called the spindle (main axis) and the other is called the cross axis. The spindle is not fixed to the horizontal X-axis, and the cross-axis is not fixed to the vertical Y-axis. When used, the direction of the axis (horizontal or vertical) is defined first by the CSS property declaration, and the orientation of the intersection is determined accordingly. The items in the container can be arranged in single or multiple rows. The spindle determines the direction of the entry on each row in the container, while the cross axis determines the direction in which the row itself is arranged. The appropriate spindle orientation can be determined according to the different page design requirements. Some of the items in the container require a horizontal arrangement from left to right, the spindle should be horizontal, while the other items in the container require a vertical arrangement from top to bottom, the spindle should be vertically oriented.
After you have determined the direction of the spindle and the cross axis, you also need to determine their respective arrangement direction. For axes in the horizontal direction, they can be arranged from left to right or right to left, and for axes in the vertical direction, from top to bottom or from bottom to top. For the spindle, the starting and ending positions of the arrangement entries are called the spindle start (main start) and the spindle end (main end), and for the cross axis, the starting and ending positions of the arrangement lines are called the intersection start (Cross start) and the intersection end (cross end), respectively. When the container is laid out, the entries in each row will start at the start of the spindle, arranged at the end of the spindle, and when there are multiple rows in the container, each line starts at the intersection of the axes, and then arranges to the end of the intersection.
The entry in the Flex box layout has two dimensions: spindle size and cross axis size, respectively, corresponding to the size of its DOM elements on the spindle and cross axes. If the spindle is horizontal, the spindle size and the cross-axis dimensions correspond to the width and height of the DOM element, respectively, and if the spindle is vertically oriented, the two dimensions are reversed. corresponding to the spindle and cross axis dimensions is the spindle size attribute and the cross axis dimension attribute, which refers to the property width or height in the CSS. For example, when the spindle is horizontally oriented, the spindle dimension property is width, and the width value is the size of the spindle size.
CSS style declarations in a flexible box layout model apply to containers or items, respectively. The related CSS properties are described in detail in the following sections. First, we show you how to use the flexible box layout model for basic page layout. In all the code examples in this article, the container's CSS class name is Flex-container, and the CSS class name for the entry is Flex-item. All the examples can be previewed on the Codepen.
Basic layout
First introduce the flexible box layout model from the most basic layout. The layout effect to be implemented is a simple picture thumbnail preview page. The basic HTML of the page is shown in Listing 1.
Listing 1. HTML code for simple picture thumbnail preview page
<ul class= "Flex-container" > <li class= "Flex-item" > </li> <li class= "Flex-item" ></li> < Li class= "flex-item" ></li> <li class= "Flex-item" ></li> <li class= "Flex-item" ></li> <li class=" Flex-item "></li></ul>
The basic HTML of the page is very simple. There are 6 <li> elements under a <ul> element. Each <li> element contains a thumbnail image of size 300x300. The <ul> element acts as a container for a flexible box layout, while the <li> element is an entry in the container. The CSS that implements the basic layout is shown in Listing 2.
Listing 2. Simple picture thumbnail preview page CSS code
. flex-container { list-style:none; Display:flex; Flex-direction:row; Flex-wrap:wrap;}. Flex-item { padding:5px;}
In Listing 2, for the container of the Flex box layout, use the "Display:flex" declaration to use the Flex box layout. The CSS property declares "Flex-direction" to determine the direction of the spindle, thus determining the basic arrangement of the items. The optional value of the "Flex-direction" property and its meaning are shown in table 1.
Table 1. Optional values for the "flex-direction" property and what it means
Property Value |
meaning |
Row (default value) |
The spindle is in the horizontal direction. The sorting order is the same as the document order of the page. If the document order is LTR, the order is left-to-right, or if the document order is RTL, the order is right-to-left. |
Row-reverse |
The spindle is in the horizontal direction. The sorting order is reversed from the document order of the page. |
Column |
The spindle is in the vertical direction. The sort order is top to bottom. |
Column-reverse |
The spindle is in the vertical direction. The sorting order is from bottom to top. |
By default, entries in the Elastic box container are as full as possible to fill a row of the container in the spindle direction. When the size of the main spindle of a container is smaller than the total spindle size of all its entries, there is a phenomenon of overlapping or exceeding the container range between the items. The CSS property "Flex-wrap" is used to declare the behavior that should be taken when the size of an entry in a container exceeds the spindle size. The optional value of the "Flex-wrap" property and its meaning are shown in table 2.
Table 2. Optional values for the "Flex-wrap" property and what it means
Property Value |
meaning |
NoWrap (default value) |
Items in a container occupy only one row of the container in the direction of the spindle, and there may be occurrences of overlapping or exceeding the scope of the container. |
Wrap |
When an entry in a container exceeds a row of the container in the spindle direction, the entry is arranged to the next line. The next line is positioned in the same direction as the intersection axis. |
Wrap-reverse |
Similar to wrap's meaning, the difference is that the position of the next line is the opposite of the intersection axis. |
You can use the "Flex-flow" attribute to combine "flex-direction" and "Flex-wrap", as shown in Listing 3.
Listing 3. Example of using the "Flex-flow" property
Flex-flow:row Wrap;
Items in a container
In addition to the containers in the Flex box layout model, entries in the container can also change their layout behavior through CSS properties. The following describes the CSS property declarations that can be used by entries in the container.
Order of entries
By default, the order of entries in a container depends on the order in which they appear in the HTML markup code. You can change the order in which entries appear in the container through the "order" property. Add the CSS declaration in Code Listing 4 to the HTML markup in the code, and the effect after the run is that the last <li> element appears at the top of the other <li> elements.
Listing 4. Example of use of the "order" property
. flex-item:last-child { Order:-1;}
The primary role of the Order property is to take into account the style and accessibility of the page. Devices that support accessibility, such as screen readers, are reading elements in the order of the code in the HTML. This requires some relatively important text to appear in front of the HTML tag. For the general user of the browser, in some cases it is better to display some relatively unimportant pictures in front of them. For example, in a product display page, in the source code to put the product description of the text in front of the product picture. This facilitates the reading of the screen reader, and the "order" attribute is used in the CSS to place the picture in front of the text. This allows the user to see the picture first.
Elasticity of item size
The core of the elastic box layout model is that the size of the item in the container is elastic. The container can dynamically adjust the size of the entry according to its size. When there is empty space in the container, the entry can extend the size to occupy additional white space, and when there is insufficient space in the container, the entry can be scaled down to prevent the container from exceeding the scope. The elasticity of the item size is determined by 3 CSS properties, namely "Flex-basis", "Flex-grow", and "Flex-shrink".
The Flex-basis property declares that the accepted value is the same as the Width property, and is used to determine the initial spindle size of an elastic entry. This is the initial value before the size of the entry is adjusted by the container. If the value of "flex-basis" is auto, the actual value used is the value of the spindle dimension property, which is the value of the width or height property. If the value of the spindle dimension property is also auto, the value used is determined by the size of the entry content.
The value of the "Flex-grow" property is a non-negative number with no units, and the default value is 1. The value of the "Flex-grow" property represents the proportion of space that is allocated between different entries when the container has extra space. For example, there are 3 entries in a container, with the values of the "Flex-grow" property being 1, 2, and 3, respectively, and when there is empty space in the container, the additional white space for the 3 entries takes up 1/6, 1/3, and 1/2 of the total space, as shown in Listing 5.
Listing 5. Example of using the "Flex-grow" property
. Flex-item:nth-child (1) { flex-grow:1;}. Flex-item:nth-child (2) { flex-grow:2;}. Flex-item:nth-child (3) { flex-grow:3;}
The "Flex-shrink" property is similar to "Flex-grow" in use. The value of this property is also non-unit, which means that the size of each entry is scaled down when the container has insufficient space. When size is reduced, the size of the entry is multiplied by the value of "flex-basis", resulting in the actual value of the dimension that should be scaled down. For example, there are 3 entries in the container, with the values of the "Flex-shrink" property being 1, 2, and 3, respectively. Each entry has a spindle size of 200px. When the size of the main spindle of the container is less than 600px, such as 540px, the size of 60px needs to be reduced by 3 entries proportional to the distribution. 3 items are reduced to 10px, 20px, and 30px respectively, and the spindle size becomes 190px, 180px and 170px respectively. The preview page is shown here.
Use the property flex to declare the values of "flex-basis", "Flex-grow", and "Flex-shrink" at the same time, in the format "none | [< ' Flex-grow ' > < ' Flex-shrink ',? | | < ' flex-basis ' >] '. The initial value of the 3 components of the value of this property is "0 1 Auto", respectively. When the value of the property "Flex" is none, it is equivalent to "0 0 auto". When the component "Flex-basis" is omitted, its value is 0%. Code Listing 6 shows an example of the use of the property "Flex".
Listing 6. Example of use of the property "Flex"
. Flex-item:nth-child (1) { flex:1 1 auto;} flex:1; The value of the Flex-grow value of 1,flex-shrink is 0% for the value of 1,flex-basis.
It is important to note that the container allocates extra space in the "Rows" unit. The container first determines whether it is a single-line layout or a multiline layout based on the attribute value of "Flex-wrap", then assigns the entry to the corresponding row, and then allocates the empty space within each row. As shown in Listing 7 for the CSS example, there are 4 entries in the container.
Listing 7. CSS declarations for multi-line layouts
. flex-container {width:990px;}. Flex-item {width:300px; flex:auto;}
Because the container is only 990px wide, only 3 entries can be arranged in a row, and the remaining 1 items are arranged in a separate row. In rows of 3 entries, the extra space 90px is allocated evenly to 3 entries, whereas in a single row of an entry, the extra 690px is completely occupied by the entry.
Item Alignment
When the dimensions of the items in the container are determined, you can set the alignment of the entries in the container. There are 3 ways to align entries.
The first way is to use an automatic blank edge, or "Margin:auto". When using automatic white-space edges, additional white space in the container is declared as a blank edge of auto, as shown in Listing 8. The CSS declaration in the profile uses "Margin-left:auto" to make the left edge of the entry occupy extra space, so that the "profile" text is displayed on the right.
Listing 8. Use automatic blank edges for item alignment
<div class= "Flex-container" > <div class= "logo" >Logo</div> <div class= "Profile" > Profile</div></div>.flex-container { Display:flex;}. Profile { Margin-left:auto;}
The second approach is alignment in the spindle direction. This is set by the "Justify-content" property on the container to adjust the alignment of the entry in the spindle direction. This adjustment of the entry alignment occurs after modifying the elastic dimensions of the entry and processing the automatic blank edges. There may be additional white space on this line when entries in a row in a container do not have elastic dimensions, or if they have reached their maximum size. Use the "Justify-content" property to allocate these spaces. This property can also control how the entry is aligned when it is outside the range of the line. The optional values and meanings of the "justify-content" attribute are shown in table 3, and the actual layout effect is illustrated in Figure 2.
Table 3. Optional values and meanings of the "justify-content" property
Property Value |
meaning |
Flex-start |
The entry is centered on the starting position of the line. The first entry is aligned with the boundary of its row in the starting direction of the spindle, and the remaining entries are arranged sequentially. |
Flex-end |
The entry concentrates on the end direction of the line. The last entry is aligned with the boundary of its row in the end direction of the spindle, and the remaining entries are arranged sequentially. |
Center |
The entry concentrates on the center of the line. The entries are arranged in the center of the line, leaving the same size blank space in the starting and ending directions of the spindle. If the empty space is insufficient, the entry will exceed the same space in two directions. |
Space-between |
The first entry is aligned with the boundary of its row in the starting direction of the spindle, and the last entry is aligned with the boundary of its row in the end direction of the spindle. White space is evenly distributed between entries, making the space between adjacent entries the same size. |
Space-around |
Similar to Space-between, the difference is that there is also a white space between the first entry and the last entry and the boundary of the line, and the size of the white space is half the size of the empty space between entries. |
Figure 2. Layout effect of different values for "justify-content" property
The third Way is alignment in the direction of the cross axis. In addition to aligning in the spindle direction, entries can also be aligned in the direction of the cross axis. The property "Align-items" on the container is used to set the default alignment direction for all entries in the container on the intersection, and the attribute "Align-self" on the entry is used to overwrite the alignment specified by the container. The optional values and meanings of the attribute "Align-items" are shown in table 4, and the actual layout effect is illustrated in Figure 3.
Table 4. Optional value and meaning of the property "Align-items"
Property Value |
meaning |
Flex-start |
The entry is aligned with the boundary of the line where it is located in the start direction of the intersection axis. |
Flex-end |
The entry remains aligned with the boundary of the line where it is located in the end direction of the intersection axis. |
Center |
The Blank Edge box (margin box) of the entry is centered on the cross axis. If the cross axis size is less than the size of the entry, the entry will exceed the same size in two directions. |
Baseline |
The entry remains aligned on the baseline. In all entries, the line is the largest entry in the direction of the intersection, and it remains aligned with the boundary of the row in the intersection direction. |
Stretch |
If the calculated value for the cross-axis dimension of an entry is "Auto", the value it actually uses will make the entry as full as possible on the cross-axis direction. |
The optional value of the property "Align-self" can also be set to "auto" in addition to those listed in the table. When the value of "align-self" is auto, its computed value is the value of the parent node's property "Align-items". If the node does not have a parent node, the computed value is "Stretch".
Figure 3. Layout effect of different values for property "Align-items"
Cross-axis blank handling
The property "Align-content" is used to align the rows in the container when the container has white space in the direction of the cross axis. This property acts like "Justify-content", except that "Justify-content" is an entry in the alignment of a row in the spindle direction. This property has no effect when there is only one row in the container. The optional values and meanings of the attribute "Align-content" are shown in table 5, and the actual layout effect is illustrated in Figure 4.
Table 5. Optional value and meaning of the property "Align-content"
Property Value |
meaning |
Flex-start |
The row is centered on the start position of the intersection axis of the container. The first line is aligned with the boundary of the container in the start direction of the intersection, and the remaining rows are arranged sequentially. |
Flex-end |
The row is centered at the end of the intersection of the container. The first line is aligned with the boundary of the container in the end direction of the intersection, and the remaining rows are arranged sequentially. |
Center |
The row is centered in the container. Rows are arranged in the center of the container, leaving a blank space of the same size in the start and end directions of the intersection axis. If there is not enough white space, the rows will exceed the same space in two directions. |
Space-between |
Rows are evenly distributed in the container. The first line is aligned with the boundary of the container in the start direction of the intersection, and the last line is aligned with the boundary of the container in the end direction of the intersection axis. White space is evenly distributed between rows, making the space between adjacent lines the same size. |
Space-around |
Similar to Space-between, the difference is that there is also a white space between the first row of entries and the boundary between the last row and the container row, and the size of the white space is half the size of the blank space between the rows. |
Stretch |
Stretch the line to fill the rest of the space. The extra space is evenly distributed between rows, making the cross-axis size of each row larger. |
Figure 4. Layout effect of different values for property "Align-content"
Back to top of page
Application examples
An example is given below to illustrate the application of the flexible box layout in the actual development. This example is a typical page layout for a blog post. When displaying a blog post, the page usually includes elements such as title, publisher, date and time, number of comments, text, illustrations, comments list, and so on. These elements are basically arranged in order from top to bottom. The HTML and CSS code for the example is given in code Listing 9 and listing 10.
Listing 9. HTML code for the blog page
<div class= "POST" >
Listing 10. CSS code for the blog page. post { Display:flex; Flex-flow:column Wrap;}. Post-meta { Display:flex; Flex-flow:row Wrap; Order:1;}. post-body { order:3;}. post-comments { order:4;}. Comments-count { Margin-left:auto;}. post-image { order:2; Align-self:center;}
In this example, the "order" property is used primarily to change the display position of the entry, and "Align-self" is used to center the picture.
Browser supportBecause the elastic box model specification itself has many different versions, there are some inconsistencies in the browser's support for the specification. The browser supports a total of 3 different version specification syntax:
- New specification: The syntax for the latest version specification, which is "Display:flex".
- Intermediate version: The 2011 unofficial norm of the grammar, namely "Display:flexbox".
- Old specification: The 2009 norm of the grammar, namely "Display:box".
The browser support situation is shown in table 6 below.
Table 6. Browser support for flexible box layout models
Chrome |
Safari |
Firefox |
Opera |
IE |
Android |
IOS |
21+ (New specification) 20-(Old specification) |
6.1+ (New specification) 3.1+ (Old specification) |
22+ (New specification) 2-21 (old spec) |
12.1+ (New specification) |
11+ (New specification) 10 (intermediate version) |
4.4+ (New specification) 2.1+ (Old specification) |
7.1+ (New specification) 3.2+ (Old specification) |
As you can see from table 6, the flexible box layout model has been supported by the mainstream browser. However, in order to support different versions of the browser, in addition to the attributes defined in the specification, you need to add the appropriate browser prefix form, as shown in Listing 11.
Listing 11. The browser prefix form of the flexible box layout model
. flex-container {display:-webkit-box; display:-moz-box; display:-ms-flexbox; display:-webkit-flex; display:flex;}. Flex-item {-webkit-box-flex:auto;-moz-box-flex:auto;-webkit-flex:auto;-ms-flex:auto; flex:auto;}. Flex-item {-webkit-box-ordinal-group:1;-moz-box-ordinal-group:1;-ms-flex-order:1;-webkit-order:1; order:1;}
For these browser-related prefixes, it is best to use a tool such as autoprefixer for processing.
Summarize
As part of the CSS3 specification, the flexible box layout model simplifies the CSS code needed to complete the layout in many typical scenarios. The layout model also provides a number of useful features to meet common layout requirements, including arranging, aligning, resizing, and allocating white space for items in a container. The flexible box layout model can be a good tool in the WEB Developer Toolkit.
In-depth understanding of CSS3 flexible Box layout model