# 圣杯布局和双飞翼布局

  • 圣杯:中间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

参考链接 (opens new window)

本地参考

最后更新: 2/24/2026, 6:35:27 PM