CSS: 手搓12列栅格

栅格系统(Grid System)是网页布局中非常经典的方案——把一行分为若干列(通常是 12 列),通过组合不同的列宽实现多样化布局。Bootstrap 等框架的核心就是栅格系统。

1. 为什么是 12 列?

12 的因数很多:1、2、3、4、6、12,所以它能灵活组合:


2. 用 Flexbox 实现栅格

(1) 基本结构

▶ 示例

HTML 📖 仅展示
<style>
/* 行容器 */
.row {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -10px;  /* 抵消列的内边距 */
}

/* 通用列样式 */
[class*="col-"] {
  padding: 0 10px;   /* 列间距 */
  box-sizing: border-box;
}

/* 为可视演示添加背景色 */
.col-demo {
  background: #e3f2fd;
  border: 1px solid #90caf9;
  padding: 12px 0;
  text-align: center;
  margin-bottom: 8px;
  border-radius: 4px;
}

/* 12 列栅格 */
.col-1  { width: 8.333333%; }   /* 1/12 */
.col-2  { width: 16.666667%; }  /* 2/12 */
.col-3  { width: 25%; }         /* 3/12 */
.col-4  { width: 33.333333%; }  /* 4/12 */
.col-5  { width: 41.666667%; }  /* 5/12 */
.col-6  { width: 50%; }         /* 6/12 */
.col-7  { width: 58.333333%; }  /* 7/12 */
.col-8  { width: 66.666667%; }  /* 8/12 */
.col-9  { width: 75%; }         /* 9/12 */
.col-10 { width: 83.333333%; }  /* 10/12 */
.col-11 { width: 91.666667%; }  /* 11/12 */
.col-12 { width: 100%; }        /* 12/12 */
</style>
<div class="row">
  <div class="col-1"><div class="col-demo">1</div></div>
  <div class="col-2"><div class="col-demo">2</div></div>
  <div class="col-3"><div class="col-demo">3</div></div>
  <div class="col-4"><div class="col-demo">4</div></div>
  <div class="col-5"><div class="col-demo">5</div></div>
  <div class="col-6"><div class="col-demo">6(一半)</div></div>
  <div class="col-7"><div class="col-demo">7</div></div>
  <div class="col-8"><div class="col-demo">8</div></div>
  <div class="col-9"><div class="col-demo">9</div></div>
  <div class="col-10"><div class="col-demo">10</div></div>
  <div class="col-11"><div class="col-demo">11</div></div>
  <div class="col-12"><div class="col-demo">12(全宽)</div></div>
</div>
逻辑代码 45 行(超过 40 行限制,仅展示)

(2) HTML 使用

HTML
<!-- 三栏等宽:每列占 4 份 -->
<div class="row">
  <div class="col-4">占 4 列</div>
  <div class="col-4">占 4 列</div>
  <div class="col-4">占 4 列</div>
</div>

<!-- 两栏不对称:左 3 右 9 -->
<div class="row">
  <div class="col-3">占 3 列</div>
  <div class="col-9">占 9 列</div>
</div>

<!-- 四栏等宽:每列占 3 份 -->
<div class="row">
  <div class="col-3">占 3 列</div>
  <div class="col-3">占 3 列</div>
  <div class="col-3">占 3 列</div>
  <div class="col-3">占 3 列</div>
</div>

3. 添加响应式断点

让栅格在不同屏幕下有不同的列数:

▶ 示例

HTML
<style>
/* 手机:默认满宽 */
.col-sm-1  { width: 8.333333%; }
.col-sm-2  { width: 16.666667%; }
.col-sm-3  { width: 25%; }
.col-sm-4  { width: 33.333333%; }
.col-sm-6  { width: 50%; }
.col-sm-12 { width: 100%; }

/* 平板 */
@media (min-width: 768px) {
  .col-md-1  { width: 8.333333%; }
  .col-md-2  { width: 16.666667%; }
  .col-md-3  { width: 25%; }
  .col-md-4  { width: 33.333333%; }
  .col-md-6  { width: 50%; }
  .col-md-8  { width: 66.666667%; }
  .col-md-12 { width: 100%; }
}

