如何在CSS中制作 "升起窗帘 "的效果(附代码)

404 阅读4分钟

"拉起窗帘 "是我所说的一种效果,即背景在滚动时由深变浅,而上面的内容在处于粘性位置时也由浅变深。

这里有一个例子,我在一个真实的项目中使用了这种效果。

想知道它是如何做到的吗?我将带你到幕后,告诉你如何提高它,只用HTML和CSS。

让我们从HTML开始

我们要做的是一种简化的 "升起窗帘 "效果,就像这样。

Showing the raise the curtains effect from dark blue to wheat.

背景和文字在滚动元素上时都会改变颜色。

为了清楚起见,我把事情做得很简单,但我们可以用三个元素来完成这个任务。

<div class="curtain">
  <div class="invert">
    <h2>Section title</h2>
  </div>
</div>

首先,我们需要一个窗帘的容器,我们将给它一个.curtain 类。然后,在.curtain ,我们有一个.invert 子元素,它将作为我们的 "粘性 "框。最后,我们在这个盒子里有内容--在这个特定的例子中,有一个好的老式的<h2> 元素。

让我们来设置一些CSS变量

我们知道有三个值是我们预先需要的。让我们把它们做成CSS变量,这样就可以很容易地把它们写进我们的样式中,并在以后需要时轻松地改变它们。

  • --minh - 容器的高度
  • --color1 - 浅色
  • --color2 - 暗色
:root {
  --minh: 98vh;
  --color1: wheat;
  --color2: midnightblue;
}

拉开窗帘的时间

接下来,我们可以使用以下技术定义我们的.curtain 元素。

  • 一个linear-gradient ,用于 "分割 "背景
  • min-height 用于容器底部的额外空间

我们使用::after 伪元素来增加底部的额外空间。这样,我们的 "粘性 "内容在滚动经过::after 元素时,实际上会粘在容器上。这是个假象。

.curtain {
  /** create the "split" background **/
  background-image: linear-gradient(to bottom, var(--color2) 50%, var(--color1) 50%);
}

/** add extra space to the bottom (need this for the "sticky" effect) **/
.curtain::after {
  content: "";
  display: block;
  min-height: var(--minh);
}

制作粘性内容

接下来,我们需要使我们的内容变得 "有粘性",即当背景和文本交换颜色值时,它可以完美地坐在容器内。事实上,我们已经给了.curtain'的子元素一个.invert 类,我们可以用它作为粘性容器。

跟我说一下--这就是我们要做的事情。

  • position: sticky 和 ,定义了粘性和它所粘的地方。top
  • mix-blend-mode: difference 将 元素内的内容的颜色与 的背景梯度相融合。<h2> .curtain
  • display: flex 对内容进行居中展示。
  • min-height 定义容器的高度,并允许在底部有额外的空间。
  • color 设置 标题的颜色。h2

现在要把这些放到CSS代码中去!

.invert {
  /** make the content sticky **/
  position: sticky;
  top: 20px;

  /** blend the content with the contrast effect **/
  mix-blend-mode: difference;

  /** center the content **/
  display: flex;
  align-items: center;
  justify-content: center;
  
  /** set the minimum height of the section **/
  min-height: var(--minh);
}

h2 {
  /** set the color of the text **/
  color: var(--color1);
}

这里有许多事情要做,所以让我们逐一解释。

首先,我们有一个不言自明的粘性位置,以及用于帮助内容居中的flexbox。这没有什么新的或特别棘手的地方。

内容的高度是用CSS变量设置的,其值与.curtain::after 伪元素的高度值相同。

mix-blend-mode: difference 声明将我们的内容与背景融合在一起。difference 值很复杂,但你可以把它想象成倒置的文本颜色与背景的对比。这里有一个来自CSS-Tricks年鉴的不错的演示,展示了不同的 mix-blend-mode值。

CodePen嵌入回退

为了使混合工作,我们需要设置我们的标题的颜色。在这种情况下,我们要给--color1 变量分配一个浅色的值(wheat)。

遇到的问题

我在研究 "拉开窗帘 "效果的细节时遇到了一些问题。例如,如果你想在 "粘性 "内容中添加图片,要避免使用那些颜色颠倒时看起来不好看的图片。

另一个问题:没有办法在特定的子元素上设置mix-blend-mode: difference ,比如标题,同时避免对图像的影响。我发现有几个原因导致它不能工作,其中第一个原因是position: sticky 取消了混合。

当在容器上使用像transform: skewY 这样的东西来给事物添加一点 "倾斜 "时,情况也是如此。我怀疑其他的属性也不能很好地混合,但我没有走到那一步来找出哪些属性。

谢幕了!

我很喜欢构建这个组件,我总是喜欢只用HTML和CSS就能完成的事情,尤其是当它们在每个浏览器上都能顺利工作的时候。

会用它做什么?你是否有不同的方法来处理这样的 "升起窗帘 "效果?请在评论中告诉我!