table { columns: 3 } 不生效,因为 <table> 使用表格格式化上下文(TFC),与 columns 要求的块级文本流冲突;强制 display: block 会破坏语义和结构,正确做法是转为 <ul> 或 grid 布局。

columns 不能直接用于 <table> 元素实现垂直分栏——浏览器会忽略该声明,因为 <table> 是原子替换元素,不支持 CSS 多列布局的文本流分栏机制。
为什么 table { columns: 3 } 不生效
根本原因是:<table> 的渲染模型与 columns 要求的「块级文本流」冲突。浏览器对 <table> 应用的是表格格式化上下文(TFC),它完全绕过常规的块流分栏逻辑。即使强制设 display: block,也会破坏表格语义和内部结构(如 <tr> 不再自动换行、<td> 高度塌陷),导致行列错位、边框断裂、表头错乱等不可控问题。
常见错误现象:column-count: 3 完全无视觉变化;加了 border 后发现容器高度为 0;调试时看到 <tbody> 内容被截断或堆叠在第一列。
- 不要给
<table>或其直接子元素(<thead>、<tbody>)设columns - 不要尝试用
display: block+columns“欺骗”浏览器——它会让<tr>变成普通块,失去行内盒行为,vertical-align失效,合并单元格(rowspan/colspan)彻底崩溃 - 若内容是纯数据列表(非真正语义化表格),应改用
<ul>或<div>+columns,而非硬套<table>
想让表格数据垂直分栏?先转成语义正确的流式结构
真正可行的路径是:放弃原生 <table>,把数据提取为扁平化列表,再用 columns 分栏。这不仅解决分栏问题,还提升可访问性与响应式适应力。
立即学习“前端免费学习笔记(深入)”;
实操建议:
- 服务端或 JS 将表格数据转为
<ul class="data-list"><li>{item}</li>...</ul>结构 - CSS 只需一行:
.data-list { columns: 3; column-gap: 1rem; } - 若需保留表头信息,可在每个
<li>内嵌套<dl>或<div class="row">模拟字段,避免用<table>套<table> - 注意:
columns按内容高度自动平衡,不是按行数均分——12 条数据在 3 列中可能分布为 4/4/4,也可能 5/4/3(取决于每项内容高度)
真要保表格语义?用 grid 替代 columns 实现“视觉等高列”
如果必须保留 <table> 标签(例如 CMS 输出、遗留系统),又需要类似分栏的横向展开效果,唯一可靠方案是用 display: grid 模拟列布局,但需重构 DOM 层级——把每列数据提为独立 <div> 块,而非依赖 <tr> 行结构。
示例结构:
<div class="table-grid"> <div class="col"><h3>姓名</h3><div>张三</div><div>李四</div></div> <div class="col"><h3>年龄</h3><div>25</div><div>31</div></div> <div class="col"><h3>城市</h3><div>北京</div><div>上海</div></div> </div>
CSS:
.table-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.5rem;
}
.col > div {
padding: 0.25rem 0.5rem;
border: 1px solid #ddd;
}
- 这种写法下,各列高度由最高项决定,天然等高
- 避免在
.col上设height或flex,否则干扰 grid 自动行高计算 - 若列数需响应式变化,用
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)),比 media query 切换column-count更稳定
最易被忽略的一点:所谓“表格分栏”,本质是混淆了「数据语义」和「展示形式」。浏览器不会帮你把二维表格强行掰成垂直流,它只尊重你写的结构。选对容器,比调一百个 hack 更省时间。



















