css 网格的粘性列问题
Sticky column issue with css grid
这是说明问题的代码笔:https://codepen.io/robertcooper_rc/pen/jOYbdbR
我正在使用 CSS 网格创建 table 布局。它运行良好,但我对网格中其中一列的 position: sticky
的行为有疑问。
我有一个水平滚动的 table,有 4 列,第一列是粘性的。
当我向右滚动时,第一列确实像预期的那样粘在左边。
但是,当滚动开始接近 table 水平 space 的末尾时,第一个不再保持其在 table 左边缘的粘性位置。
我注意到,如果我删除 <aside>
的 HTML 标记,粘滞列行为将按预期工作。但是,我需要 <aside>
存在。
关于如何在保持 DOM 结构的同时使用 CSS 解决此问题的任何想法?
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.container {
display: flex;
width: 300px;
padding: 0.5rem;
border: 1px solid red;
}
aside {
padding-right: 1rem;
width: 100px;
}
.table {
min-width: 0;
overflow: scroll;
}
.row {
display: grid;
grid-template-columns: repeat(4, 100px);
}
.col {
border: 1px solid black;
background: #eee;
}
.sticky {
position: sticky;
left: 0;
z-index: 1;
background: lightblue;
}
<div class="container">
<aside>
My aside
</aside>
<div class="table">
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
</div>
</div>
所以问题实际上出在.table
上的min-width
设置上。行末未定义宽度,这会影响 row-end.
处的粘性元素的行为
您会注意到,如果将 min-width: 0;
交换为 min-width: 100%;
,它会按照您的意愿运行,但是 table
会溢出到 .container
之外。
A stickily positioned element is treated as relatively positioned until its containing block crosses a specified threshold (such as setting top to value other than auto) within its flow root.
也就是说,滚动的元素需要有一个定义的宽度,这样粘性元素就知道保持粘性。
一个简单的解决方案是将所有 .table
元素嵌套在另一个具有已定义宽度的包装器中。我根据内容和容器的渲染宽度选择了300px
。
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.container {
display: flex;
width: 300px;
padding: 0.5rem;
border: 1px solid red;
}
aside {
padding-right: 1rem;
width: 100px;
}
.table {
min-width: 0;
overflow: scroll;
}
.row {
display: grid;
grid-template-columns: repeat(4, 100px);
}
.col {
border: 1px solid black;
background: #eee;
}
.sticky {
position: sticky;
left: 0;
z-index: 1;
background: lightblue;
}
.wrapper {
width: 300px;
}
<div class="container">
<aside>
My aside
</aside>
<div class="table">
<div class="wrapper">
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
</div>
</div>
</div>
这是说明问题的代码笔:https://codepen.io/robertcooper_rc/pen/jOYbdbR
我正在使用 CSS 网格创建 table 布局。它运行良好,但我对网格中其中一列的 position: sticky
的行为有疑问。
我有一个水平滚动的 table,有 4 列,第一列是粘性的。
当我向右滚动时,第一列确实像预期的那样粘在左边。
但是,当滚动开始接近 table 水平 space 的末尾时,第一个不再保持其在 table 左边缘的粘性位置。
我注意到,如果我删除 <aside>
的 HTML 标记,粘滞列行为将按预期工作。但是,我需要 <aside>
存在。
关于如何在保持 DOM 结构的同时使用 CSS 解决此问题的任何想法?
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.container {
display: flex;
width: 300px;
padding: 0.5rem;
border: 1px solid red;
}
aside {
padding-right: 1rem;
width: 100px;
}
.table {
min-width: 0;
overflow: scroll;
}
.row {
display: grid;
grid-template-columns: repeat(4, 100px);
}
.col {
border: 1px solid black;
background: #eee;
}
.sticky {
position: sticky;
left: 0;
z-index: 1;
background: lightblue;
}
<div class="container">
<aside>
My aside
</aside>
<div class="table">
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
</div>
</div>
所以问题实际上出在.table
上的min-width
设置上。行末未定义宽度,这会影响 row-end.
您会注意到,如果将 min-width: 0;
交换为 min-width: 100%;
,它会按照您的意愿运行,但是 table
会溢出到 .container
之外。
A stickily positioned element is treated as relatively positioned until its containing block crosses a specified threshold (such as setting top to value other than auto) within its flow root.
也就是说,滚动的元素需要有一个定义的宽度,这样粘性元素就知道保持粘性。
一个简单的解决方案是将所有 .table
元素嵌套在另一个具有已定义宽度的包装器中。我根据内容和容器的渲染宽度选择了300px
。
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.container {
display: flex;
width: 300px;
padding: 0.5rem;
border: 1px solid red;
}
aside {
padding-right: 1rem;
width: 100px;
}
.table {
min-width: 0;
overflow: scroll;
}
.row {
display: grid;
grid-template-columns: repeat(4, 100px);
}
.col {
border: 1px solid black;
background: #eee;
}
.sticky {
position: sticky;
left: 0;
z-index: 1;
background: lightblue;
}
.wrapper {
width: 300px;
}
<div class="container">
<aside>
My aside
</aside>
<div class="table">
<div class="wrapper">
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
<div class="row">
<div class="col sticky">Col 1</div>
<div class="col">Col 2</div>
<div class="col">Col 3</div>
<div class="col">Col 4</div>
</div>
</div>
</div>
</div>