我正在尝试在 React 中创建一个可重用的 Table 组件,该组件具有粘性列(水平滚动时(,带有display: grid
和position: sticky
。
我在Chrome中开始实现,一切都按预期工作,所以我检查了Firefox和Safari组件在那里的工作方式。不幸的是,Firefox和Safari处理position: sticky
的方式与Chrome不同。
例:
为了简洁起见,这里有一个Codepen,可以在其中检查问题。
我发现了什么:
为了进行测试,我使表中的第一列和最后两列具有粘性。我发现Firefox将最后两列的th
和td
元素渲染为position: absolute
。
每当我将表格大小调整为较小的宽度时,表格的scrollWidth
(应该是所有列width
的总和(和clientWidth
(应该是table
元素的width
(在Firefox 上是相同的,在Chrome 上是不同的值。
例如:
// Firefox & Safari
table.scrollWidh = 657
table.clientWidth = 657
// Chrome
table.scrollWidth = 800
table.clientWidth = 657
TBH,我不确定我是否同时在Firefox和Safari中发现了一个错误,或者我现在应该信任哪个浏览器。或者我的实现中缺少一个 CSS 属性。
你遇到过这个吗?如果我错过了什么,你有提示吗?
终于,我能够解决问题。该解决方案需要一些JS修改。
问题是在Firefox和Safari上,table
元素的scrollWidth
不包含列的宽度,该列具有position: sticky
CSS规则.
为了解决这个问题,我在table
中引入了一个::before
伪元素。 样式定义现在如下所示:
table {
...
position: relative;
}
table::before {
position: absolute;
top: 0;
left: 0;
height: 100%;
z-index: -1;
}
我计算所有列宽度的总和并将其应用于伪元素。
之后,scrollWidth
也将在Firefox和Safari上具有正确的值。
不幸的是,这个问题没有纯粹的CSS解决方案。幸运的是,无论如何我都必须测量列宽,因为我需要它们来获得正确的left
和right
值。