多栏布局方案

两栏布局与三栏布局(圣杯、双飞翼)的实现方式

问题

实现常见的多栏布局:

  1. 两栏布局:左侧定宽,右侧自适应
  2. 三栏布局:左右定宽,中间自适应(圣杯布局、双飞翼布局)

解答

两栏布局

1. float + margin

.container {
  overflow: hidden; /* 清除浮动 */
}

.left {
  float: left;
  width: 200px;
  height: 300px;
  background: #f66;
}

.right {
  margin-left: 200px; /* 留出左侧空间 */
  height: 300px;
  background: #3cf;
}
<div class="container">
  <div class="left">左侧定宽</div>
  <div class="right">右侧自适应</div>
</div>

2. float + BFC

.left {
  float: left;
  width: 200px;
  height: 300px;
  background: #f66;
}

.right {
  overflow: hidden; /* 触发 BFC,不与浮动元素重叠 */
  height: 300px;
  background: #3cf;
}

3. Flex 布局

.container {
  display: flex;
}

.left {
  width: 200px; /* 或 flex: 0 0 200px */
  height: 300px;
  background: #f66;
}

.right {
  flex: 1; /* 占据剩余空间 */
  height: 300px;
  background: #3cf;
}

4. Grid 布局

.container {
  display: grid;
  grid-template-columns: 200px 1fr; /* 左侧200px,右侧自适应 */
}

.left {
  height: 300px;
  background: #f66;
}

.right {
  height: 300px;
  background: #3cf;
}

三栏布局

1. 圣杯布局

特点:DOM 结构中,中间内容在前(优先渲染),使用 padding 预留左右空间。

.container {
  padding: 0 200px; /* 为左右栏预留空间 */
  overflow: hidden;
}

/* 三栏都浮动 */
.center, .left, .right {
  float: left;
  height: 300px;
}

.center {
  width: 100%; /* 占满容器宽度 */
  background: #3cf;
}

.left {
  width: 200px;
  margin-left: -100%; /* 移动到上一行最左边 */
  position: relative;
  left: -200px; /* 再向左移动自身宽度 */
  background: #f66;
}

.right {
  width: 200px;
  margin-left: -200px; /* 移动到上一行最右边 */
  position: relative;
  right: -200px; /* 再向右移动自身宽度 */
  background: #fc3;
}
<div class="container">
  <div class="center">中间自适应</div>
  <div class="left">左侧定宽</div>
  <div class="right">右侧定宽</div>
</div>

2. 双飞翼布局

特点:中间栏套一层容器,用 margin 预留空间,不需要 position 定位。

.container {
  overflow: hidden;
}

.center, .left, .right {
  float: left;
  height: 300px;
}

.center {
  width: 100%;
  background: #3cf;
}

.center-inner {
  margin: 0 200px; /* 为左右栏预留空间 */
  height: 100%;
}

.left {
  width: 200px;
  margin-left: -100%; /* 移动到上一行最左边 */
  background: #f66;
}

.right {
  width: 200px;
  margin-left: -200px; /* 移动到上一行最右边 */
  background: #fc3;
}
<div class="container">
  <div class="center">
    <div class="center-inner">中间自适应</div>
  </div>
  <div class="left">左侧定宽</div>
  <div class="right">右侧定宽</div>
</div>

3. Flex 三栏布局

.container {
  display: flex;
}

.left {
  width: 200px;
  height: 300px;
  background: #f66;
}

.center {
  flex: 1;
  height: 300px;
  background: #3cf;
}

.right {
  width: 200px;
  height: 300px;
  background: #fc3;
}
<div class="container">
  <div class="left">左侧定宽</div>
  <div class="center">中间自适应</div>
  <div class="right">右侧定宽</div>
</div>

4. Grid 三栏布局

.container {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
}

.left {
  height: 300px;
  background: #f66;
}

.center {
  height: 300px;
  background: #3cf;
}

.right {
  height: 300px;
  background: #fc3;
}

关键点

  • 圣杯 vs 双飞翼:圣杯用 padding + position,双飞翼用额外容器 + margin,双飞翼更简单
  • 负 margin 原理margin-left: -100% 会让元素向左移动父容器宽度,回到上一行
  • BFC 特性:BFC 区域不会与浮动元素重叠,可用于自适应布局
  • 现代方案:Flex 和 Grid 更简洁,兼容性已足够好,优先使用
  • 中间优先渲染:圣杯和双飞翼的 DOM 结构让中间内容先加载,有利于 SEO 和用户体验