1. 两栏布局
<div class="father">
<div class="left"></div>
<div class="right"></div>
</div>
左侧宽度固定,右边自适应
-
float + margin-left
.father { width: 500px; height: 100px; background-color: aquamarine; } .left { float: left; width: 100px; height: 100px; background-color: aqua; } .right { margin-left: 100px; height: 100px; background-color: bisque; }
-
float + bfc
.father { width: 500px; height: 100px; background-color: aquamarine; } .left { float: left; width: 100px; height: 100px; background-color: aqua; } /* 可以通过 overflow 创建 BFC 区域 */ .right { overflow: hidden; height: 100px; background-color: bisque; } /* 或者可以通过 display 创建 BFC 区域 */ /* .right { display: flex; height: 100px; background-color: bisque; } */
- 原理是 BFC 区域,默认不会和 float 元素重叠
- 但设置 right 元素的 float 不行,因为 float 元素的宽度如果没有设置,会尽可能的窄(刚好与内容宽度相同)
-
利用 position: absolute
.father { position: relative; width: 500px; height: 100px; background-color: aquamarine; } .left { width: 100px; height: 100px; background-color: aqua; } .right { position: absolute; height: 100px; top: 0; left: 100px; right: 0; background-color: bisque; }
- 虽然 absolute 的默认宽度也是尽可能的窄,但是可以通过设置 left 和 right 拉开
-
inline-block + calc
.father { font-size: 0; width: 500px; height: 100px; background-color: aquamarine; } .left { display: inline-block; width: 100px; height: 100px; background-color: aqua; } .right { display: inline-block; width: calc(100% - 100px); height: 100px; background-color: bisque; }
- 需要设置 font-size 否则 inline-block 之间会有空隙(被当作空格的换行符)
-
flex 弹性盒子
.father { display: flex; width: 500px; height: 100px; background-color: aquamarine; } .left { width: 100px; height: 100px; background-color: aqua; } .right { flex: 1; height: 100px; background-color: bisque; }
- flex 是 flex-grow,flex-shrink,flex-basis 的缩写,相当于 flex-grow: 1
-
grid 网格布局
.father { display: grid; width: 500px; height: 100px; grid-template-columns: 100px auto; background-color: aquamarine; } .left { grid-column: 1; height: 100px; background-color: aqua; } .right { grid-column: 2; height: 100px; background-color: bisque; }
左侧宽度不固定,右边自适应
- float + bfc
- flex 弹性盒子
- grid 网格布局
2. 三栏布局
( 和两栏布局很相似,但是为了面试问到还要想,还是整理了一下,到时候能回答的更流利 )
<div class="father">
<div class="left"></div>
<div class="middle"></div>
<div class="right"></div>
</div>
左右定宽,中间自适应
-
float + position
.father { position: relative; width: 500px; height: 200px; background-color: antiquewhite; } .left { float: left; width: 100px; height: 200px; background-color: blueviolet; } .right { float: right; width: 100px; height: 200px; background-color: aqua; } .middle { position: absolute; left: 100px; right: 100px; height: 200px; background-color: chartreuse; }
-
position + margin-left
不能再 float + margin-left + margin-right 因为 margin-right 会把右边的 float 元素给挤到下一行.father { position: relative; width: 500px; height: 200px; background-color: antiquewhite; } .left { position: absolute; top: 0; left: 0; width: 100px; height: 200px; background-color: blueviolet; } .right { position: absolute; top: 0; right: 0; width: 100px; height: 200px; background-color: aqua; } .middle { margin-left: 100px; margin-right: 100px; height: 200px; background-color: chartreuse; } /* 或者可以不通过 margin,通过纯 position 实现 */ /* .middle { position: absolute; left: 100px; right: 100px; height: 200px; background-color: chartreuse; } */
-
float + BFC
注意之前的 div 顺序是左中右,这里需要改成 左右中
原因是,BFC 会避开 float 区域,先渲染左,然后渲染中的时候,中会把除了左覆盖的范围全覆盖上,再渲染右的时候,右便会被挤到第二行,而如果先渲染左,再渲染右,最后渲染中的时候,它会自动避开左和右,就不会出现问题.father { width: 500px; height: 200px; background-color: antiquewhite; } .left { float: left; width: 100px; height: 200px; background-color: blueviolet; } .right { float: right; width: 100px; height: 200px; background-color: aqua; } .middle { overflow: hidden; height: 200px; background-color: chartreuse; } <!-- 注意这里的顺序 --> <div class="father"> <div class="left"></div> <div class="right"></div> <div class="middle"></div> </div>
-
inline-block + calc
.father { font-size: 0; width: 500px; height: 200px; background-color: antiquewhite; } .left { display: inline-block; width: 100px; height: 200px; background-color: blueviolet; } .right { display: inline-block; width: 100px; height: 200px; background-color: aqua; } .middle { display: inline-block; width: calc(100% - 200px); height: 200px; background-color: chartreuse; }
-
flex 弹性盒子
.father { display: flex; width: 500px; height: 200px; background-color: antiquewhite; } .left { width: 100px; height: 200px; background-color: blueviolet; } .right { width: 100px; height: 200px; background-color: aqua; } .middle { flex: 1; height: 200px; background-color: chartreuse; }
-
grid 网格布局
.father { display: grid; grid-template-columns: 100px auto 100px; width: 500px; height: 200px; background-color: antiquewhite; } .left { grid-column: 1; height: 200px; background-color: blueviolet; } .right { grid-column: 3; height: 200px; background-color: aqua; } .middle { grid-column: 2; height: 200px; background-color: chartreuse; }
3. 总结 两栏布局 和 三栏布局
( 面试应该怎么回答 )
不管是 两栏布局还是 三栏布局,都有很多很多种,本质上基本上都是依靠 absolute 绝对定位,margin,inline-block,calc 计算属性,float 和 BFC( 不会覆盖到 float 区域的特性 )这几个方法,进行组合来实现的,例 absolute + margin,float + margin,inline-block + calc 计算属性,float + BFC 等等方法,又或者直接通过 flex 布局或者 grid 布局可以更轻松的实现