在 CSS 网格中使用位置粘性

127 阅读3分钟

在 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;
}

image.png 默认情况下,卡片将拉伸以匹配最大的卡片(右起第一张)。要覆盖该行为,我们需要将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 写的这篇很棒的文章。一定要读一读!