CSS has long struggled with simple, efficient, accurate and compatible layouts, but in traditional layouts, only float and Position are reliable and cross-browser compatible technologies. In order to further improve the layout ability, CSS in 2009 launched the layout tool Flex and launched behind the king grid layout, among them, Flex has a powerful one-dimensional layout ability, and grid has a more powerful two-dimensional layout ability. Today, we are going to talk about flex layout techniques based on centering, spatial distribution, Margin + Flex layout and responsive layout.

Center problem

In traditional layout technology, horizontal and vertical positioning requirements can be realized by means of text-align, margin, padding, position and other means for different element types, but these troublesome technologies have specific objects. For example, text-align and line-height are for inline elements, while margin: Auto is for block-level elements. Flex layout technology simplifies application scenarios by simply setting just-Content: Center for any type of element, align-items for vertical center, and both for horizontal and vertical center. Let’s look at a few examples:

First, block-level elements can be easily centered horizontally and vertically.

<head> <style>.father {/* set the flex layout */ display: flex; /* Implement horizontal center */ justify-content: center; /* align-items: center; width: 500px; height: 500px; background-color: antiquewhite; } .son { width: 100px; height: 100px; background-color: lightpink; } </style> </head> <body> <div class="father"> <div class="son"></div> </div> </body>Copy the code

Then, when we look at inline elements, it’s ok for the same set of code to center them horizontally and vertically.

<head> <style>.father {/* set the flex layout */ display: flex; /* Implement horizontal center */ justify-content: center; /* align-items: center; width: 500px; height: 500px; background-color: antiquewhite; } .son { width: 100px; height: 100px; background-color: lightpink; } </style> </head> <body> <div class="father"> <! - the child elements directly replace with inline element - > < span class = "son" > < / span > < / div > < / body >Copy the code

In general, inline elements cannot be sized by setting width and height attributes, but once a Flex layout is set, it automatically adds display: block to inline elements, and flex layouts invalidate float, clear, and vertical-align attributes.

It’s worth noting that the flex layout affects only the immediate children of the container, not all descendants. Let’s look at the following example

<head> <style> .father { display: flex; justify-content: center; align-items: center; width: 500px; height: 500px; background-color: antiquewhite; } .container { width: 200px; height: 200px; background-color: rgb(9, 131, 238); } .son { width: 100px; height: 100px; background-color: lightpink; } </style> </head> <body> <div class="father"> <! Son --> <div class="container"> <span class="son">son</span> </div> </div> </body>Copy the code

By adding a layer of containers around the SPAN element, flex’s influence cannot be passed to the SPAN element, height and width cannot be set, and horizontal and vertical Settings cannot be passed to the direct child of the non-father span element through container.

Spatial distribution problem

Flex layouts overcome the difficulty of achieving flexible spatial distribution and alignment with traditional layouts. On the Flex axis (horizontal x by default), you can control space allocation and alignment by setting Flex and context-Content, and on the Flex cross axis (vertical Y by default) you can control space allocation and alignment by setting align-items and align-self.

1. Spindle space

First, let’s take a look at the multi-column layout. Set the width of each column to be fixed and evenly distributed on the horizontal axis to achieve the following effect:

In traditional layout, it is very troublesome to realize the uniform horizontal space distribution of the column layout adaptive parent container, at least not by stacking float+margin directly. But using the Flex layout you can directly set up the implement-Content: space-instituted implementation.

<head> <style> .container { display: flex; width: 800px; height: 500px; background-color: antiquewhite; /* Set justify-content to evenly split space */ justify-content: space instituted; } .container > * { line-height: 50px; text-align: center; width: 50px; height: 50px; background-color: lightcoral; } </style> </head> <body> <div class="container"> <div class="item1">item1</div> <div class="item2">item2</div> <div class="item3">item3</div> <div class="item4">item4</div> <div class="item5">item5</div> </div> </body>Copy the code

