圣杯布局和双飞翼布局
我们希望有一种简单高效的三栏布局方式可以实现以下要求:
- 两边固定宽度,中间自适应
- 先加载中间的内容(因为两边是导航栏和广告栏,中间是内容区)
2006 年,圣杯布局在 Matthew Levine 的文章 In Search of the Holy Grail 中被提出。也许是因为当时该模板有效的解决了以上需求(“圣杯”象征“渴求之物”),又或者是因为将左右两栏定位到两侧的过程十分像杯把(圣杯有杯把吗?),它被命名为“圣杯”。
圣杯布局
通过为父元素设置左右padding
,然后利用浮动和负边距将左右两栏移动到适当位置,并使用相对定位调整左右两栏的位置。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.container {
padding: 0px 100px;
min-width: 300px;
overflow: hidden;
}
.left {
float: left;
position: relative;
left: -100px;
margin-left: -100%;
width: 100px;
height: 100px;
background-color: red;
}
.center {
float: left;
width: 100%;
height: 100px;
background-color: green;
}
.right {
float: left;
position: relative;
left: 100px;
margin-left: -100px;
width: 100px;
height: 100px;
background-color: blue;
}
</style>
</head>
<body>
<div class="container">
<div class="center"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>
缺点
- 某一列内容溢出时,三栏不是等高的。(进行等高布局解决)
- 中间栏的最小宽度不能小于左右两栏的宽度,否则左右两栏会掉到下一行。(设置 min-width 解决)
双飞翼布局
通过在中间栏内部添加一个内部容器,并为这个内部容器设置左右margin
来保留左右两栏的位置,同样利用浮动和负边距来实现三栏布局。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
body{
width: 100vw;
height: 100vh;
}
.container > div{
float: left;
}
/* 左 */
.left {
margin-left: -100%;
width: 100px;
height: 100vh;
background: red;
}
/* 中 */
.center {
width: 100%; /* 自适应 */
height: 100vh;
background: green;
}
.inner {
/* 防止中间的内容被覆盖 */
padding: 0 100px;
}
/* 右 */
.right {
margin-left: -100px;
width: 100px;
height: 100vh;
background: blue;
}
</style>
</head>
<body>
<div class="container">
<div class="center">
<div class="inner">中</div>
</div>
<div class="left">左</div>
<div class="right">右</div>
</div>
</body>
</html>
优点
- 双飞翼布局省去了很多 css,由于不使用定位,中间栏的最小宽度不再受限于左右两栏宽度。
缺点
- 双飞翼布局多加一层 dom 树节点,增加渲染树生成的计算量, dom 结构不如圣杯布局简单直观。
- 三列等高问题仍然要单独解决。