您无法将 position: sticky;
应用于 <thead>
。也不能应用于 <tr>
。但您可以将 position: sticky;
应用于 <th>
,这意味着您 *可以* 在普通的 <table>
中创建固定标题。这很棘手,因为如果您不知道这个奇怪的怪癖,很难责怪您。将固定定位应用于表格标题等父元素比将固定定位应用于每行中的单个元素更有意义。
问题归结于这样一个事实,即粘性需要 position: relative
来工作,而 在 CSS 2.1 规范中不适用于 <thead>
和 <tr>
。
如果您需要实现固定表格标题,但不知道 <th>
的解决方法,那么对此有两种非常极端的反应。
- 完全不要使用表格标记。 相反,使用不同的元素 (
<div>
等) 和其他 CSS 布局方法来复制表格的样式,但不会被锁定在使用position: relative
和创建position: sticky
父元素。 - 使用表格元素, 但使用新的
display
值完全删除所有默认样式。
第一个方法很危险,因为您没有使用语义化和可访问的元素来读取和导航内容。第二个方法几乎相同。您可以选择这条路线,但需要 非常小心地重新应用语义 角色。
无论如何,如果您坚持使用 <th>
元素的 sticky
值,那么所有这些都不重要。
查看示例
使用 CSS 的固定表格标题 by Chris Coyier (@chriscoyier)
在 CodePen 上。
在表格中间将表格标题作为一行可能有点奇怪,但这只是为了说明这个想法。我设想的是用不同颜色的标题栏来区分不同运动队的球员。
每当我想到数据表格时,我也会想到如何使它们具有响应性。幸运的是,有很多方法,所有方法都取决于以最佳方式对数据进行分组和探索。
我的老 cukpu 正在寻找一个支持这种表格的插件。因为我使用的是 Excel
提醒一下各位:不要忘记为
th
元素添加scope
属性。此外,为固定元素定义一个
top
(或bottom
) 属性 (我已经数不清多少次因为没有设置这个属性而无法理解为什么它不起作用了 ♂️)。太棒了。如果现在可以固定第一列就好了 ;O)
这是我的解决方案,它还可以使第一列固定。
我复制了各种表格元素的 outerHTML 部分,并将它们放到 “sticky” 表格元素的 innerHTML 中。演示的源代码在 GIT 上 https://github.com/napengam/sticky
还有一个演示来可视化效果,位于 http://hgsweb.de/sticky/html/index.html
此致
我不得不在工作中这样做。我有一个表格,包含任意数量 (从 5 列到 30 多列)。他们希望标题固定,第一列也固定。我唯一能使其生效的方法是将 4 个表格合并在一起,使其看起来像一个表格。“表格标题”实际上是在一个带有 overflow: hidden 的 div 中的两个表格。当水平滚动时,我必须将非固定列的表格沿与滚动相反的方向进行平移,以伪造水平滚动。第二组表格位于 “表格标题” 下方,最小高度为 60vh。这使得标题看起来是固定的,但实际上它只是滚动看起来像 “表格行” 的内容。同样,我必须在 y 轴上匹配固定列的平移,以进行滚动。制作起来很麻烦,经过几个月的审批和测试版,项目所有者突然不喜欢表格有自己的垂直滚动,甚至不记得他们多么渴望拥有第一个固定列。唉。
对于第一个选项,您可以使用其他元素并使用 ARIA 来应用语义和角色。这是一个示例 - https://www.w3.org/TR/wai-aria-practices/examples/table/table.html.
此技术有优缺点,因此应进行彻底测试,但该选项是可行的。这将更容易使其具有响应性。
这对于无边框单元格来说效果不错,但对于带边框的固定
<th>
来说,各种浏览器存在问题,尤其是在border-collapse:collapse
的情况下。我发现的最佳解决方法是使用border-collapse:separate
和border-spacing:0
,然后仅在每个<th>
和<td>
的两侧 (例如顶部/左侧) 设置边框。Edge 还有其他问题。添加此代码会有所帮助,但在滚动时边框仍然会消失在内容后面。
浏览器供应商真的需要在这方面达成一致,让我们能够将固定定位应用于
<thead>
(去他妈的规范)!并确保边框在这样做的时候表现正常!很好地概述了如何实现这种外观。
我很好奇是否有一些技巧可以处理使用固定定位的半透明对象。我在以前的项目中发现,所有标题都保留在最 “最近” 成为固定的标题下方 (或在某些情况下,在最 “最近” 成为固定的标题上方)。我加深了半透明度,它提供了可以接受的对比度以阻止来自下方文本的渗透,但看起来仍然很糟糕,并且使标题周围的阴影变得非常强烈。也许可以像
sticky-displace
这样,带有over
、under
和push
选项?当标题被固定时,是否有一个伪类?如果我们可以使用 css 仅在标题被固定时添加阴影,那就太好了。
非常感谢,你简直救了我的工作!
在 Firefox 中可以工作!
您还需要指定一个高度才能使它生效。我使用了 max-height 属性。
如果我为表格容器设置 overflow-x: auto,则固定定位无效。
嗨,Chris,感谢您的文章。如果我需要将两个标题固定到顶部 - 一个在另一个下方,我该怎么办?用例:- 第一个标题包含静态值,但第二个标题 (在第一个标题下方) 包含可以应用于所有行的值 - 例如下拉选择、复选框 (选择所有行)、输入值。简而言之,第二个标题就像对一列的 “全部应用” 功能。如果表格的其余部分是可滚动的,如何将这两行标题固定到顶部。
干得好!对于简单的应用来说,这是一个很好的修复方法。
如何使前两行标题固定?
在 Safari 浏览器版本 15 中无法使用。
我将我的代码修改为使 thead -> 标题固定在顶部,而 tbody 标题覆盖其他 tbody 标题。
使用
如果您想替换两个固定标题,可以为 tr 添加一个类,以区分哪个是哪个。
示例 https://codepen.io/stephen-george-west/pen/rNpjXYL