左侧固定,右侧自适应两栏是css中常见的布局,比如本站的主页,左侧是导航栏,右侧则是主要内容。
为了方便理解,整篇文章将左侧盒子记为LA,右侧盒子记为RB,模型如下图。

一、 双inline-block
这种方法是通过width: calc(100% - 140px)来动态计算RB的宽度。为了得到width,我们需要知道:
两个盒子之间的的距离(RB的margin-left);
LA宽度(content+padding+border),以此计算父容器宽度的100%需要减去的数值。
为了简化盒子宽度的计算,LA 和 RB 设置为 box-sizing:border-box;以及父元素的box-sizing: content-box;。
由于两个inline-block的盒子,盒子顶端会出现不对齐现象,通过设置vertical-align解决。
inline-block的盒子之间存在空隙,通过设置父容器的font-size: 0;或者用注释消除html中的空格等方法解决。
代码如下
.wrapper {
padding: 15px 20px;
border: 1px dashed #ff6c60;
box-sizing: content-box;//width只包含子元素,不包括border和padding
font-size: 0; }
.left {
width: 120px;
border: 5px solid #ddd;
}
.right {
margin-left: 20px;
border: 5px solid #ddd;
width: calc(100% - 140px);//(left-width)+margin=140px
}
.wrapper .left,
.wrapper .right {
display: inline-block;
vertical-align: top;
font-size: 14px;
box-sizing: border-box;
}
双inline-block虽然利用了calc动态计算盒子宽度,但是也存在以下缺点:
1. 需要知道LA的宽度,两个盒子的距离,还要设置各个元素的box-sizing
2. 需要消除空格字符的影响
3. 需要设置vertical-align: top满足顶端对齐。
二、 双float
LA 和 RB 均通过float来布局,同样利用了calc动态计算RB的宽度
.wrapper {
padding: 15px 20px;
border: 1px dashed #ff6c60;
box-sizing: content-box;
overflow: auto;//父元素需要清除浮动
}
.left {
width: 120px;
border: 5px solid #ddd;
}
.right {
margin-left: 20px;
border: 5px solid #ddd;
width: calc(100% - 140px);
}
.wrapper .left,
.wrapper .right {
float: left;
box-sizing: border-box;
}
双float虽然利用了float布局,但是也存在以下缺点:
1. 需要知道LA的宽度,两个盒子的距离,还要设置各个元素的box-sizing。
2. 父元素需要清除浮动。
无论是inline-block 还是 float 都需要知道每个部分的宽度范围,否则无法实现自适应 。
三、 float+margin-left (更常用一点)
为了让 LA 和 RB 之间具有一定空隙,需要为 LA 留出足够的距离,这个距离的大小(W)=LA的width + 两个盒子之间的距离。通过设置RB的margin-left = W可以实现布局,代码部分如下。
.wrapper {
overflow: hidden; // 清除浮动,使得父元素的高度可以包含浮动子元素
}
.wrapper .left {
float: left;
width: 120px;
}
.wrapper .right {
margin-left: 150px;//RB 距离 LA 20px
}
.wrapper .left,
.wrapper .right {
height: 500px;
border: 5px solid #ddd;
}
这个方法存在的缺点:
1. 需要清除浮动
2. 需要计算右侧盒子的margin-left
四、 absolute+margin-left
LA使用绝对定位(在文档流中不占空间),让RB不能无视LA的存在
.wrapper .left {
width: 120px;
position: absolute;
}
.wrapper .right {
margin-left: 150px;
}
这种方法的缺点是:
1. 使用了绝对定位,若是用在某个div中,需要更改父容器的position。
2. 没有清除浮动的方法,若LA高于RB,就会超出父容器的高度。因此只能通过设置父容器的min-height来放置这种情况。
五、float+BFC
关于BFC可详见BFC,利用了左侧浮动,但是右侧盒子通过overflow: auto形成了BFC,因此右侧盒子不会与浮动的元素重叠。代码如下,
.wrapper {
padding: 15px 20px;
border: 1px dashed #ff6c60;
box-sizing: content-box;
overflow: auto;//清除浮动
}
.left {
width:120px;
border: 5px solid #ddd;
float: left;
margin-right: 20px;
}
.right {
margin-left: 0;
overflow: auto;//形成BFC
border: 5px solid #ddd;
}
六、flex布局法(个人觉得非常好用)
关于flex的详细介绍详见flex布局;
.wrapper {
display: flex;
align-items: flex-start;//两列自动对齐
}
.wrapper .left {
flex: 0 0 auto;
}
.wrapper .right {
flex: 1 1 auto;
}
七、grid
暂时还没用过 。。。