CSS 三栏布局之圣杯布局和双飞翼布局
主要介绍两种, 圣杯布局和双飞翼布局
两者都是实现左右两栏固定宽度, 中间自适应的三栏布局.
写了两个Demo, 实现了两种布局的效果, 点击可以预览
圣杯布局
双飞翼布局
前言
为什么会出现圣杯布局?
传统情况下我们对于三栏布局方案是这样的
<header>header</header>
<div class="container">
<div class="left">
<p>这是左边的盒子</p>
</div>
<div class="middle">
<p>这是中间的盒子</p>
</div>
<div class="right">
<p>这是右边的盒子</p>
</div>
</div>
<footer>footer</footer>
从上到下,从左到右
因为浏览器渲染引擎在构建和渲染渲染树是异步的(谁先构建好谁先显示)
所以我们希望将中间部分的主内容提取,提前显示,通过CSS,优化DOM的渲染
于是提出了这样的结构
<div class="container">
<div class="middle">
<p>这是中间的盒子</p>
</div>
<div class="left">
<p>这是左边的盒子</p>
</div>
<div class="right">
<p>这是右边的盒子</p>
</div>
</div>
下面看看如何实现吧
1. 圣杯布局
圣杯布局来源于文章In Search of the Holy Grail
首先给出固定HTML样式, 注意中间的盒子要定义在前面先渲染
<div class="container">
<div class="middle">
<p>这是中间的盒子</p>
</div>
<div class="left">
<p>这是左边的盒子</p>
</div>
<div class="right">
<p>这是右边的盒子</p>
</div>
</div>
1.1 首先给cotainer
设置padding 撑开两边, 为两栏留出空间
.container {
padding-left: 200px;
padding-right: 150px;
}
得到下图
1.2. 给三个盒子都设置浮动, 给左右盒子定死宽度, 中间自适应, 同时清除浮动
/*清除浮动*/
.container::after {
content: "";
display: block;
clear: both;
}
.left, .right, .middle {
float: left;
}
.left {
width: 200px;
}
.right {
width: 150px;
}
.middle {
width: 100%;
}
如此可以得到下图, 中间盒子占了100%, 因此占据了整行, 左右两个盒子被挤到了下面
接下来的工作就是将左右两个盒子放到预留的位置上
1.3 利用负margin将左右盒子放置预留位置
还需要使用position: relative;
, 来辅助定位
.left, .right {
position: relative;
}
.left {
margin-left: -100%;
left: -200px;
}
.right {
margin-left: -150px;
right: -150px;
}
最终效果图
总样式
/* 公共样式 */
.container {
width: 800px;
border: 1px dashed #dedede;
}
.container::after {
content: "";
display: block;
clear: both;
}
.left {
width: 200px;
background: #2DB3E4;
}
.right {
width: 150px;
background: #F37EC1;
}
.middle {
width: 100%;
background: #81B6AE;
}
.left, .right, .middle {
float: left;
}
布局样式
.container {
padding-left: 200px;
padding-right: 150px;
}
.left, .right {
position: relative;
}
.left {
margin-left: -100%;
left: -200px;
}
.right {
margin-left: -150px;
right: -150px;
}
2. 双飞翼布局
既然有了圣杯布局,那么为什么提出双飞翼布局呢?
因为圣杯布局有缺陷,当屏幕尺寸变小,会发生下面的情况
双飞翼布局, 源于淘宝UED
双飞翼布局需要更改DOM结构
<div class="container">
<div class="middle">
<div class="main">
<p>这是中间的盒子</p>
</div>
</div>
<div class="left">
<p>这是左边的盒子</p>
</div>
<div class="right">
<p>这是右边的盒子</p>
</div>
</div>
在圣杯布局中, 是通过给父容器设置padding
, 用以给左右盒子留出空间
而在双飞翼布局中, 通过给中间的盒子中额外新增的div设置margin
,
布局样式
.main {
margin-left: 200px;
margin-right: 150px;
}
.left {
margin-left: -100%;
}
.right {
margin-left: -150px;
}
布局样式相对于圣杯布局简洁了不少, 不需要设置position: relative;
来辅助定位
公共样式
p {
margin: 0;
padding-bottom: 20px;
}
.container {
width: 800px;
border: 1px dashed #dedede;
}
.container::after {
content: "";
display: block;
clear: both;
}
.left {
width: 200px;
background: #2DB3E4;
}
.right {
width: 150px;
background: #F37EC1;
}
.middle {
width: 100%;
background: #81B6AE;
}
.left, .right, .middle {
float: left;
}