粘性元素主要用于在整个滚动过程中保持某些内容显示在屏幕上。虽然这很酷,但我们也可以用同样的方式隐藏元素!
这是一个典型的(嗯)粘性情况
查看 CodePen 上 Preethi Sam (@rpsthecoder) 编写的 position:sticky (CSS)。
粘性元素 (position: sticky;
) 与固定元素 (position: fixed;
) 非常相似,因为它们都可以在用户向上或向下滚动页面时保持其在屏幕上的位置。区别在于,粘性元素仍然局限于其所在的父容器。将上面粘性示例与这个使用固定元素实现相同概念的示例进行比较
查看 CodePen 上 CSS-Tricks (@css-tricks) 编写的 position:sticky (CSS)。
假设我们希望创建一种效果,即元素在滚动时滑入或滑出视图 - 有点像视差。例如,一个滑出的标题和一个滑入的页脚

好吧,猜猜怎么着?我们可以用粘性元素做到这一点!
查看 CodePen 上 Preethi Sam (@rpsthecoder) 编写的 使用“position:sticky”实现滑入和滑出效果。
我们怎么做呢?很高兴你问。让我们分解一下。
HTML 设置
在我们的示例中,有三个粘性元素
- 第一个是类别标题,一旦到达屏幕顶部,它就会滑到文章正文下方。
- 第二个是文章标题,它始终显示在屏幕顶部,而内容正文在滚动时会消失在其后面(这是典型的粘性元素行为)。
- 第三个元素是页脚,它会从文章中滑出,并在文章滚动到某个阈值以上时显示。
让我们看看它是如何实现的。这是我们正在使用的 HTML…基本上是两篇文章
<article>
<div class="category">Category Header</div>
<h1 class="title">Article 1 Title</h1>
<p>Body content would go here.</p>
<!-- More content -->
<div class="footer">
<p>Article 1 Footer</p>
</div>
</article>
<article>
<div class="category">Category Header</div>
<h1 class="title">Article 2 Title</h1>
<p>Body content would go here.</p>
<!-- More content -->
<div class="footer">
<p>Article 2 Footer</p>
</div>
</article>
粘性 CSS
.category
、.title
和 .footer
元素将获得 position:sticky;
以及一个放置属性,用于说明在滚动时它们将在屏幕上的哪个位置开始“粘贴”。
.category,
.title,
.footer {
position: -webkit-sticky; /* Required for Safari */
position: sticky;
height: 50px;
}
.category {
top: 0;
}
.title {
top: 0;
}
.footer {
bottom: 100px;
z-index: -1;
}
除了样式设置外,我对粘性元素没有做太多操作。它们已经完成了它们需要做的事情:粘贴到屏幕上。剩下的就是创建一个覆盖层和一些空间,以便元素在页面滚动时进入和离开。
可能有很多方法可以在文章上创建粘性元素可以在页面上通过并隐藏在其下的覆盖层 - 我使用了background-image
。
article {
background-image: linear-gradient(
to bottom,
transparent 50px,
#F5A623 50px,
#F5A623 calc(100% - 50px),
transparent 0
);
margin: auto auto 50px auto;
}
背景线性渐变应用于文章,从上到下运行,从50px
的透明度开始,并以50px
处的硬停止进行颜色更改。calc
部分?这就是我告诉颜色继续但底部保留50px
的方式。然后我们再次变为透明。这意味着我们在顶部和底部有两个50px
的透明条纹,高度相等,与类别标题和页脚的高度匹配。

