前言
在日常布局中,无论是两栏布局还是三栏布局,使用的频率都非常高,而且在面试中,被问到的几率还是挺大的。
两栏布局
两栏布局想要的效果就是将页面分割成左右宽度不等的两列,宽度较小的列设置为固定宽度,剩余宽度由另一列撑满
比如我们常见的Element文档用的就是两栏布局,左边侧边栏占少部分内容,蓝色区域为主要内容布局容器
三栏布局
三栏布局按照左中右的顺序进行排列,通常中间列最宽且会随着屏幕自适应宽度,左右两列次之
比如vant的文档就是三栏布局
两栏布局
两栏布局非常常见,实现思路也很简单,一般是左边固定宽度,右边自适应宽度
浮动实现
- 使用
float使左边容器浮动 - 右边容器使用
margin-left撑出宽度做内容显示 - 父容器添加BFC,让子容器撑起其高度 代码如下
<style>
.box {
overflow: hidden; /*添加BFC*/
}
.left {
float: left;
width: 200px;
background-color: goldenrod;
height: 200px;
}
.right {
margin-left: 200px;
background-color: lightgray;
height: 200px;
}
</style>
<div class="box">
<div class="left">left</div>
<div class="right">right</div>
</div>
flex弹性布局实现
- 给父容器添加
display:flex - 左边容器设置宽度
- 右边容器
flex:1占据剩余宽度 代码如下
<style>
.box {
display: flex;
}
.left {
background-color: greenyellow;
width: 200px;
height: 200px;
}
.right {
background-color: fuchsia;
height: 200px;
flex: 1;
}
</style>
<div class="box">
<div class="left">left</div>
<div class="right">right</div>
</div>
flex可以说时最简单的方法,代码量少,但是要注意一点,flex容器默认align-items: stretch;,这会导致两个容器会一直等高,如果不想等高可以给父容器设置一个align-items: flex-start;属性
三栏布局
面试中三栏布局被问到的概率会很大,而且大概率会问道圣杯双飞翼布局,三栏布局主要就是要实现左右两边容器宽度固定,中间容器自适应
两边使用 absolute,中间使用 margin
- 左右两边容器相对父容器定位
- 左边
top:0; left:0;右边top:0;right:0; - 中间占满一行,但通过 margin和左右两边留出位置 代码如下:
<style>
.container {
height: 200px;
position: relative;
}
/*左右进行绝对定位*/
.left,
.right {
position: absolute;
height: 100%;
top: 0;
background: #ff69b4;
}
.left {
left: 0;
width: 200px;
}
.right {
right: 0;
width: 200px;
}
/*中间用margin空出左右元素所占的空间*/
.center {
height: 100%;
padding: 0 200px;
background: #659;
}
</style>
<div class="container">
<div class="center">center</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
圣杯布局(两边使用 float 和负 margin)
- 三个元素放在同一个父级元素中,代表中间盒子的元素放在最前面。
- 父级盒子设置左右
padding,三个盒子全部浮动,设置中间盒子宽度100%。 - 左右盒子设置固定宽度,设置左边盒子左边距-100%同时相对自身定位,右边平移自身宽度,右边盒子设置右边距-自身宽度。
- 最后设置父级盒子清除浮动,否则父级盒子的高度无法被撑开。
<style>
.container {
padding: 0 200px;
overflow: hidden; /*添加BFC清除浮动*/
}
.container .column
float: left;
}
.center {
background-color: violet;
width: 100%;
}
.left {
background-color: wheat;
width: 200px;
margin-left: -100%;
position: relative;
right: 200px;
}
.right {
background-color: tomato;
width: 200px;
margin-right: -200px;
}
</style>
<div class="container">
<div class="column center">center</div>
<div class="column left">left</div>
<div class="column right">right</div>
</div>
圣杯布局不需要添加dom节点,正常情况下是没有问题的,但是特殊情况下就会暴露此方案的弊端,当center部分的宽小于left部分时就会发生布局混乱。
双飞翼布局(两边使用 absolute,中间使用 margin)
- 三个盒子对应三个元素,其中中间盒子套了两层,中间盒子内部盒子设置
margin。 - 三个盒子全部浮动,设置中间盒子宽度100%。
- 左右盒子设置固定宽度,设置左边盒子左边距-100%,右边盒子设置右边距-自身宽度。
- 后设置父级盒子清除浮动,否则父级盒子的高度无法被撑开。 代码如下:
<style>
.box {
overflow: hidden;
}
.box .column {
float: left;
}
.left {
background-color: wheat;
width: 200px;
margin-left: -100%;
}
.container {
width: 100%;
}
.center {
background-color: salmon;
margin: 0 200px;
}
.right {
background-color: springgreen;
width: 200px;
margin-right: -200px;
position: relative;
right: 200px;
}
</style>
<div class="box">
<div class="column container">
<div class="center">center</div>
</div>
<div class="column left">left</div>
<div class="column right">right</div>
</div>
双飞翼布局优点是不会像圣杯布局那样变形,CSS样式代码更简洁,缺点是多加了一层dom节点
使用 display: table 实现
<table> 标签用于展示行列数据,不适合用于布局。但是可以使用 display: table; 来实现布局的效果
- 先通过 display: table设置为表格,设置
table-layout: fixed表示列宽自身宽度决定,而不是自动计算。 - 内层的左中右通过 display: table-cell设置为表格单元。
- 左右设置固定宽度,中间设置 width: 100% 填充剩下的宽度。 代码如下:
<style>
.box {
height: 200px;
display: table;
table-layout: fixed;
width: 100%;
}
.left,
.right,
.center {
display: table-cell;
}
.left,
.right {
width: 200px;
background: greenyellow;
}
.center {
background: rosybrown;
width: 100%;
}
</style>
<div class="box">
<div class="left">left</div>
<div class="center">center</div>
<div class="right">right</div>
</div>
display: grid; 网格布局
- 将父容器设置成网格布局
grid-template-columns: 200px auto 200px;设置三列网格其中左右分别200px,中间自适应
代码如下:
<style>
.box {
display: grid;
width: 100%;
grid-template-columns: 200px auto 200px;
}
.left,
.right,
.center {
height: 200px;
}
.left {
background: coral;
}
.right {
width: 200px;
background: lightblue;
}
.center {
background: firebrick;
}
</style>
<div class="box">
<div class="left">left</div>
<div class="center">center</div>
<div class="right">right</div>
</div>
display:flex; 弹性布局
- 将父容器设置为
display:flex;。 - 盒内元素两端对齐,将中间容器设置
flex:1,填充空白区域。 代码如下:
<style>
.box {
display: flex;
justify-content: space-between;
}
.left,
.right,
.center {
height: 200px;
}
.left {
width: 200px;
background: coral;
}
.right {
width: 200px;
background: lightblue;
}
.center {
background: khaki;
flex: 1;
}
</style>
<div class="box">
<div class="left">left</div>
<div class="center">center</div>
<div class="right">right</div>
</div>