Let’s look at the allocation of space for elements. You can set Up Flex to set the allocation of space for elements on the main axis. For details on the flex property allocation algorithm, refer to my other article flex Layout allocation. Suppose you want to set up 3 column Spaces, fixed width sidebar on both sides, adaptive width content in the middle, the effect is as follows:

Traditional layouts can be implemented using float or position layout strategies, but they are not very compact. When using Flex layout, simply set the middle content area to Flex :1(mainly to adjust the flex-grow property) and set the left and right sides to a constant width.

<head> <style> .main { display: flex; height: 500px; background-color: antiquewhite; } .main > * { line-height: 50px; text-align: center; } .sidebar-left { width: 100px; background-color: aqua; }. Content {/* flex defaults to 0 1 auto; */ flex:1; background-color:coral; } .sidebar-right { width: 100px; background-color: aqua; } </style> </head> <body> <div class="main"> <div class="sidebar-left">sidebar-left</div> <div class="content">content</div> <div class="sidebar-right">sidebar-right</div> </div> </body>Copy the code

The Grid system also uses Flex layout, and sets the Flex property and width property to divide the spindle space into 12 parts. In bootstrap source code, first set flex layout in the row class, and then set the corresponding proportion width and Flex properties in col-*, col-MD -* and other layout properties to achieve different space allocation.

. Row {-- -- bs - gutter - x: 1.5 rem; --bs-gutter-y: 0; /* Set flex layout in row */ display: flex; flex-wrap: wrap; margin-top: calc(-1 * var(--bs-gutter-y)); Margin - right: calc (0.5 * var (-- bs - gutter - x)); Margin - left: calc (0.5 * var (-- bs - gutter - x)); }. Col {/* Set flex to 1 in col class */ flex: 1 0 0%; } .col-1 { flex: 0 0 auto; /* Set the col-1 class width to 1/12 */ width: 8.33333333%; } .col-2 { flex: 0 0 auto; /* Set the col-1 class width to 2/12 */ width: 16.66666667%; } .col-3 { flex: 0 0 auto; /* In the col-1 class set the width to 3/12 */ width: 25%; } /* col-* * *Copy the code

Thus, the following effects can be achieved:

<div class="container">
  <div class="row">
    <div class="col">
      1 of 3
    </div>
    <div class="col-6">
      2 of 3 (wider)
    </div>
    <div class="col">
      3 of 3
    </div>
  </div>
  <div class="row">
    <div class="col">
      1 of 3
    </div>
    <div class="col-5">
      2 of 3 (wider)
    </div>
    <div class="col">
      3 of 3
    </div>
  </div>
</div>
Copy the code

<div class="container">
  <div class="row">
    <div class="col">
      1 of 2
    </div>
    <div class="col">
      2 of 2
    </div>
  </div>
  <div class="row">
    <div class="col">
      1 of 3
    </div>
    <div class="col">
      2 of 3
    </div>
    <div class="col">
      3 of 3
    </div>
  </div>
</div>
Copy the code

Finally, we can also use Flex to implement sticky footer, as shown in the following image. You can push the footer directly to the bottom of the page, which is very simple.

<head>
    <style>
        html {
            height: 100%;
        }

        body {
            min-height: 100%;
            display: flex;
            /* Set the axis to y */
            flex-direction: column;
        }
        
        header {
            height: 50px;
            background-color: aqua;
        }

        main {
            /* Here main takes up all remaining space in the main direction */
            flex: 1;
            background-color: aquamarine;
        }

        footer {
            background-color: antiquewhite;
            height: 50px;
        }
    </style>
</head>

<body>
    <header>header</header>
    <main>main</main>
    <footer>footer</footer>
</body>
Copy the code

2. Cross axis space

On the cross axis, we use the flex align-items and align-self layout to overcome the problems of contour layout, baseline alignment, etc. It is very flexible and convenient!

