三栏布局
Posted: 09.21.2019
什么是三栏布局?
描述
三栏布局是一种经典的布局。它具有以下规定:
- 三栏必须在同一行
- 左侧部分有固定的宽度
- 右侧部分有固定的宽度
- 中间部分的宽度随着页面大小而改变
- (最好能实现)中间部分首先被渲染
例子
就拿这个作为需求。
我们想要:
- 左侧部分为 200px
- 右侧部分为 300px
- 中间部分的宽度是弹性的
浮动
- 该方法并没有优先渲染中间部分
- 中间部分反而是最后渲染的,请注意查看 HTML 代码
- 中间部分必须排在左侧部分和右侧部分后
<div class="container">
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
</div>
<style>
.left {
float: left;
width: 200px;
height: 50px;
background-color: lightgreen;
}
.right {
float: right;
width: 300px;
height: 50px;
background-color: pink;
}
.center {
margin-left: 200px;
margin-right: 300px;
height: 50px;
background-color: skyblue;
}
</style>
绝对位置
- 绝对位置同样没有优先渲染中间部分
<div class='container'>
<div class='left'></div>
<div class='center'></div>
<div class='right'></div>
</div>
<style>
.left {
position: absolute;
top: 0;
left: 0;
width: 200px;
background: lightgreen;
height: 50px;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 300px;
background: pink;
height: 50px;
}
.center {
top: 0;
margin: 0 300px 0 200px;
background: skyblue;
height: 50px;
}
</style>
弹性盒
- 最简便的方法,但存在兼容性的问题
- IE 6~9 不支持
- IE 10, 11 部分支持
- 其它浏览器的最新版本都支持
- 没有优先渲染中间部分
<div class='container'>
<div class='left'></div>
<div class='center'></div>
<div class='right'></div>
</div>
<style>
.container {
display: flex;
flex-direction: row;
}
.left {
flex: 0 0 200px;
height: 50px;
background: lightgreen;
}
.right {
flex: 0 0 300px;
height: 50px;
background: pink;
}
.center {
flex-basis: 100%;
height: 50px;
background: skyblue;
}
</style>
Table 布局
- 优点是,可以同时使用
vertical-align - 没有优先渲染中间部分
<div class='container'>
<div class='left'></div>
<div class='center'></div>
<div class='right'></div>
</div>
<style>
.container {
display: table;
width: 100%;
}
.container > div {
display: table-cell;
}
.left {
width: 200px;
height: 50px;
background: lightgreen;
}
.right {
width: 300px;
height: 50px;
background: pink;
}
.center {
height: 50px;
background: skyblue;
}
</style>
Grid 布局
- Grid 能做的其实比这要多多了
- 仍然具有兼容性的问题,而且比 flexbox 问题还大
- IE 6~9 不支持
- IE 10, 11 部分支持
- QQ browser, Baidu browser and Opera Mini 不支持
- 别的浏览器的最新版本都支持
- 没有优先渲染中间部分
<div class='container'>
<div class='left'></div>
<div class='center'></div>
<div class='right'></div>
</div>
<style>
.container {
display: grid;
width: 100%;
grid-template-rows: 50px;
grid-template-columns: 200px auto 300px;
}
.left {
background: lightgreen;
}
.center {
background: skyblue;
}
.right {
background: pink;
}
</style>
圣杯布局
- 优先渲染中间部分
- 核心思想是利用负边距
- 设置负边距会让当前的元素朝着左上角的位置移动,整体移动的距离便是负边距指定的距离
- 如果该行无法满足移动的距离,该元素会移动到上面一行,从右往左继续移动剩下的距离
<div class='container'>
<div class='center col'></div>
<div class='left col'></div>
<div class='right col'></div>
</div>
<style>
/* padding from right 300px and from left 200px */
.container {
height: 50px;
padding: 0 300px 0 200px;
}
/* 这里设置位置为 relative 是为了使用 left/right 属性 */
.col {
float: left;
position: relative;
}
/**
* 在使用负边距前,左侧元素在中间元素的正下方,两者左侧对齐
*
* 1. 设置负边距会让左侧元素朝着左上方的位置移动
* 2. margin-left: -100%,意味着左侧元素需要移动 100% 的距离(相对于页面),也就是一整行
* 3. 因此,左侧元素最终的位置是和中间元素重叠的,两者左侧对齐
* 4. 然后需要设置 left: -200px,这样的话左侧元素就会移动到之前空出来的 padding 空间里
*/
.left {
left: -200px;
width: 200px;
margin-left: -100%;
height: 50px;
background: lightgreen;
}
/**
* 在使用负边距前,右侧元素在中间元素的正下方,两者左侧对齐
*
* 1. 设置负边距会让右侧元素朝着左上方的位置移动
* 2. margin-left: -300px,意味着右侧元素需要移动 300px 的距离(正好为其的宽度)
* 3. 因此,右侧元素最终的位置是和中间元素重叠的,两者右侧对齐
* 4. 然后需要设置 right: -300px,这样的话右侧元素就会移动到之前空出来的 padding 空间里
*/
.right {
right: -300px;
width: 300px;
margin-left: -300px;
height: 50px;
background: pink;
}
.center {
width: 100%;
height: 50px;
background: skyblue;
}
</style>
双飞翼布局
- 中间的部分会优先渲染
- 核心思想依旧还是负边距,和圣杯布局很类似
- 但是 HTML 的结构变了,而在双飞翼布局里,left/right就不需要了
- 因为在圣杯布局里,有左侧和右侧的 padding,用来容纳左侧和右侧部分。
- 这也就意味着,在应用负边距前,左侧部分和右侧部分的起始位置,并不是 container 的边缘,而是 padding 后的位置
- 因此, -100% 的左侧 margin 会让左侧元素移动到正上方相同的位置,也就是中间元素的位置,左侧对齐
- 右侧元素也是这个道理
- 而在双飞翼布局中,container 的宽度是满的,反而是中间部分的两侧有 margin
- 因此,左侧元素和右侧元素,在应用负边距前的起始位置,就是container的边缘,与其左对齐
- 在这样的情况下,-100% 的 margin 会让左侧元素移动到正上方相同的位置,也就是中间部分 margin 空出来的位置,因此就不需要设置 left/right 属性
- 右侧元素也是这个道理
<div class='container'>
<div class='center col'>
<div class='center-inner'></div>
</div>
<div class='left col'></div>
<div class='right col'></div>
</div>
<style>
.container {
height: 50px;
}
.col {
float: left;
}
.center {
width: 100%;
height: 50px;
background: skyblue;
}
.center-inner {
margin: 0 300px 0 200px;
}
.left {
width: 200px;
height: 50px;
margin-left: -100%;
background: lightgreen;
}
.right {
width: 300px;
height: 50px;
margin-left: -300px;
background: pink;
}
</style>
参考资料
圣杯布局、双飞翼布局、Flex布局和绝对定位布局的几种经典布局的具体实现示例