三栏布局一般指的是页面中一共有三栏,左右两栏宽度固定,中间自适应的布局,三栏布局的具体实现
浮动
利用浮动,左右两栏设置固定大小,并设置对应方向的浮动。中间一栏设置左右两个方向的margin值,注意这种方式,中间一栏必须放到最后
浮动元素的布局有个特点:其摆放的位置会避开常规流元素(书写在浮动元素前面的常规流元素),但后面的常规流元素依然会与其进行重叠
所以如果我们要利用浮动的方法来实现三栏布局,那么侧边栏对应的元素在html文档中的位置就要在主区域的前面,但这样也导致了主体内容是最后加载的
<style>
.container {
height: 200px;
}
.left {
float: left;
width: 200px;
height: 100%;
background-color: orange;
}
.right {
float: right;
width: 300px;
height: 100%;
background-color: orange;
}
.main {
height: 100%;
margin-left: 200px;
margin-right: 300px;
background-color: lightblue;
}
</style>
<body>
<div class="container">
<aside class="left"></aside>
<aside class="right"></aside>
<div class="main"></div>
</div>
</body>
将三栏的元素全部浮动,利用calc计算属性控制主区域的宽度
<style>
.container {
height: 200px;
}
.left,
.right,
.main {
float: left;
height: 100%;
}
.left {
width: 200px;
background-color: orange;
}
.right {
width: 300px;
background-color: orange;
}
.main {
width: calc(100% - 500px);
background-color: lightblue;
}
</style>
<body>
<div class="container">
<aside class="left"></aside>
<div class="main"></div>
<aside class="right"></aside>
</div>
</body>
绝对定位
利用绝对定位,左右两栏设置为绝对定位,中间设置对应方向大小的margin的值,无需考虑HTML结构中的顺序
这种做法有个好处:就是可以把我们主要区域那一栏书写在包含块的最前面,这样有利于SEO优化,搜索引擎在读取源代码的时候会认为越靠前的元素越重要
<style>
.container {
position: relative;
height: 200px;
}
.main {
height: 100%;
margin-left: 200px;
margin-right: 300px;
background-color: lightblue;
}
.left {
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 100%;
background-color: orange;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 300px;
height: 100%;
background-color: orange;
}
</style>
<body>
<div class="container">
<div class="main"></div>
<aside class="left"></aside>
<aside class="right"></aside>
</div>
</body>
flex布局
利用flex布局,左右两栏设置固定大小,中间一栏设置为flex:1;由于开启了开启了flex布局的元素的align-items属性为strench,所以其子元素的高度会自动伸展至填充父元素
<style>
.container {
display: flex;
height: 200px;
}
.left {
flex: 0 0 200px;
background-color: orange;
}
.right {
flex: 0 0 300px;
background-color: orange;
}
.main {
flex: 1;
background-color: lightblue;
}
</style>
<body>
<div class="container">
<aside class="left"></aside>
<div class="main"></div>
<aside class="right"></aside>
</div>
</body>
圣杯布局(浮动与相对定位的结合)
利用浮动和负边距来实现。父级元素设置左右的 padding,三列均设置向左浮动,中间一列放在最前面,宽度设置为父级元素的宽度,因此后面两列都被挤到了下一行,通过设置 margin-left 负值将其移动到上一行,再利用相对定位,定位到两边
浮动元素已经脱离了文档流,所以margin-left作用与浮动元素与作用于常规流元素效果不同,如果是常规流元素,无论下一行的margin值为多少,都不会切换到上一行去;但是对于浮动元素而言,却可以轻易通过margin值跨行移动,这也是我们实现圣杯布局的重要基础
<style>
.container {
height: 200px;
padding: 0 300px 0 200px;
}
.left,
.right,
.main {
float: left;
height: 100%;
}
.main {
width: 100%;
background-color: lightblue;
}
.left {
position: relative;
top: 0;
left: -200px;
width: 200px;
margin-left: -100%;
background-color: orange;
}
.right {
position: relative;
top: 0;
right: -300px;
width: 300px;
margin-left: -300px;
background-color: orange;
}
</style>
<body>
<div class="container">
<div class="main"></div>
<aside class="left"></aside>
<aside class="right"></aside>
</div>
</body>
双飞翼布局
双飞翼布局相对于圣杯布局来说,左右位置的保留是通过中间列的 margin 值来实现的,而不是通过父元素的 padding 来实现的,而且主要区域多了一层嵌套元素,导致我们可以不需要使用相对定位。但本质上来说,其也是通过浮动和外边距负值来实现的
- 左边通过使用
margin-left:-100%,相当于中间的宽度,所以向上偏移到左侧 - 右边通过使用
margin-left:-300px,相当于自身宽度,所以向上偏移到最右侧
<style>
.container {
height: 200px;
}
.left,
.right,
.wrapper {
float: left;
height: 100%;
}
.wrapper {
width: 100%;
}
.main {
height: 100%;
margin-left: 200px;
margin-right: 300px;
background-color: lightblue;
}
.left {
width: 200px;
margin-left: -100%;
background-color: orange;
}
.right {
width: 300px;
margin-left: -300px;
background-color: orange;
}
</style>
<body>
<div class="container">
<div class="wrapper">
<div class="main"></div>
</div>
<aside class="left"></aside>
<aside class="right"></aside>
</div>
</body>
table布局
标签用于展示行列数据,不适合用于布局。但是可以使用 display: table 来实现布局的效果
- 先通过
display: table 设置为表格,设置 table-layout: fixed 表示列宽自身宽度决定,而不是由单元格内容设定;
- 内层的左中右通过
display: table-cell设置为表格单元
- 左右设置固定宽度,主区域填充剩下的宽度
<style>
.container {
display: table;
height: 200px;
}
.left,
.right,
.main {
display: table-cell;
height: 100%;
}
.left {
width: 200px;
background-color: orange;
}
.main {
background-color: lightblue;
}
.right {
width: 300px;
background-color: orange;
}
</style>
<body>
<div class="container">
<aside class="left"></aside>
<div class="main"></div>
<aside class="right"></aside>
</div>
</body>
grid布局
将父容器设置为grid布局,grid-template-columns: 200px auto 300px; 设置三列网格其中左右分别为200px和300px,中间自适应
<style>
.container {
display: grid;
height: 200px;
grid-template-columns: 200px auto 300px;
}
.left {
background-color: orange;
}
.right {
background-color: orange;
}
.main {
background-color: lightblue;
}
</style>
<body>
<div class="container">
<aside class="left"></aside>
<div class="main"></div>
<aside class="right"></aside>
</div>
</body>
实现效果
display: table 设置为表格,设置 table-layout: fixed 表示列宽自身宽度决定,而不是由单元格内容设定;display: table-cell设置为表格单元<style>
.container {
display: table;
height: 200px;
}
.left,
.right,
.main {
display: table-cell;
height: 100%;
}
.left {
width: 200px;
background-color: orange;
}
.main {
background-color: lightblue;
}
.right {
width: 300px;
background-color: orange;
}
</style>
<body>
<div class="container">
<aside class="left"></aside>
<div class="main"></div>
<aside class="right"></aside>
</div>
</body>
grid-template-columns: 200px auto 300px; 设置三列网格其中左右分别为200px和300px,中间自适应<style>
.container {
display: grid;
height: 200px;
grid-template-columns: 200px auto 300px;
}
.left {
background-color: orange;
}
.right {
background-color: orange;
}
.main {
background-color: lightblue;
}
</style>
<body>
<div class="container">
<aside class="left"></aside>
<div class="main"></div>
<aside class="right"></aside>
</div>
</body>
上述所有方法最终实现的效果均如下图所示: