CSS 教程 / CSS 表格:边框、尺寸与 table-layout

CSS 表格布局根据表格的尺寸规则和内容分配列空间。table-layout: auto 考虑单元格内容,而固定布局在表格具有明确宽度时可以使列的尺寸更可预测。

区分表格宽度和单元格内边距

table { width: 100%; border-collapse: collapse; }

th, td { padding: 12px; border: 1px solid #aaa; text-align: start; }

width: 100% 告诉表格根据其父元素的宽度来调整自身大小。单元格内部的空间设为 padding,边框设为 border。border-collapse: collapse 是通过合并相邻单元格的边框来显示边框的一种方法。设置表格的宽度和在内容中设置换行是分开的。

设置 width: 100% 的表格并不保证始终容纳在父元素内。不可换行的内容或较大的最小宽度可能导致实际表格或单元格内容更宽。在典型的数据表中,让单元格高度根据句子长度增长是安全的。如果设置了固定高度,则需要在放大文本或添加内容时检查是否被截断。

根据内容分配列

<colgroup>
  <col style="width: 30%;">
  <col style="width: 70%;">
</colgroup>

该练习将简短的项目名称和长描述分成两列。示例采用 30:70 的比例,为说明列保留更多空间。如果实际数据包括日期、价格、长描述等,请根据每列的角色进行分配。如果默认的自动布局足够可读,则无需强行设置比例。

当指定整个列的百分比时,如下所示,请将总和设置为100%。不要将colgroup宽度声明视为在任何情况下都强制执行的最终结果。自动布局与内容的最小尺寸和表格计算共同作用。MDN:colgroup。

比较自动布局和固定布局

值 列宽计算 长内容中需要检查的事项
table-layout: auto 基于单元格内容计算 长值可能导致表格或列变得很大。
table-layout: fixed 使用指定的表格宽度、列宽和首行宽度等。 后面的单元格中的长内容可能会溢出或被截断

固定表格布局需要指定表格宽度;width: auto 并不会产生预期的固定计算效果。在这里,两个表格都使用 width: 100% 并且具有相同的列组,仅在 table-layout 上有所不同。如果单元格截断文本,请单独检查其换行和省略条件。参见 MDN:table-layout, CSS 溢出、长文本换行和省略。

以下数据包含我们希望显示而不换行的长预订代码。完整示例将 nowrap·hidden·ellipsis 同样应用于两个表格的此单元格。自动布局可以扩展以反映长值的空间,而 fixed 布局配合省略规则,可以在给定列宽内显示缩略文本。原始文本在单独的段落中完整提供,因此您也可以查看截断的代码。

项目 说明
您需要的物品 带上水瓶和舒适的鞋子。
预订代码 GARDEN-VISIT-RESERVATION-2026-ABCDEFGHIJKLMNOPQRSTUVWXYZ
参观信息 即使长信息句子跨越多行,单元格高度也会增加以适应内容。

在窄屏幕上滚动表格区域

.table-scroll { overflow-x: auto; }

table { width: 100%; min-width: 32rem; }

如果你的根字体大小是16px,那么32rem就是512px。如果屏幕上的可用宽度小于这个值,表格将保持其最小宽度,只有父容器区域会横向滚动。这必须与整个页面横向滑动区分开来。练习中的32rem只是用于比较这两列的目的,并不意味着所有表格的最小宽度。检查小屏幕是否被截断,并可以根据「使用宽度、缩放和键盘测试检查响应式CSS」项目进行操作。

如果你的表格较小且仍然可读,你可以降低或移除最小宽度。相反,压缩多个列和长值可能会让它们难以阅读。根据实际数据确定语义列是否可以缩短、通过换行解决,或者是否需要水平移动。在移动端,像“你可以水平移动”这样的提示会很有帮助。

可滚动的容器具有 tabindex="0"、role="region"、一个描述性无障碍名称和可见的焦点轮廓。使用 Tab 键进入其中,然后使用方向键到达最后一列。不需要滚动的表格不自动需要额外的 Tab 停止点。参见 MDN:overflow。

运行完整的表格比较

将以下代码写入 tables.html ,以 UTF-8 编码保存并用浏览器打开。两个表格使用相同的三行和相同的 30:70 列比例,所以你可以比较不同布局之间的差异。预约代码是用于布局练习的虚拟数据。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Table sizes and long content</title>
  <style>
    body { margin: 16px; color: #333; font: 16px/1.6 sans-serif; }
    .table-scroll { max-width: 640px; overflow-x: auto; margin-block: 16px; }
    .table-scroll:focus-visible { outline: 3px solid #9b5d00; outline-offset: 3px; }
    table { width: 100%; min-width: 32rem; border-collapse: collapse; }
    th, td { padding: 12px; border: 1px solid #aaa; text-align: start; }
    .auto { table-layout: auto; }
    .fixed { table-layout: fixed; }
    .token { font-family: monospace; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .original { max-width: 640px; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>Automatic and fixed table layout</h1>
  <h2>table-layout: auto</h2>
  <div class="table-scroll" role="region" aria-label="Auto Batch Comparison Table" tabindex="0"><table class="auto"><colgroup><col style="width: 30%;"><col style="width: 70%;"></colgroup><thead><tr><th scope="col">item</th><th scope="col">explanation</th></tr></thead><tbody><tr><th scope="row">What to bring</th><td>Bring a water bottle and comfortable shoes.</td></tr><tr><th scope="row">reservation code</th><td class="token">GARDEN-VISIT-RESERVATION-2026-ABCDEFGHIJKLMNOPQRSTUVWXYZ</td></tr><tr><th scope="row">Visitor Information</th><td>Even if long information sentences span multiple lines, the cell height is increased to match the content.</td></tr></tbody></table></div>
  <h2>table-layout: fixed</h2>
  <div class="table-scroll" role="region" aria-label="Fixed batch comparison table" tabindex="0"><table class="fixed"><colgroup><col style="width: 30%;"><col style="width: 70%;"></colgroup><thead><tr><th scope="col">item</th><th scope="col">explanation</th></tr></thead><tbody><tr><th scope="row">What to bring</th><td>Bring a water bottle and comfortable shoes.</td></tr><tr><th scope="row">reservation code</th><td class="token">GARDEN-VISIT-RESERVATION-2026-ABCDEFGHIJKLMNOPQRSTUVWXYZ</td></tr><tr><th scope="row">Visitor Information</th><td>Even if long information sentences span multiple lines, the cell height is increased to match the content.</td></tr></tbody></table></div>
  <p class="original">Full reservation code: GARDEN-VISIT-RESERVATION-2026-ABCDEFGHIJKLMNOPQRSTUVWXYZ</p>
</body>
</html>
  1. 缩小窗口并检查两个表格的宽度。根字体为 16px 时,fixed 表格的最小宽度为 512px,而自动表格可以更宽以反映更长的代码。两个表格都应该在其包裹区域内水平移动,而不是在整个页面上移动。
  2. 使用 Tab 键移动到固定表格区域,并使用右箭头键检查最后一列。在小屏幕上,还可以检查是否可以用手指水平移动。比较完成后,手动将滚动位置恢复到最左侧。
  3. 将 .fixed 中的 table-layout 改为 auto。检查在相同数据下列和表格宽度的变化后,将其恢复为 fixed。
  4. 将 .token 的 white-space 改为 normal,并添加overflow-wrap: anywhere。检查长代码是否换行以增加单元格高度,然后恢复到原来的声明。
  5. 将列比例改为40:60。比较短条目列的间距与描述列中的换行情况。将其恢复到原来的30:70,并在大屏幕和放大文本下检查。

如果比例看起来不如预期,请检查表格布局以及指定的表格宽度、最小宽度和长字符串的换行条件。如果水平移动不起作用,请确保将 overflow-x 指定在包裹表格的父元素上,而不是表格本身。如果你选择缩写单词,你应该能够在其他地方阅读重要的原始文本。