一、前言
圣杯布局和双飞翼布局这道面试题我看过很多次了,每一次都以为自己看明白了, 结果一段时间不看还是忘记了,可能是我经历的面试层次太低,没有考到吧。。再就是平时开发中一般没有这种优化要求,用的比较少,今天就再次好好看看并总结如下:
二、由来
这部分摘自知乎CSS 圣杯布局和双飞翼布局的理解与思考
圣杯布局来源于文章In Search of the Holy Grail,而双飞翼布局来源于淘宝UED。虽然两者的实现方法略有差异,不过都遵循了以下要点:
- 两侧宽度固定,中间宽度自适应
- 中间部分在DOM结构上优先,以便先行渲染
- 允许三列中的任意一列成为最高列
- 只需要使用一个额外的
<div>
标签
三、实现圣杯布局
3.1. 整体思路
整体思路(面试中问道思路可以这样答):
圣杯布局的主要思路是利用左右
padding
预留出左右两栏的空间, 在通过负margin + 定位
将左右两栏调整到预留的空间中
3.2 具体实现
3.2.1 源码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>圣杯布局</title>
<link rel="stylesheet" href="./css/grail.css">
</head>
<body>
<!-- 为了熟悉语义化标签,这里使用header,和div效果一样 -->
<header>这是标题</header>
<main>
<div class="main">这是内容</div>
<div class="left">这是左侧的</div>
<div class="right">这是右侧</div>
</main>
<footer>这是页脚</footer>
</body>
</html>
css代码:
* {
margin: 0;
padding: 0;
text-align: center;
color: #fff;
}
header,
footer {
background-color: #058ED2;
height: 100px;
line-height: 100px;
}
main {
/* 通过左右padding预留出左右两栏的位置 */
padding: 0 300px 0 200px;
position: relative;
}
main::after {
content: "";
display: block;
clear: both;
}
.main,
.left,
.right {
float: left;
}
.main {
height: 400px;
line-height: 400px;
background-color: #ccc;
width: 100%;
}
.left {
height: 200px;
width: 200px;
line-height: 200px;
background-color: #55007f;
margin-left: -100%;
position: relative;
left: -200px;
}
.right {
height: 300px;
width: 300px;
line-height: 300px;
background-color: #55aa7f;
margin-left: -300px;
position: relative;
left: 300px;
}
3.3.2 效果
思考1:为什么要包裹一层main标签?
思考2:圣杯布局在宽度缩小到一定程度时,页面结构会崩塌,这是为什么
四、实现双飞翼布局
4.1 双飞翼布局存在的意义
圣杯布局已经解决了三栏的问题, 为什么淘宝UED还要提出双飞翼布局?具体见上面思考2
4.2 整体思路
双飞翼布局通过主体区域左右margin预留出左右两栏的空间,在通过负margin
将两栏移动到预留出的空白实现
4.3 实现
4.3.1 源码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>双飞翼布局</title>
<link rel="stylesheet" href="./css/wings.css">
</head>
<body>
<!-- 为了熟悉语义化标签,这里使用header,和div效果一样 -->
<header>这是标题</header>
<main>
<div class="main">这是内容</div>
</main>
<div class="left">这是左侧的</div>
<div class="right">这是右侧</div>
<footer>这是页脚</footer>
</body>
</html>
css源码
* {
margin: 0;
padding: 0;
text-align: center;
color: #fff;
}
header,
footer {
background-color: #058ED2;
height: 100px;
line-height: 100px;
}
main {
width: 100%;
float: left;
}
.left,
.right {
float: left;
}
/* 为main设置外边距,预留左右两侧空间 */
.main {
margin: 0 300px 0 200px;
height: 500px;
line-height: 500px;
background-color: #55557f;
}
.left {
width: 200px;
height: 200px;
background-color: #00ACED;
line-height: 200px;
margin-left: -100%;
}
.right {
height: 400px;
width: 300px;
margin-left: -300px;
background-color: #111111;
line-height: 400px;
}
footer {
clear: both;
}
4.3.2 效果
五、总结
圣杯布局和双飞翼布局各有各的优点和长处,具体还是根据业务需求来选择(脱离业务谈技术选型无异于扯淡)
圣杯布局当页面无限缩放时页面结构会崩塌,且利用margin和定位,代码更复杂,但代码结构更符合语义化规范
双飞翼布局代码不符合语义规范,可读性较差(中间三栏本应该在同级,且三栏的父级应该和头尾同级;而实现时除了主体都属于一级,主体属于子级,具体查看双飞翼布局的dom结构),但是代码更简洁,且不存在崩塌的问题