Seven ways to achieve fixed left and adaptive two-column layout on the right

Summarize the seven methods of two-column layout that is fixed on the left and adaptive on the right. Among them are the old-fashioned floatmethods, the BFC method, and the flexlayout and gridlayout of CSS3. Not all layouts will be used in development, but some knowledge points will be involved. For the final effect, you can check here

Commonly used methods of width adaptation usually take advantage of blockthe fluidity of horizontal element widths that can be adjusted with the parent container. Another idea is to use calc()methods in CSS to dynamically set the width. Another idea is to take advantage of the new layout flex layoutand layout in CSS grid layout.

Start by creating the basic HTML layout and the most basic styles.

<div class="wrapper" id="wrapper"> <div class="left"> 左边固定宽度,高度不固定 </br> </br></br></br>高度有可能会很小,也可能很大。 </div> <div class="right"> 这里的内容可能比左侧高,也可能比左侧低。宽度需要自适应。</br> 基本的样式是,两个div相距20px, 左侧div宽 120px </div> </div> 

The basic style is that the two boxes are spaced apart 20px, the left box is wide  120px, and the right box is adaptive. The basic CSS styles are as follows:

.wrapper {
    padding: 15px 20px; border: 1px dashed #ff6c60; } .left { width: 120px; border: 5px solid #ddd; } .right { margin-left: 20px; border: 5px solid #ddd; } 

The following code is covered based on this basic code, and the effect is achieved by adding different classes to the container.

dual inline-blockplan

.wrapper-inline-block {
    box-sizing: content-box; font-size: 0; // 消除空格的影响 } .wrapper-inline-block .left, .wrapper-inline-block .right { display: inline-block; vertical-align: top; // 顶端对齐 font-size: 14px; box-sizing: border-box; } .wrapper-inline-block .right { width: calc(100% - 140px); } 

This method works by width: calc(100% - 140px)dynamically calculating the width of the box on the right. You need to know the distance from the right box to the left, and the specific width of the left box (content+padding+border), so as to calculate 100%the value to be subtracted from the width of the parent container. At the same time, you also need to know whether the width of the box on the right contains borderthe width. Here, in order to simply calculate the exact width of the right box, the child element box-sizing:border-box;and the parent element are set box-sizing: content-box;. Also, as inline-blocka box of two, it must be set vertical-alignso that its tops are aligned. In addition, in order to accurately apply the calculated width, you need to eliminate divthe space between them, you need to set the parent container font-size: 0;, or use a comment to eliminate htmlthe space in the middle. shortcoming:

  • You need to know the width of the left box, the distance between the two boxes, and set the value of each element.box-sizing
  • Need to remove the effect of space characters
  • Need to set vertical-align: topto meet the top alignment.

dual floatplan

.wrapper-double-float {
    overflow: auto; // 清除浮动 box-sizing: content-box; } .wrapper-double-float .left, .wrapper-double-float .right { float: left; box-sizing: border-box; } .wrapper-double-float .right { width: calc(100% - 140px); } 

The principle of this scheme is the same as that of the dual floatscheme, both of which realize self-adaptation by dynamically calculating the width. However, since the floating blockelements will be close to each other and arranged in a row when there is space , there is no need to set display: inline-block;them, and naturally there will be fewer problems such as top alignment and space characters occupying space.

A floated box is shifted to the left or right until its outer edge touches the containing block edge or the outer edge of another float.

However, since float is applied, the parent element needs to clear the float. shortcoming:

  • You need to know the width of the box on the left, the distance between the two boxes, and set each element box-sizing.
  • The parent element needs to clear the float.

float+margin-leftplan

.wrapper-float {
    overflow: hidden; // 清除浮动 } .wrapper-float .left { float: left; } .wrapper-float .right { margin-left: 150px; } 

The above two schemes use CSS calc()functions to calculate the width value. The following two schemes use the blockflow characteristics of the width of the element box of the level to fill the parent container and adapt to the width of the parent container. But blockthe elements of the level are on their own line, so find a way to blockarrange the two together. We know that the blocklevel element will think that the floating element does not exist, but inlinethe level element can recognize the floating element. This way, blocklevel elements can be placed on the same line as floated elements. In order to keep the right and left boxes apart, there needs to be enough distance for the left box. The size of this distance is the width of the left box and the sum of the distance between the two boxes. Then set the value to that of the box on the right margin-left. shortcoming:

  • Need to clear float
  • Need to calculate the right side of the boxmargin-left

absolute+margin-leftHow to use

Another way to get the two blockto line up is to use position: absoluteabsolute positioning for the left box. This way, the right box can also ignore it.

.wrapper-absolute .left {
    position: absolute; } .wrapper-absolute .right { margin-left: 150px; } 

shortcoming:

  • Absolute positioning is used. If it is used in a div, the parent container needs to be changed position.
  • There is no way to clear the float, if the left box is higher than the right box, it will exceed the height of the parent container. min-heightSo this situation can only be placed by setting the parent container's .

float+BFCHow to use

The above methods all need to calculate a certain value through the width of the left box. The following three methods do not need to be calculated. Just set the space between the two boxes.

.wrapper-float-bfc {
    overflow: auto; } .wrapper-float-bfc .left { float: left; margin-right: 20px; } .wrapper-float-bfc .right { margin-left: 0; overflow: auto; } 

This solution also uses the left-side float, but the right-side box overflow: auto;forms a BFC, so the right-side box does not overlap the floated element.

an element in the normal flow that establishes a new block formatting context (such as an element with ‘overflow’ other than ‘visible’) must not overlap the margin box of any floats in the same block formatting context as the element itself。

In this case, you only need to set the floating box on the left margin-rightto achieve the distance between the two boxes. The box on the right is blocklevel, so the width can be adaptive. shortcoming:

  • The parent element needs to clear the float

flexplan

.wrapper-flex {
    display: flex; align-items: flex-start; } .wrapper-flex .left { flex: 0 0 auto; } .wrapper-flex .right { flex: 1 1 auto; } 

flexIt can be said to be the best solution, with less code and easy to use. One day everyone will switch to a modern browser and it will work. It should be noted that flexa default property value of the container is: align-items: stretch;. This property results in the effect of equal column heights. To make the two box heights automatic, set: align-items: flex-start;

gridplan

Another new layout. It can satisfy a need, but that's not really where it's useful.

.wrapper-grid {
    display: grid; grid-template-columns: 120px 1fr; align-items: start; } .wrapper-grid .left, .wrapper-grid .right { box-sizing: border-box; } .wrapper-grid .left { grid-column: 1; } .wrapper-grid .right { grid-column: 2; } 

Notice:

  • gridThe layout also has a default effect of equal column heights. Requires setting:  align-items: start;.
  • gridThere is one other notable flexdifference in the layout: when used margin-left, the gridlayout defaults box-sizingto the position between the set box widths. Instead , use the distance between the outer or outer sides of the flextwo divs .borderpadding

limit case

Finally, we can look at the performance of different schemes when the limit of the parent container is small. There are mainly four cases:

  • The case of dynamically calculating the width

    Two schemes: double inline-block scheme and double float scheme. When the width limit is small, the width of the div on the right will be very small, and because of the flow layout, the div on the right will move to the next line.

  • Dynamic calculation of the right margin-left case

    Two schemes: float+margin-left scheme and absolute+margin-left scheme. When the width limit is small, since the div on the right ignores the existence of the div on the left in the document flow, it will still exist in this line and be hidden.

  • float+BFCProgram situation

    In this case, due to the special relationship between BFC and float, the div on the right will also drop to the next line after the width is reduced to the minimum.

  • flexand gridthe situation

    In this case, by default, the div that neither of the two layouts cannot fit will be moved to the next line. However, flex layout can set the extra div to move to the next line through flex-flow: wrap;. Grid layout is not currently supported.

If you feel there is something wrong with the writing, please point it out.

This article was first published at https://zhuqingguang.github.io/2017/08/16/adapting-two-layout/

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325551969&siteId=291194637