一、前言
圣杯布局和双飞翼布局这道面试题我看过很多次了,每一次都以为自己看明白了, 结果一段时间不看还是忘记了,可能是我经历的面试层次太低,没有考到吧。。再就是平时开发中一般没有这种优化要求,用的比较少,今天就再次好好看看并总结如下:
二、由来
这部分摘自知乎CSS 圣杯布局和双飞翼布局的理解与思考
圣杯布局来源于文章In Search of the Holy Grail,而双飞翼布局来源于淘宝UED。虽然两者的实现方法略有差异,不过都遵循了以下要点:
- 两侧宽度固定,中间宽度自适应
- 中间部分在DOM结构上优先,以便先行渲染
- 允许三列中的任意一列成为最高列
- 只需要使用一个额外的
<div>
标签
三、实现圣杯布局
3.1. 整体思路
整体思路(面试中问道思路可以这样答):
圣杯布局的主要思路是利用左右padding
预留出左右两栏的空间, 在通过负margin + 定位
将左右两栏调整到预留的空间中
3.2 具体实现
3.2.1 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>圣杯布局</title> <link rel="stylesheet" href="./css/grail.css"> </head> <body> <header>这是标题</header> <main> <div class="main">这是内容</div> <div class="left">这是左侧的</div> <div class="right">这是右侧</div> </main> <footer>这是页脚</footer> </body> </html>
|
css代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| * { margin: 0; padding: 0; text-align: center; color: #fff; }
header, footer { background-color: #058ED2; height: 100px; line-height: 100px; }
main { 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 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>双飞翼布局</title> <link rel="stylesheet" href="./css/wings.css"> </head> <body> <header>这是标题</header> <main> <div class="main">这是内容</div> </main> <div class="left">这是左侧的</div> <div class="right">这是右侧</div> <footer>这是页脚</footer> </body> </html>
|
css源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| * { 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 { 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结构),但是代码更简洁,且不存在崩塌的问题