直接写 td:first-child { width: 120px } 不生效,因 table-layout: auto 下浏览器按内容计算自然宽度,td 宽度无法约束整列;可靠方案是配合 table-layout: fixed、显式 table 宽度及 <col> 元素设置列宽。

为什么直接写 td:first-child { width: 120px } 不生效
因为浏览器默认用 table-layout: auto,它先扫描所有单元格内容算出“自然宽度”,再缩放整张表去适配容器。td:first-child { width: 120px } 只给第一个单元格盒模型设宽,不改变列级基准——第二行一个长 URL 就能把第一列撑开,完全失控。
<col> 必须配合 table-layout: fixed 和显式 width
真正锁定第一列的唯一可靠方式是用 <col>,但它不是“写了就起作用”。三个条件缺一不可:
-
<table>上必须有style="table-layout: fixed; width: 100%"(或具体像素值,如width: 800px) -
<colgroup>必须是<table>的直接子元素,且严格位于<thead>或第一行<tr>之前 - 第一列对应
<col style="width: 120px">,其余列用空<col>即可均分剩余空间
漏掉任意一条,<col> 都会被忽略。比如只加 table-layout: fixed 但没设 width,浏览器会 fallback 到“均分 100%”,而这个 100% 没参照系,结果还是飘。
多列均分时容易踩的坑
均分不是靠猜,而是靠计算和结构约束:
立即学习“前端免费学习笔记(深入)”;
- 列数必须和
<col>数量严格一致——动态列数得用 JS 插入对应数量的<col> - 如果用了百分比(比如
width: 33.33%),三列之和必须严格等于 100%,浮点误差会导致最后一列被压缩或溢出 -
<col>不支持fr单位,width: 1fr是无效写法,别抄 Grid 的语法 - 内容无空格(如长 URL、Base64 字符串)会撑破列宽,必须额外加
word-break: break-word或overflow: hidden控制
完整最小可行结构示例
<table style="table-layout: fixed; width: 100%;">
<colgroup>
<col style="width: 120px">
<col>
<col>
</colgroup>
<thead><tr><th>ID</th><th>名称</th><th>状态</th></tr></thead>
<tbody><tr><td>1</td><td>商品A</td><td>上架</td></tr></tbody>
</table>注意:这里第二、三列用空 <col>,它们会均分 100% - 120px 的剩余空间;如果父容器是 flex 容器,确保它给了明确宽度(比如 min-width: 600px),否则 width: 100% 会失效。



















