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 float
methods, the BFC method, and the flex
layout and grid
layout 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 block
the 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 layout
and 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-block
plan
.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 border
the 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-block
a box of two, it must be set vertical-align
so that its tops are aligned. In addition, in order to accurately apply the calculated width, you need to eliminate div
the space between them, you need to set the parent container font-size: 0;
, or use a comment to eliminate html
the 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: top
to meet the top alignment.
dual float
plan
.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 float
scheme, both of which realize self-adaptation by dynamically calculating the width. However, since the floating block
elements 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-left
plan
.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 block
flow 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 block
the elements of the level are on their own line, so find a way to block
arrange the two together. We know that the block
level element will think that the floating element does not exist, but inline
the level element can recognize the floating element. This way, block
level 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 box
margin-left
absolute+margin-left
How to use
Another way to get the two block
to line up is to use position: absolute
absolute 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-height
So this situation can only be placed by setting the parent container's .
float+BFC
How 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-right
to achieve the distance between the two boxes. The box on the right is block
level, so the width can be adaptive. shortcoming:
- The parent element needs to clear the float
flex
plan
.wrapper-flex {
display: flex; align-items: flex-start; } .wrapper-flex .left { flex: 0 0 auto; } .wrapper-flex .right { flex: 1 1 auto; }
flex
It 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 flex
a 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;
grid
plan
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:
grid
The layout also has a default effect of equal column heights. Requires setting:align-items: start;
.grid
There is one other notableflex
difference in the layout: when usedmargin-left
, thegrid
layout defaultsbox-sizing
to the position between the set box widths. Instead , use the distance between the outer or outer sides of theflex
two divs .border
padding
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+BFC
Program situationIn 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.
-
flex
andgrid
the situationIn 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/