类别标题和文章页脚是滑入和滑出文本的元素,因此它们的高度决定了渐变顶部和底部的透明条纹的长度。
这一切是如何结合在一起的呢?类别标题和文章标题的顶部与视口顶部对齐时,都会粘贴到屏幕上。标题叠加在类别标题之上,当它开始粘贴到视口顶部时,会完全隐藏类别标题。
至于页脚,它已经粘贴在距离屏幕底部100px
的位置(在文章边界内),但你不会看到它,因为它被使用z-index:-1
推到了内容后面。一旦我们滚动到文章背景的最后一个透明条纹的开头,它就会可见。
.footer {
bottom: 100px;
margin: 50px auto auto auto;
z-index: -1;
}
因为类别标题只是内容,除了文本本身之外没有其他东西可以隐藏,所以最好为最后一个粘性元素(页脚)设置50px
的顶部边距(以保持一致),这样在滚动时你就不会看到它隐藏在类别标题后面。
就是这样!
现在,当然,您希望使其成为自己的风格并进行更改,例如尺寸、元素数量和内容类型。关键是创建那些允许您的粘性元素隐藏在其后并在通过时显示的覆盖层 - 再一次,可能有很多不同的方法来实现这一点,但我使用了渐变中的透明条纹。
什么,另一个例子?当然!
这是一个使用水平滚动(和水平渐变)的另一个示例,它可能非常适合将此概念应用于移动设备
查看 CodePen 上 Preethi Sam (@rpsthecoder) 编写的 使用粘性元素实现水平滑入和滑出效果。
看到当一篇文章离开视口时食物是如何显示的,然后当下一篇文章经过时又是如何隐藏的吗?
相同的 HTML 设置
<article>
<div class="title">Article 1 Title</div>
<p>Article content goes here.</p>
<img class="image" src="/path/to/revealed/image.png">
</article>
<article>
<div class="title">Article 2 Title</div>
<p>Article content goes here.</p>
<img class="image" src="/path/to/revealed/image.png">
</article>
我将使用我的线性渐变解决方案来创建覆盖层,这次从左到右应用,以适应水平滚动
article {
background-image: linear-gradient(
to right,
transparent 50px,
#F5A623 50px,
#F5A623 calc(100% - 50px),
transparent 0
);
}
.title,
.image {
position: sticky;
position: -webkit-sticky;
z-index: -1;
width: 50px;
}
.title {
left: 20px;
margin-right: 52px;
}
.image {
left: 150px;
}
再次注意,我们使用的是与之前相同的两个 50px 透明条纹 - 唯一的区别是我们将其应用于宽度而不是高度。
这两个粘性元素(标题和图像)都将在文章下方和穿过文章。因此,为了避免在滚动期间它们重叠,标题获得了一个等于图像宽度(为 50px,Chrome 中额外增加 2px 以获得更清晰的线条)的右侧边距。
以下是发生的情况:当我们水平滚动时,标题粘贴在距离屏幕左侧边缘 20px 的位置,图像粘贴在距离相同边缘 150px 的位置。因为它们都具有z-index: -1;
,所以它们将消失在文章(也就是背景渐变)下方 - 当它们穿过渐变的纯色部分时会被隐藏,并通过透明条纹显示。
好的,再举一个例子
在结束之前,让我再向您展示一个启发这篇文章的例子。它是一个在滚动时显示的网站页脚。很久以前,我第一次在Ryan Seddon 的网站上看到了这个设计。

这种设计通常是使用一个“固定”的页脚,并在页面末尾留出一些空间让它出来,使用边距。我认为如果固定元素可以对整个页面执行此操作,那么粘性元素可能可以对单个元素执行类似的操作 - 因此我得出了目前为止的想法。
因此,我们可以使用到目前为止介绍的粘性技术来实现相同的效果。
首先,我们的 HTML
<main>
<h1>Site Title</h1>
<p>Site content</p>
</main>
<footer>
Site Footer
</footer>
html {
background-color: #fff;
}
body {
background-image: linear-gradient(
to top,
transparent 60px,
#fff 60px,
#fff 0
);
}
footer {
position: -webkit-sticky;
position: sticky;
bottom: 0;
height: 50px;
padding: 5px 0;
z-index: -1;
}
查看 CodePen 上 Preethi Sam (@rpsthecoder) 编写的 使用“position:sticky”实现页面页脚滑出。
正文上的粘性页脚和背景渐变可以解决问题。
我一直在尝试使用粘性元素和 z-index 将其放置在滚动背景元素之上,并使用 css-grid 将所有内容绑定在一起,其中父容器包含粘性元素和滚动元素。这一切在 html/css 中都运行良好,并且在转换为 react 或 vue 时仍然运行良好。但是,如果我尝试在 react 或 vue 中将事物分解成组件,统一的 css-grid 就会崩溃。我想这更多是一个 css-grid 问题,而不是“粘性”元素问题。抱歉。如果您有任何关于如何在 css-grid 父容器中跨多个 react 或 vue 组件使 css-grid 正常工作的建议,请告诉我。我想要使用组件的原因是为了能够按组隐藏/显示或加载/删除内容,并执行其他 react/vue 的优秀操作,这些操作使用组件更有意义。与 css-grid 相关的 css 都在一个文件中,并导入到各个组件文件中。我认为问题可能是 CSS-grid api 中缺少 CSS-grid 子网格,但我不确定。我希望这一切都说得通。谢谢:Jim
由于此效果需要将显示的元素堆叠在下方并使用负的 z-index,因此它会使元素无法访问指针事件。对于图形/装饰之类的东西,这并非一定是一个重大问题,但如果我理解正确,则该元素不能包含交互式元素,例如链接/按钮。您是否有允许交互的实现?例如,显示一个选项工具栏会非常酷。
您的想法呢?
将父容器的
z-index
设置为 0 或更大,并将position
设置为relative
。搞定!嗨,James - 现在我得到了之前显示的元素,它渲染在 section body 的顶部,这违背了整个目的。我是否误解了什么?
可惜的是,Divi 主题自定义 CSS 验证器不支持 position: sticky;