使用 CSS 指示页面滚动位置

Avatar of Preethi
Preethi

DigitalOcean 为您的旅程的每个阶段提供云产品。立即开始使用 200 美元的免费积分!

滚动是我们每个人在网络上都会做的事情,它已经成为一种期望,甚至可能是一种习惯,就像刷牙一样。这可能是我们没有过多考虑设计滚动体验的原因——它是一个众所周知的基本功能。事实上,流行的“没有折叠”这句话源于人们知道如何滚动,并且不存在人们不会到达的任意线。

基于滚动的功能往往涉及一些定制的 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; 和一个顶部距离值。这意味着指示器将在从屏幕顶部计算的位置到达时粘贴。发生这种情况时,看起来是白色的黑色指示器会与紫色指示器容器混合,使其看起来像是深紫色,代表页面上的新滚动位置。

反之亦然。当指示器失去其粘性位置时,它会从指示器栏的紫色背景移动到页面的白色背景,再次隐藏它……就像它从未存在过一样!

这是演示再次

就是这样。您可以通过使用非白色背景和另一种混合模式,或者为指示器栏或停止点设置渐变来进一步尝试。