双inline-block方案
方法是通过calc(100% - 140px)动态计算右侧盒子的宽度
缺点:
需要知道左侧盒子的宽度,两个盒子的距离,还要设置各个元素的box-sizing
需要消除空格字符的影响
需要设置vertical-align: top满足顶端对齐。
.warpper-inline-block{
box-sizing: border-box;
font-size: 0;
}
.warpper-inline-block .left,
.warpper-inline-block .right{
display: inline-block;
vertical-align: top;
font-size: 14px;
box-sizing: border-box;
}
.warpper-inline-block .right{
width: calc(100% - 140px);
}
双float方案
和双inline-block一样,通过calc函数计算宽度
缺点:
需要知道左侧盒子的宽度,两个盒子的距离,还要设置各个元素的box-sizing。
父元素需要清除浮动。
.wapper-double-float{
overflow: hidden; 创建bfc,清除浮动
box-sizing: border-box;
}
.wapper-double-float .left,
.wapper-double-float .right{
float: left;
box-sizing: border-box;
}
.wapper-double-float{
width: calc(100% - 140px);
}
float + margin-left方案
运用了浮动覆盖块级元素,盒模型宽度自适应性
为了让右侧盒子和左侧盒子保持距离,需要为左侧盒子留出足够的距离。
这个距离的大小为左侧盒子的宽度以及两个盒子之间的距离之和。然后将该值设置为右侧盒子的margin-left。
缺点:
需要清除浮动
需要计算右侧盒子的margin-left
.wapper-float{
overflow: hidden;
}
.wapper-float .left{
float: left;
}
.wapper-float .right{
margin-left: 150px;
}
使用absolute+margin-left方法
左侧盒子使用position:absolute,这样右侧盒子会无视绝对定位元素盒子
又因为left和top默认值为auto会计算静态位置,所以可以通过margin-left算出右侧的空间
缺点:
使用了绝对定位,若是用在某个div中,需要更改父容器的position,因为绝对定位元相对最近定位的祖先元素为包含块。
没有清除浮动的方法,若左侧盒子高于右侧盒子,就会超出父容器的高度。因此只能通过设置父容器的min-height来放置这种情况。
.wapper-absolute .left{
position: absolute;
}
.wapper-absolute .right{
margin-left:150px;
min-height: 200px;
}
使用float+bfc方法
右侧盒子创建bfc,创建bfc的常规流盒子会避开浮动盒子
这种情况下,只需要为左侧的浮动盒子设置margin-right,
就可以实现两个盒子的距离了。而右侧盒子是block级别的,
所以宽度能实现自适应。
缺点:
父元素需要清除浮动
.wapper-float-bfc{
overflow: hidden;
}
.wapper-float-bfc .left{
float: left;
margin-right: 20px;
}
.wapper-float-bfc .right{
margin-left: 0;
overflow: hidden;
}
flex方案
flex: 0 0 auto,让伸展值或收缩值为0,auto使用基础值,表示盒子不伸展不收缩保持原宽度
flex: 1 1 auto,让伸展值或收缩值为1,auto使用基础值,伸展值为1表示盒子的width加上伸展值(伸展值计算弹性容器剩余空间)
收缩值为1,表示盒子比例收缩
flex容器的一个默认属性值:align-items: stretch;。这个属性导致了列等高的效果。
为了让两个盒子高度自动,需要设置: align-items: flex-start;
无缺点
.wapper-flex{
display: flex;
align-items: flex-start;
}
.wapper-flex .left{
flex: 0 0 auto;
}
.wapper-flex .right{
flex: 1 1 auto;
}
grid方案
又一个新型的布局方式。可以满足需求,但这并不是它发挥用处的真正地方。
.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;
}
注意:
grid布局也有列等高的默认效果。需要设置: align-items: start;。
grid布局还有一个值得注意的小地方和flex不同:在使用margin-left的时候,grid布局默认是box-sizing设置的盒宽度之间的位置。而flex则是使用两个div的border或者padding外侧之间的距离。
极限情况:
动态计算宽度的情况
两种方案: 双inline-block方案和双float方案。宽度极限小时,右侧的div宽度会非常小,由于遵循流动布局,所以右侧div会移动到下一行。
动态计算右侧margin-left的情况
两种方案: float+margin-left方案和absolute+margin-left方案。宽度极限小时,由于右侧的div忽略了文档流中左侧div的存在,所以其依旧会存在于这一行,并被隐藏。
float+BFC方案的情况
这种情况下,由于BFC与float的特殊关系,右侧div在宽度减小到最小后,也会掉落到下一行。
flex和grid的情况
这种情况下,默认两种布局方式都不会放不下的div移动到下一行。不过 flex布局可以通过 flex-flow: wrap;来设置多余的div移动到下一行。 grid布局暂不支持。