# 圣杯布局和双飞翼布局
圣杯:中间padding+左侧margin-left&position+右侧margin-right
双飞翼:
多一个div包裹,中间元素margin+左侧margin-left+右侧margin-left两侧宽度固定,中间宽度自适应
中间部分在DOM结构上优先,以便先行渲染
允许三列中的任意一列成为最高列
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>圣杯布局 - 完整实现</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-width: 650px;
/* 防止布局挤压变形 */
}
#header,
#footer {
height: 60px;
line-height: 60px;
text-align: center;
background: #333;
color: white;
}
/* 核心容器:设置padding为左右栏预留空间 */
#container {
padding-left: 200px;
/* 左栏宽度 */
padding-right: 150px;
/* 右栏宽度 */
overflow: hidden;
background: yellow;
}
#container::before {
content: "";
position: absolute;
left: 200px;
/* padding-left的值 */
top: 0;
bottom: 0;
width: 2px;
background: red;
z-index: 100;
}
/* 三栏共用样式 */
#container .column {
float: left;
position: relative;
height: 300px;
text-align: center;
color: white;
font-size: 12px;
}
/* 中间栏 - 优先渲染 */
#center {
width: 100%;
background: #2ecc71;
/* 绿色 */
opacity: 0.5;
overflow-y: auto;
}
/* 左侧栏 */
#left {
width: 200px;
background: #3498db;
/* 蓝色 */
opacity: 0.5;
/* 圣杯布局核心步骤 */
margin-left: -100%;
/* 1. 左移一整行,与center左对齐 */
left: -200px;
/* 2. 再左移自身宽度,进入padding区域 */
/* right: 200px 建议使用left负值,更加语义化*/
}
/* 右侧栏 */
#right {
width: 150px;
background: #9b59b6;
/* 紫色 */
opacity: 0.5;
/* 圣杯布局核心步骤 */
margin-left: -150px;
/* 1. 左移自身宽度,使其贴到center右侧 */
right: -150px;
/* 2. 再右移自身宽度,进入padding区域 */
}
#footer {
clear: both;
/* 清除浮动影响 */
}
/* 响应式:在小屏幕上恢复流式布局 */
@media (max-width: 768px) {
body {
min-width: auto;
}
#container {
padding: 0;
}
.column {
float: none;
width: 100% !important;
position: static;
margin: 0 !important;
left: 0 !important;
right: 0 !important;
}
#center {
order: 1;
}
#left {
order: 2;
}
#right {
order: 3;
}
}
</style>
</head>
<body>
<div id="header">页头 - 圣杯布局演示</div>
<div id="container">
<!-- 注意HTML顺序:中间内容在前,利于SEO和移动端 -->
<div id="center" class="column">1 -
中间内容区(自适应宽度)中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来中间栏有很多文字内容,会显示出来显示出来显示出来
</div>
<div id="left" class="column">2 - 左侧边栏(固定200px)</div>
<div id="right" class="column">3 - 右侧边栏(固定150px)</div>
</div>
<div id="footer">页脚 - 布局高度自适应</div>
</body>
</html>
以下写法并非传统的圣杯布局,而且存在高度塌陷问题,仅作参考
<style>
*{
margin:0;
padding:0
}
#container {
padding-left: 200px;
padding-right: 150px;
}
#container .column {
float: left;
}
#center {
width: 100%;
background:greenyellow
}
#left {
width: 200px;
/* 相对于父级的100% */
/* 本来应该和center同一排,以为center占满了 */
/* 现在掉下去后又忘往左移,超过宽度就挤上去了 */
/* 正好和center左侧重合 */
margin-left: -100%;
position: relative;
/* 再往左移动200px */
right: 200px;
background: skyblue;
}
#right {
width: 150px;
/* 相当于宽度在后来的div完全遮盖,虽然没有后面div不过可以这么理解 */
/* 没有了宽度,自然可以和center同一排 */
margin-right: -150px;
background: mediumvioletred;
}
#footer {
clear: both;
}
</style>
<div id="header">header</div>
<div id="container">
<div id="center" class="column">1</div>
<div id="left" class="column">2</div>
<div id="right" class="column">3</div>
</div>
<div id="footer">footer</div>
<style type="text/css">
body {
min-width: 500px;
}
#container {
width: 100%;
}
.column {
float: left;
}
#center {
margin-left: 200px;
margin-right: 150px;
background:green
}
#left {
width: 200px;
margin-left: -100%;
background: #00D6B2;
}
#right {
width: 150px;
margin-left: -150px;
background: indianred
}
#footer {
clear: both;
}
</style>
<body>
<div id="header"></div>
<div id="container" class="column">
<div id="center">1</div>
</div>
<div id="left" class="column">2</div>
<div id="right" class="column">3</div>
<div id="footer"></div>
<body>
不考虑兼容性,可直接用flex或者计算属性来代替,也可以左右两部分定位,中间给百分比宽度,padding:0 x px
← @import&link css设计模式 →