For example, in section 1, we use align-items: center to center the element vertically. For example, the 3 column Spaces in the previous section are only suitable for layout. We use the default value of “stretch” of align-items to realize the high-height layout of the three column Spaces of “sidebar left”, “Content” and “sidebar Right”.

For the baseline alignment layout, we can also do this cleanly with align-items: flex-end.

   <head>
       <style>
           .container {
               display: flex;
               height: 500px;
               width: 500px;
               background-color: antiquewhite;
               align-items: flex-end;
           }

           .container > * {
               text-align: center;
               width: 100px;
               margin: 0 30px;
               background-color: aquamarine;
           }  

           .item1 {
               height: 100px;
           }

           .item2 {
               height: 200px;
           }

           .item3 {
               height: 300px;
           }


       </style>
   </head>
   <body>
       <div class="container">
           <div class="item1">item1</div>
           <div class="item2">item2</div>
           <div class="item3">item3</div>
       </div>
   </body>
Copy the code

Margin + flex layout

If flex layout is a sharp tool, then margin: Auto with flex layout is a magic tool.

Although The Flex layout is strong, the flex layout’s space allocation strategy, which focuses on Flex elements, is much weaker when it comes to controlling the spacing between elements, with only a few keywords in the context-content attribute. For example, implementing the following two navigation bars is more difficult.

This can also be done with a float layout, or by wrapping the first three elements HOME,BLOG, and ARTICLE in a container, and then using context-Content: Between. Here, we use Margin: Auto to be more efficient. We can use margin-left in the last element: auto. Push the last element to the far right.

<head> <style> ul { border: 1px solid rgb(216, 216, 216); width: 80%; margin: auto; padding: 0; display: flex; } li { margin: 0; list-style: none; line-height: 3em; border-bottom: 1px solid transparent; padding: 0 1em; } li:hover { border-bottom: 1px solid rgb(8, 250, 0); cursor: pointer; } li a { text-decoration: none; color: black; } li:last-child {/* Last element uses margin-left: auto. */ margin-left: auto; } </style> </head> <body> <nav> <ul> <li><a href="#">HOME</a></li> <li><a href="#">BLOG</a></li> <li><a href="#">ARTICLE</a></li> <li><a href="#">CONTACT</a></li> </ul> </nav> </body>Copy the code

As zhang Xinxu said, margin: Auto padding rule is as follows:

  1. If one side is fixed, one sideauto,autoIs the size of the remaining space
  2. If both sides are zeroauto, then the remaining space is evenly divided

We use fixed-width + Margin: Auto to achieve horizontal centering in block-level elements, set fixed-width height in absolute positioning and set the opposite attribute to 0, and then use Margin: Auto to achieve horizontal and vertical centering. In Flex layout, all space is left over except the height and width of the element itself, and margin: Auto controls how it is allocated.

For example, we set the width of the elements in the Flex layout and use Margin: Auto to center them horizontally. Set the height of the elements in the Flex layout and use Margin: Auto to center them vertically.

Responsive layout

Using Flex layout technology and media query technology, it is easy to achieve a responsive layout. For the navigation bar example above, we add the following media query code:

@media screen and (max-width:500px) {/* flex: column; } li:last-child { margin-left: 0; }}Copy the code

When the screen width is less than 500px, the navigation bar layout is vertical:

conclusion

In general, Flex’s control ability in one-dimensional space is very strong, mainly reflected in the spindle and cross axis alignment and space allocation is very simple and efficient operation, can be very convenient to achieve horizontal and vertical center, space isometric, bottom alignment, isometric alignment, adaptive multi-column layout and responsive layout, at the same time, margin: Auto scheme with flex layout is even more powerful, in the spatial distribution of control ability to a higher level, basic can meet the needs of daily layout. Flex layout technology is now supported in most browsers, such as Firefox, Chrome, Opera, Microsoft Edge and IE 11, and is the preferred solution for one-dimensional layouts if Flex meets project compatibility requirements.