CSS 多列布局(Multi-column Layout)让你可以将内容分成多列显示,类似报纸或杂志的排版效果。这是一种自动处理内容分布的布局方式,特别适合长文本的阅读体验。
基本概念#
多列布局会自动将内容在列之间分配:
.multi-column { column-count: 3;}内容会自动从第一列流到第二列,再到第三列。
定义列数#
column-count#
指定固定列数:
.two-columns { column-count: 2;}
.three-columns { column-count: 3;}
.four-columns { column-count: 4;}column-width#
指定列的理想宽度:
.auto-columns { column-width: 300px; /* 浏览器会根据容器宽度自动计算列数 */}🎯 column-width 是最小宽度,实际宽度可能更大以填满容器。
columns 简写#
.columns { /* column-width column-count */ columns: 300px 3;
/* 只设置列数 */ columns: 3;
/* 只设置宽度 */ columns: 300px;
/* 自动 */ columns: auto;}响应式列数#
.responsive-columns { /* 列宽至少 250px,列数自动 */ columns: 250px auto;}
/* 或使用媒体查询 */.articles { column-count: 1;}
@media (min-width: 640px) { .articles { column-count: 2; }}
@media (min-width: 1024px) { .articles { column-count: 3; }}列间距与分隔线#
column-gap#
设置列之间的间距:
.gapped { column-count: 3; column-gap: 40px;}
/* 使用相对单位 */.relative-gap { column-count: 3; column-gap: 2em;}column-rule#
在列之间添加分隔线:
.ruled { column-count: 3; column-rule: 1px solid #e5e7eb;}
/* 分开设置 */.ruled-detailed { column-rule-width: 2px; column-rule-style: dashed; column-rule-color: #3b82f6;}column-rule 语法与 border 相同:
.rules { column-rule: 1px solid #ccc; column-rule: 2px dashed #3b82f6; column-rule: 3px dotted rgba(0, 0, 0, 0.2);}🎯 分隔线不占用空间,显示在 column-gap 的中间。
内容填充#
column-fill#
控制内容如何在列之间分配:
.balanced { column-fill: balance; /* 默认:尽量平均分配 */}
.sequential { column-fill: auto; /* 按顺序填充,可能不平均 */}/* balance 需要固定高度才能看出效果 */.fixed-height { height: 400px; column-count: 3; column-fill: balance;}
.auto-fill { height: 400px; column-count: 3; column-fill: auto; /* 第一列填满后才填第二列 */}跨列元素#
column-span#
让元素跨越所有列:
.full-width { column-span: all;}
.normal { column-span: none; /* 默认 */}.article { column-count: 3; column-gap: 40px;}
.article h2 { column-span: all; text-align: center; margin: 2rem 0;}🔶 column-span 只支持 all 或 none,不能指定具体列数。
断列控制#
break-inside#
控制元素内部是否断列:
.no-break { break-inside: avoid; /* 避免在元素内部断列 */}
.allow-break { break-inside: auto; /* 默认:允许断列 */}break-before / break-after#
控制元素前后的断列:
.break-before { break-before: column; /* 在元素前强制断列 */}
.break-after { break-after: column; /* 在元素后强制断列 */}
.avoid-break-before { break-before: avoid-column; /* 避免在元素前断列 */}实用断列控制#
/* 卡片不断开 */.card { break-inside: avoid;}
/* 标题和内容不分开 */h2,h3 { break-after: avoid;}
/* 图片说明不分开 */figure { break-inside: avoid;}实战案例#
报纸风格文章#
.newspaper-article { column-count: 3; column-gap: 40px; column-rule: 1px solid #d1d5db; text-align: justify;}
.newspaper-article h1 { column-span: all; text-align: center; font-size: 2.5rem; margin-bottom: 1.5rem; padding-bottom: 1rem; border-bottom: 2px solid #1f2937;}
.newspaper-article h2 { column-span: all; font-size: 1.5rem; margin: 2rem 0 1rem;}
.newspaper-article p { margin-bottom: 1rem; line-height: 1.7;}
.newspaper-article p:first-of-type::first-letter { font-size: 4rem; float: left; line-height: 1; margin-right: 0.5rem; color: #3b82f6;}卡片瀑布流#
.card-waterfall { column-count: 3; column-gap: 20px;}
.card-waterfall .card { break-inside: avoid; margin-bottom: 20px; padding: 20px; background: white; border-radius: 12px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);}
/* 响应式 */@media (max-width: 1024px) { .card-waterfall { column-count: 2; }}
@media (max-width: 640px) { .card-waterfall { column-count: 1; }}图片画廊#
.gallery { column-count: 4; column-gap: 16px;}
.gallery-item { break-inside: avoid; margin-bottom: 16px;}
.gallery-item img { width: 100%; border-radius: 8px; display: block;}
.gallery-item figcaption { padding: 8px 0; font-size: 0.875rem; color: #6b7280;}术语列表#
.glossary { column-count: 2; column-gap: 48px; column-rule: 1px solid #e5e7eb;}
.glossary dt { font-weight: 600; color: #1f2937; break-after: avoid;}
.glossary dd { margin: 0 0 1.5rem 0; color: #4b5563; break-inside: avoid;}时间线#
.timeline { column-count: 2; column-gap: 60px; column-rule: 2px solid #3b82f6;}
.timeline-item { break-inside: avoid; position: relative; padding: 20px; margin-bottom: 20px;}
.timeline-item::before { content: ''; position: absolute; width: 12px; height: 12px; background: #3b82f6; border-radius: 50%; top: 24px;}
/* 左列的点在右边 */.timeline-item:nth-child(odd)::before { right: -36px;}
/* 右列的点在左边 */.timeline-item:nth-child(even)::before { left: -36px;}菜单列表#
.menu { column-count: 2; column-gap: 48px;}
.menu-category { break-inside: avoid; margin-bottom: 32px;}
.menu-category h3 { font-size: 1.25rem; color: #1f2937; padding-bottom: 8px; border-bottom: 2px solid #3b82f6; margin-bottom: 16px; break-after: avoid;}
.menu-item { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px dotted #d1d5db;}
.menu-item-name { font-weight: 500;}
.menu-item-price { color: #3b82f6; font-weight: 600;}目录结构#
.toc { column-count: 2; column-gap: 40px;}
.toc-section { break-inside: avoid; margin-bottom: 24px;}
.toc-section h4 { font-size: 1rem; color: #1f2937; margin-bottom: 8px; break-after: avoid;}
.toc-section ul { list-style: none; padding: 0; margin: 0;}
.toc-section li { padding: 4px 0;}
.toc-section a { color: #4b5563; text-decoration: none;}
.toc-section a:hover { color: #3b82f6;}与其他布局配合#
多列 + Flexbox#
.flex-columns { display: flex; gap: 40px;}
.flex-columns > * { flex: 1; /* 每个 flex 子项内部使用多列 */ column-count: 2;}多列 + Grid#
.grid-with-columns { display: grid; grid-template-columns: 1fr 2fr; gap: 40px;}
.grid-with-columns .main { column-count: 2; column-gap: 24px;}浏览器兼容性#
多列布局支持良好:
| 浏览器 | 支持版本 |
|---|---|
| Chrome | 50+ |
| Firefox | 52+ |
| Safari | 10+ |
| Edge | 12+ |
部分旧浏览器需要前缀:
.columns { -webkit-column-count: 3; -moz-column-count: 3; column-count: 3;
-webkit-column-gap: 40px; -moz-column-gap: 40px; column-gap: 40px;}常见问题#
🤔 内容不平均分布?
确保使用 column-fill: balance(默认值)。如果容器有固定高度,检查内容是否过长导致溢出。
🤔 元素被截断?
对需要保持完整的元素添加 break-inside: avoid:
.card,figure,blockquote { break-inside: avoid;}🤔 多列布局 vs Grid/Flexbox?
- 多列布局:内容自动流动分配,适合文本和瀑布流
- Grid:精确的二维网格控制
- Flexbox:一维排列,适合导航、工具栏
🤔 图片高度不一致导致布局问题?
使用 break-inside: avoid 保持图片和说明不分离:
figure { break-inside: avoid; margin-bottom: 16px;}CSS 多列布局是实现报纸杂志风格排版的利器。它特别适合长文本阅读、瀑布流画廊、术语列表等场景。掌握断列控制可以确保内容的完整性和阅读体验。下一篇我们将学习用户交互相关的 CSS ��性。