在 CSS 网格中使用位置粘性
你有没有遇到过position: sticky网格容器的子容器没有按预期工作的情况?几天前,我正在帮助一位朋友解决那个确切的问题,并想最终写下它。
介绍
这个问题实际上并不是错误或错误。事实上,这是默认 CSS 行为的效果。为什么以及如何?让我们看看下面的例子。
<div class="wrapper">
<aside></aside>
<main></main>
</div>
.wrapper {
display: grid;
grid-template-columns: 250px minmax(10px, 1fr);
grid-gap: 1rem;
}
我们有一个网格,使旁边250px的宽度,其余的可用空间用于主要部分。很简单吧?

现在,我们要添加position: sticky到side 元素以使其在滚动时固定。
aside {
position: sticky;
top: 0;
}
哎呀。它不工作?这是为什么?让我们来了解一下。
默认行为 Align-Items
为side 元素添加背景将显示其高度等于主要部分。

这是align-items属性的默认行为。它默认为拉伸。结果,一列将在高度上拉伸以匹配网格中最大的列。
让我向您展示另一个有助于更好地说明问题的示例。我们有一个简单的网格容器。

.cards__list {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1rem;
}
默认情况下,卡片将拉伸以匹配最大的卡片(右起第一张)。要覆盖该行为,我们需要将
align-items值更改为start。
.cards__list {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1rem;
align-items: start;
}

回到最初的例子。为了显示这个问题,我在旁白部分添加了一个背景。尝试在以下演示中切换复选框并注意侧边栏高度如何变化。
为了使侧边栏具有粘性,我们需要覆盖默认的拉伸行为并使侧边高度等于内容。我们可以align-self在side 元素上使用:
aside {
align-self: start;
}
或者align-items在父项上使用,这将影响所有子项。
.wrapper {
display: grid;
grid-template-columns: 250px minmax(10px, 1fr);
grid-gap: 1rem;
align-items: start;
}
在两者之间进行选择取决于您的用例。您可能有两列以上,而您只想对齐其中的一列。
另一个例子
可以共享 CSS 网格的相同默认行为的一个非常相似的示例是团队列表页面。

在滚动时,我们希望“设计”保持固定,这样我们就可以确定当前的团队列表是针对“设计”的。如果不使用align-self: start标题,它将无法按预期工作。
.section {
display: grid;
grid-template-columns: 100px 1fr;
grid-gap: 2rem;
}
.section__headline {
position: sticky;
top: 1rem;
align-self: start;
}
结论
问题/问题是功能,而不是实际问题。这是一个 CSS 功能示例,我们的开发人员在某些情况下可能会从中受益,并覆盖到另一个值(就像在本文中一样)。
原来有一篇关于同一主题的文章(这就是网络社区的好处,就是从不同的声音中听到相同的主题,对吧?)。我发现了 Melanie Richards 写的这篇很棒的文章。一定要读一读!