/* 桌面 */
@media (min-width: 1024px) {
  .col-lg-1  { width: 8.333333%; }
  .col-lg-2  { width: 16.666667%; }
  .col-lg-3  { width: 25%; }
  .col-lg-4  { width: 33.333333%; }
  .col-lg-6  { width: 50%; }
  .col-lg-8  { width: 66.666667%; }
  .col-lg-12 { width: 100%; }
}
.media-demo { padding: 20px; background: #f0f0f0; border-radius: 8px; border: 1px solid #ddd; }
</style>
<div class="media-demo">Media demo</div>
▶ 试一试

(1) 响应式使用示例

HTML
<!-- 手机:堆叠显示;平板:两栏;桌面:四栏 -->
<div class="row">
  <div class="col-sm-12 col-md-6 col-lg-3">Col sm 12 col md 6 col lg 3</div>
  <div class="col-sm-12 col-md-6 col-lg-3">Col sm 12 col md 6 col lg 3</div>
  <div class="col-sm-12 col-md-6 col-lg-3">Col sm 12 col md 6 col lg 3</div>
  <div class="col-sm-12 col-md-6 col-lg-3">Col sm 12 col md 6 col lg 3</div>
</div>

4. 添加偏移类

有时候需要让列偏移,比如让内容居中:

▶ 示例

HTML
<style>
.col-offset-0 { margin-left: 0; }
.col-offset-1 { margin-left: 8.333333%; }
.col-offset-2 { margin-left: 16.666667%; }
.col-offset-3 { margin-left: 25%; }
.col-offset-4 { margin-left: 33.333333%; }
.col-offset-6 { margin-left: 50%; }
</style>
<div class="col-offset-0">无偏移列</div>
<div class="col-offset-1">偏移 1 列</div>
<div class="col-offset-2">偏移 2 列</div>
<div class="col-offset-3">偏移 3 列</div>
<div class="col-offset-4">偏移 4 列</div>
<div class="col-offset-6">偏移 6 列</div>
▶ 试一试
HTML
<!-- 让内容位于中间 -->
<div class="row">
  <div class="col-6 col-offset-3">
    这个内容占据中间6列,左右各偏移3列
  </div>
</div>

5. 完整的栅格系统

▶ 示例

HTML 📖 仅展示
<style>
/* ===== 栅格系统 ===== */
.row {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -10px;
}

[class*="col-"] {
  padding: 0 10px;
  box-sizing: border-box;
}

/* 12 列 */
.col-1  { width: 8.333333%; }
.col-2  { width: 16.666667%; }
.col-3  { width: 25%; }
.col-4  { width: 33.333333%; }
.col-5  { width: 41.666667%; }
.col-6  { width: 50%; }
.col-7  { width: 58.333333%; }
.col-8  { width: 66.666667%; }
.col-9  { width: 75%; }
.col-10 { width: 83.333333%; }
.col-11 { width: 91.666667%; }
.col-12 { width: 100%; }

/* 偏移 */
.col-offset-1  { margin-left: 8.333333%; }
.col-offset-2  { margin-left: 16.666667%; }
.col-offset-3  { margin-left: 25%; }
.col-offset-4  { margin-left: 33.333333%; }
.col-offset-6  { margin-left: 50%; }

/* 响应式 */
@media (min-width: 768px) {
  .col-md-1  { width: 8.333333%; }
  .col-md-2  { width: 16.666667%; }
  .col-md-3  { width: 25%; }
  .col-md-4  { width: 33.333333%; }
  .col-md-6  { width: 50%; }
  .col-md-8  { width: 66.666667%; }
  .col-md-12 { width: 100%; }
}

@media (min-width: 1024px) {
  .col-lg-1  { width: 8.333333%; }
  .col-lg-2  { width: 16.666667%; }
  .col-lg-3  { width: 25%; }
  .col-lg-4  { width: 33.333333%; }
  .col-lg-6  { width: 50%; }
  .col-lg-8  { width: 66.666667%; }
  .col-lg-12 { width: 100%; }
}
.media-demo { padding: 20px; background: #f0f0f0; border-radius: 8px; border: 1px solid #ddd; }
</style>
<div class="media-demo">Media demo</div>
逻辑代码 48 行(超过 40 行限制,仅展示)

6. 用 CSS Grid 实现栅格

也可以使用 Grid 来实现,更简洁:

▶ 示例

HTML
<style>
.grid-12 {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 20px;
}

.g-col-3  { grid-column: span 3; }
.g-col-4  { grid-column: span 4; }
.g-col-6  { grid-column: span 6; }
.g-col-8  { grid-column: span 8; }
.g-col-12 { grid-column: span 12; }
.grid-12-item {
  background: #e8f4f8;
  border: 1px solid #3498db;
  padding: 16px;
  margin: 4px;
  border-radius: 4px;
  text-align: center;
}
</style>
<div class="grid-12">
    <div class="grid-12-item">Grid 12 item</div>
    <div class="grid-12-item">Grid 12 item</div>
    <div class="grid-12-item">Grid 12 item</div>
</div>
▶ 试一试

❓ 常见问题

Q 为什么栅格系统都用 12 列?
A 12 能被 2、3、4、6 整除,组合最灵活。可以做出 1/2、1/3、1/4、1/6、2/3、3/4 等各种比例。Bootstrap 等主流框架都采用 12 列栅格,这已经成了事实标准。
Q 手写栅格和用 Bootstrap 的栅格有什么区别?
A 手写栅格能帮你理解原理,Bootstrap 的栅格是封装好的实现。实际项目直接用 Bootstrap 更高效,但理解原理后遇到框架不满足的场景,你也能自己写栅格系统。
Q Flex 版栅格和 Grid 版栅格哪个好?
A 各有利弊。Flex 版适合一维排列,但无法跨行对齐。Grid 版二维能力强,列与列之间可以对齐。如果只需要简单的行内列分配,Flex 版就够了;如果需要网格线对齐,用 Grid 版。

7. 常用布局模式

这是最常见的页面布局模式:

▶ 示例

HTML
<style>
.holy-grail {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar main aside"
    "footer footer footer";
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: 60px 1fr 40px;
  min-height: 100vh;
  gap: 10px;
}

.holy-grail-header { grid-area: header; background: #2c3e50; color: white; }
.holy-grail-sidebar { grid-area: sidebar; background: #34495e; color: white; }
.holy-grail-main { grid-area: main; background: #ecf0f1; }
.holy-grail-aside { grid-area: aside; background: #34495e; color: white; }
.holy-grail-footer { grid-area: footer; background: #2c3e50; color: white; }

.holy-grail-item {
  padding: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>
<div class="holy-grail">
  <header class="holy-grail-header holy-grail-item">Header</header>
  <aside class="holy-grail-sidebar holy-grail-item">Sidebar</aside>
  <main class="holy-grail-main holy-grail-item">Main Content</main>
  <aside class="holy-grail-aside holy-grail-item">Aside</aside>
  <footer class="holy-grail-footer holy-grail-item">Footer</footer>
</div>
▶ 试一试

(2) 瀑布流布局(Pinterest风格)

使用Grid实现简单的瀑布流效果:

▶ 示例

HTML
<style>
.masonry {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 15px;
  padding: 15px;
}

.masonry-item {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 8px;
  padding: 20px;
  color: white;
  break-inside: avoid;
}

.masonry-item:nth-child(2) { height: 150px; }
.masonry-item:nth-child(3) { height: 100px; }
.masonry-item:nth-child(5) { height: 180px; }
</style>
<div class="masonry">
  <div class="masonry-item">项目 1</div>
  <div class="masonry-item">项目 2</div>
  <div class="masonry-item">项目 3</div>
  <div class="masonry-item">项目 4</div>
  <div class="masonry-item">项目 5</div>
  <div class="masonry-item">项目 6</div>
</div>
▶ 试一试

(3) 仪表盘布局

使用Grid实现数据展示面板:

▶ 示例

HTML 📖 仅展示
<style>
.dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto;
  gap: 15px;
  padding: 15px;
  background: #f5f5f5;
}

.dashboard-card {
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.dashboard-card h3 {
  margin: 0 0 10px 0;
  font-size: 14px;
  color: #666;
}

.dashboard-card .value {
  font-size: 24px;
  font-weight: bold;
  color: #2c3e50;
}

.dashboard-card:nth-child(1) { border-left: 4px solid #3498db; }
.dashboard-card:nth-child(2) { border-left: 4px solid #2ecc71; }
.dashboard-card:nth-child(3) { border-left: 4px solid #e74c3c; }
.dashboard-card:nth-child(4) { border-left: 4px solid #f39c12; }
</style>
<div class="dashboard">
  <div class="dashboard-card">
    <h3>总用户数</h3>
    <div class="value">12,345</div>
  </div>
  <div class="dashboard-card">
    <h3>活跃用户</h3>
    <div class="value">8,901</div>
  </div>
  <div class="dashboard-card">
    <h3>转化率</h3>
    <div class="value">23.5%</div>
  </div>
  <div class="dashboard-card">
    <h3>收入</h3>
    <div class="value">$45,678</div>
  </div>
</div>
逻辑代码 48 行(超过 40 行限制,仅展示)
💡 布局要点: 圣杯布局用 grid-template-areas 定义区域,瀑布流用 repeat(3, 1fr) 均分列,仪表盘用固定列数展示数据卡片。

📖 小节

📝 作业

  1. 实现上面的完整 12 列栅格系统,创建一个 HTML 页面展示不同列组合的效果(如 3-3-3-3、4-4-4、2-8-2 等)。
  2. 使用响应式栅格,让一个页面在手机上显示单列、平板上显示两列、桌面上显示四列。
  3. 使用 col-offset-3 让一个内容块在页面中居中显示。
  4. 使用 Grid 版本重新实现上面的 12 列栅格,对比两个版本的代码差异。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