HTML 中的 `<colgroup>` 和 `<col>` 表格列样式/结构。
colgroup 是列容器、col 是单列句柄,可按列统一下发样式
<colgroup> 和 <col> 是 HTML 表格里唯一能「按列」统一下发样式的元素:写一次,整列生效,不用给几十个 <td> 挨个加 class。但它们不渲染任何可见内容、不能有子内容,浏览器真正认账的 CSS 属性只有四个——border、background、width、visibility,其余写了也没用。
<colgroup> 和 <col> 有什么区别?
结论:<colgroup> 是列的容器,<col> 是单列的句柄;colgroup 用 span 一次管多列,col 一列一个(也可以用 span 管连续几列)。
结构规则有三条硬性约束:
<colgroup>必须是<table>的直接子元素,位置在<caption>之后、<thead>/<tbody>/<tfoot>/<tr>之前;<col>只能作为<colgroup>的子元素,它是空元素(void element,指没有内容和结束标签的元素),不能包文字或其他标签;- 两者都支持
span属性,取值是 1–1000 的整数,默认 1。注意:<colgroup>一旦写了span,就不能再包含<col>子元素——这是 HTML 规范的内容模型规定,写了属于无效标记。
哪些 CSS 属性写在 <col> 上才有效?
结论:CSS 2.1 §17.5.1 明确列出列盒(table-column box)适用的属性只有 border、background、width、visibility 四个,margin、padding、height、display 一律不生效。
color、font-size、text-align 这类可继承属性,在现代浏览器里会沿盒树继承到单元格,实际能用;但它们属于「继承」而不是「列样式」,兼容性不如上面四个稳。
实践建议:宽度和背景写在 <col>/<colgroup> 上,边框、内边距、对齐方式仍然写回 th/td——因为单元格背景的绘制层级高于列背景,td 上的 background 会盖掉 col 的。
怎么用 <col> 给表格整列设宽度和背景?
结论:把列宽和高亮交给 <col>,表格主体只留数据,结构最干净。下面这份代码可以直接复制:
<table class="score">
<colgroup>
<col class="c-name">
<col span="2" class="c-score">
<col class="c-op">
</colgroup>
<thead>
<tr><th>姓名</th><th>语文</th><th>数学</th><th>操作</th></tr>
</thead>
<tbody>
<tr><td>张三</td><td>92</td><td>88</td><td>编辑</td></tr>
</tbody>
</table>
.score { table-layout: fixed; width: 100%; }
.c-name { width: 160px; background: #f7f7f9; }
.c-score { background: #fffdf3; } /* span="2",语文+数学两列同时生效 */
.c-op { width: 80px; }
关键一步是 table-layout: fixed。默认的 auto 布局下,col 的 width 只是「建议宽度」,内容一长列就被撑开;换成 fixed 后,列宽严格按第一行和 <col> 的宽度分配,超过就换行或溢出。另外,<col> 数量少于实际列数时,剩余列保持默认样式,不会报错。
colspan/rowspan 会让 <col> 对错列吗?
结论:<col> 是按「表格网格的列序号」生效,不是按单元格生效,所以合并单元格会让视觉对应关系变复杂。
具体表现:一个 colspan="2" 的单元格会同时吃到它覆盖的两列的背景;一个 rowspan="2" 的单元格会占用后续行的那一列,导致下面几行的单元格实际落列位置后移。排查「背景串列」时,先数合并跨度,再看 <col> 的书写顺序是否和网格列一一对应。
想整列隐藏,可以写 col { visibility: collapse },它会把列从布局中移除(不是留空白),Firefox 支持最早,Chrome 需要较新版本;若要兼容老浏览器,用 JS 按列号给对应 td/th 加隐藏类更稳。
一句话收束:<colgroup> 管列的分组、<col> 管一列或多列的宽度与背景,能生效的属性就 border、background、width、visibility 四个,配上 table-layout: fixed 才能让列宽说到做到,其余样式老老实实写回单元格。
转载请注明出处,版权归原作者所有。