“拉开窗帘”是我对一种效果的称呼,这种效果在滚动时背景颜色从深色变为浅色,而顶部的內容在粘性定位时也从浅色变为深色。
这是一个我在 真实项目 中使用该效果的示例
想知道它是如何实现的吗? 我将带您深入了解幕后,并向您展示如何仅使用 HTML 和 CSS 来实现它。
让我们从 HTML 开始
我们正在制作的是一种简化的“拉开窗帘”效果,如下所示

为了清晰起见,我将内容保持简单,但我们可以用三个元素来构建它
<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
值
为了使混合效果生效,我们需要设置标题的颜色。在本例中,我们将浅色值 (wheat
) 分配给 --color1
变量。
“拉开窗帘”演示
注意事项
在制定“拉开窗帘”效果的细节时,我遇到了一些问题。例如,如果您想在“粘性”内容中添加图像,请避免使用在颜色反转时看起来不好的图像。这是一个我制作了一个简单的 SVG 和透明 PNG 图像的快速演示,它看起来不错。
另一个注意事项:无法在特定子元素(如标题)上设置 mix-blend-mode: difference
,同时避免对图像产生影响。我发现有几个原因导致它不起作用,首先是 position: sticky
会取消混合效果。
在容器上使用 transform: skewY
添加一点“倾斜”效果时也是如此。我怀疑其他属性与混合效果配合得不好,但我没有深入研究以找出是哪些属性。
这是一个不进行滚动的演示,它去除了有问题的属性
谢幕!
我很享受构建这个组件的过程,我总是喜欢用 HTML 和 CSS 就能完成一些事情,尤其是在它们在每个浏览器上都能流畅运行时。
您将用它做什么?您是否会采用不同的方法来实现类似的“拉开窗帘”效果?请在评论中告诉我!
这种效果最近非常火爆——很棒的文章和教程!更多滚动教程 < 我的投票
太聪明了!我原以为会加入一些 JavaScript,但真的没想到这是纯 CSS 实现的!
另外,还有一个很酷的想法:由于反转的文本往往会使字母稍微“发光”(解释),我想知道是否可以使用可变字体通过调整“GRAD”或“wght”轴来弥补这种发光效果……:-)