滚动是我们每个人在网络上都会做的事情,它已经成为一种期望,甚至可能是一种习惯,就像刷牙一样。这可能是我们没有过多考虑设计滚动体验的原因——它是一个众所周知的基本功能。事实上,流行的“没有折叠”这句话源于人们知道如何滚动,并且不存在人们不会到达的任意线。
基于滚动的功能往往涉及一些定制的 CSS 和 JavaScript 组合。这是因为没有太多原生功能可用。但是,如果我们能够只使用 CSS 来完成一些事情呢?
例如,请看这个巧妙的 使用 CSS 创建的水平滚动条。我想做类似的事情,但要指示滚动区域而不是捕获连续滚动。换句话说,我不想在滚动时增加指示器的长度,我只想在到达页面的特定部分时增加长度。
像这样
我的计划是:每个区域都带有指示器,在到达屏幕顶部之前是无法检测到的。在那里,它通过更改颜色变得可见并粘贴到视窗顶部。
反向操作应该完全相反:当向上滚动屏幕时,指示器会跟随,将其伪装成肉眼无法察觉的状态。
这里有两个关键部分。第一个是指示器在接近屏幕顶部时更改颜色。第二个是指示器固定在屏幕顶部,只有当其所在的区域被向下滚动时才会下降。
第二个很容易做到:我们在元素上使用 position: sticky;
。当页面滚动时,粘性元素会粘贴到其父容器中屏幕上的特定位置。
这让我们回到了更改颜色。由于 HTML 文档的背景默认是白色,因此我将白色保留为演示的基色。这意味着指示器在基色之上时应该显示为白色,并在位于屏幕顶部指示器栏之上时变成其他颜色。

这就是 CSS 混合模式发挥作用的地方。它们为我们提供了许多选项来创建各种颜色混合。我将使用 overlay 值。这个值在本质上非常动态。我不会深入解释混合(因为 CSS-Tricks 年鉴 已经很好地完成了这项工作),但考虑到这个演示,我想说:当背景颜色为白色时,产生的前景颜色为白色;当背景颜色为其他颜色时,产生的颜色会更深或更浅,具体取决于它与之混合的颜色。
演示中的指示器停止点是黑色的。但是,由于混合,我们看到它们是白色的,因为它们位于白色背景上。当它们位于指示器容器元素之上时,该元素是可爱的紫色,我们看到一个深紫色的指示器停止点,因为我们正在将指示器停止点的黑色与指示器容器的紫色混合。
从 HTML 开始
<div id="passageWrapper">
<strong>Sections Scrolled ↴</strong>
<!-- Indicator container -->
<div id="passage"></div>
</div>
<!-- Indicator stop -->
<div class=passageStops></div>
<!-- First Section -->
<div class="sections">
<!-- Content -->
</div>
<!-- Another indicator stop -->
<div class="passageStops"></div>
<!-- Second Section -->
<div class="sections">
<!-- Content -->
</div>
<!-- Another indicator stop -->
<div class="passageStops"></div>
<!-- Third Section -->
<div class="sections">
<!-- Content -->
</div>
非常简单,对吧?最顶部有一个粘性容器,用于保存到达顶部的指示器。从那里,我们有三个内容部分,每个部分的顶部都有一个指示器,这些指示器会与指示器一起粘贴到顶部,并与指示器混合。
这是 CSS
.passageStops {
background-color: black; /* Each indicator stop is black */
mix-blend-mode: overlay; /* This makes it appear white on a white background */
width: 33.3%; /* Three sections total, so each section is one-third */
top: calc(1em + 3px);
}
#passage,
.passageStops{
height: 10px;
}
#passageWrapper,
.passageStops {
position: sticky; /* The container and stops should stick to the top */
z-index: 1; /* Make sure the indicator and stops stay at the forefront */
}
#passage {
background: violet; /* Will blend with black to make a darker violet indicator */
margin: 0 0 20px 0;
}
#passageWrapper{
background-color: white; /* Make sure we're working with white to hide indicator stops */
height: 40px;
top: 0px;
}
/* Each stop will shift one-third the width of the indicator container to cover the whole thing when the last section is reached. */
.passageStops:nth-child(4){ margin-left: 33.3%; }
.passageStops:nth-child(6){ margin-left: 66.6%; }
/* More styling, blah blah. */
指示器 (.passageStops
) 是黑色的。但是,overlay 混合模式使得它们在与下面的白色背景混合时看起来是白色的。由于有三个部分,每个指示器都占三分之一的宽度。
指示器具有 position: sticky;
和一个顶部距离值。这意味着指示器将在从屏幕顶部计算的位置到达时粘贴。发生这种情况时,看起来是白色的黑色指示器会与紫色指示器容器混合,使其看起来像是深紫色,代表页面上的新滚动位置。
反之亦然。当指示器失去其粘性位置时,它会从指示器栏的紫色背景移动到页面的白色背景,再次隐藏它……就像它从未存在过一样!
这是演示再次
就是这样。您可以通过使用非白色背景和另一种混合模式,或者为指示器栏或停止点设置渐变来进一步尝试。
非常聪明,我喜欢它!
足智多谋。感谢这篇文章。
这是一个很好的例子:https://codepen.io/MadeByMike/pen/ZOrEmr
这真的很酷!我在想你是否考虑过在每个部分(除了最后一个)而不是
.passageStops
div 上使用:after
伪选择器?或者这与 position sticky 不兼容?