Knockout 文本 是一种技术,其中文字从元素中剪切出来,露出背景。 换句话说,您只能看到背景,因为字母会敲出洞。 它很有吸引力,因为它打开了我们在传统 CSS 属性(如 color
)中无法获得的排版样式。
虽然我们过去已经看到过 许多方法 来实现 knockout 文本,但现在我们可以使用一些现代 CSS 属性,甚至可以进一步增强效果,例如过渡和动画。 让我们看看它们在实际中的应用。
混合混合模式
有 四种混合模式 可以轻松地制作文本剪切:multiply
、screen
、darken
和 lighten
。 将这些应用于图像和文本堆栈的顶部元素(文本位于顶部)会创建 knockout 设计。
尽管在大多数情况下,在这些混合模式中使用黑色或白色来获得文本和背景之间的清晰区别,但我更喜欢使用更深或更浅的颜色,以保持背面图像稍微可见,如下所示
<div class="backdrop">
<p class="text">Taitō</p>
</div>
/* Background layer with an image */
.backdrop {
background: url("/path/to/image.jpg") center;
...
}
/* Dark foreground layer, with white text, set to "multiply" mix blend mode */
.text {
color: white;
background: rgb(59, 2, 6);
mix-blend-mode: multiply;
...
}
查看 CodePen 上 Preethi 的示例 CSS Knockout Text (@rpsthecoder)。
使用更深(或更浅)的颜色也会在显示在文本中的图像中创建一个不错的“主题”。
multiply 混合模式保持较深的颜色为深色,较浅的颜色则让后面的内容透过来:顶层上的黑色部分将完全不透明,而白色将完全透明。

multiply
混合混合模式的效果。在上面的示例中,白色文本变得完全透明,而它周围的较深颜色只让后面的图像略微可见,因为较深的阴影不受影响。
screen 混合模式颠倒了角色:较深的颜色会产生半透明,而较浅的阴影则保持明亮并阻止后面的内容。
darken 和 lighten 混合模式分别类似于 multiply 和 screen,除了在可见的背面图像的部分上会丢失细节。 这些模式不会混合阴影,而是选择显示的两个图层中的较深或较浅阴影。
请查看下方四种模式混合颜色的差异
/* Knockout text within a dark area */
.multiply {
color: white;
mix-blend-mode: multiply;
background-color: rgb(59, 2, 6);
}
/* Knockout text within a bright area */
.screen {
color: black;
mix-blend-mode: screen;
background-color: rgb(244, 220, 211);
}
/* Knockout text within a dark area that's less detailed */
.darken {
color: white;
mix-blend-mode: darken;
background-color: rgb(59, 2, 6);
}
/* Knockout text within a light area that's less detailed */
.lighten {
color: black;
mix-blend-mode: lighten;
background-color: rgb(244, 220, 211);
}
查看 CodePen 上 Preethi 的示例 CSS Knockout Text (@rpsthecoder)。
使用混合模式是获得 knockout 文本效果的最便捷选择,因为它允许我们应用其他技术可能不允许的额外样式。
让我们仔细看看可以用来增强 knockout 效果的样式。
阴影模糊
向文本添加白色/黑色或浅色/深色文本阴影会产生模糊效果。 例如,假设我添加了一个具有较大的模糊半径值的 text-shadow
.text {
text-shadow: 0 0 9px white;
...
}
现在边缘不再那么清晰,并会产生一种云状效果
查看 CodePen 上 Preethi 的示例 CSS Blurred Knockout Text (@rpsthecoder)。
动画
我们甚至可以稍微移动一下东西。 例如,让我们利用上面我们看到的 text-shadow
想法并在其上进行一些移动,使其看起来像是文本在发光
.text {
animation: glow 3s infinite;
...
}
@keyframes glow {
0% {
text-shadow: 0 0 10px white;
}
15% {
text-shadow: 2px 2px 10px rgba(255, 255, 255, 1),
-2px -2px 10px rgba(255, 255, 255, 1);
}
30% {
text-shadow: 2px 2px 4px rgba(255, 255, 255, .7),
-2px -2px 4px rgba(255, 255, 255, .7);
}
50% {
text-shadow: 20px 20px 50px rgba(255, 255, 255, .5),
-20px -20px 50px rgba(255, 255, 255, .5);
}
}
查看 CodePen 上 Preethi 的示例 CSS knockout Text Glow Animation (@rpsthecoder)。
过渡
过渡是我们可以应用于 knockout 文本的另一个属性,它打开了更多有趣的可能性,例如在伪类(如 :hover
)上使用 text-indent
。
以下是如何在伪类上使用过渡来将新元素引入 knockout 文本中
/* The knockout text */
.text {
transition: text-indent .5s;
...
}
/* On hover, trigger the transition */
.text:hover {
text-indent: 5px;
transition: text-indent .5s;
}
/* The thing that slides in on hover */
.text:hover::before {
display: inline-block;
content: '✈︎';
}
查看 CodePen 上 Preethi 的示例 CSS Knockout Text Transition (@rpsthecoder)。
背景剪裁
使用 text
值设置的 background-clip
CSS 属性将背景剪裁为其前景文本的形状。

background-clip: text
<p class="text">Taitō</p>
.text {
background: url("/path/to/image.jpg") center;
background-clip: text;
color: transparent;
...
}
查看 CodePen 上 Preethi 的示例 Knockout Text (@rpsthecoder)。
透明文本显示了它后面已经被剪裁成文本形状的图像。 虽然这是一种真正的 knockout 文本方法——它实际上删除了屏幕上文本周围的背景——但没有背景可以渗透或移动,这为其他效果(如模糊或移动文本)留下了很少的空间。 这就是 mix-blend-mode
占优势的地方。
CSS 遮罩
我们研究的第一个技术采用 遮罩,这是一种在前景层上创建形状并使用颜色来确定显示形状的多少的概念。 前景的黑色部分会隐藏(或“遮罩”),白色部分会显示背景,反之亦然。 黑色和白色之间的任何灰色值都会被视为不同程度的部分透明度。
CSS 遮罩的工作原理相同:您直接声明一个图像作为应用到另一个图像上的遮罩,并且根据遮罩的类型,我们会剪切一部分。 在撰写本文时,CSS 遮罩仅在 Firefox 中得到完全支持。
此浏览器支持数据来自 Caniuse,其中包含更多详细信息。 数字表示浏览器在该版本及更高版本中支持该功能。
桌面
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
120 | 53 | 否 | 120 | 15.4 |
移动设备/平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 127 | 15.4 |
由于我们专门关注 knockout 文本,因此遮罩需要由文本制成。 这是 SVG <mask>
的绝佳用途,它可以使用 SVG 形状和文本创建遮罩。
<div class="backdrop">
<p class="text"></p>
</div>
<svg>
<defs>
<mask id="m">
<rect width="100%" height="100%" fill="white" />
<text x="50%" y="75%" text-anchor="middle">Taitō</text>
</mask>
</defs>
</svg>
/* Background layer with an image */
.backdrop {
background: url("/path/to/image.jpg") center;
...
}
/* Dark foreground layer with masking applied */
.text {
background-color: rgba(59, 2, 6, 1);
mask-type: luminance;
/* Referrer to an SVG mask */
mask: url("#m");
...
}
svg {
width: 75vw;
height: 20vw;
}
/* SVG text inside the mask */
text {
font: bolder 12vw 'Alfa Slab One';
}
查看 CodePen 上 Preethi 的示例 Knockout Text (@rpsthecoder)。
前景元素的 mask-type
属性上的 luminance
值实现了遮罩机制,其中该图层的各个部分(对应于遮罩的黑色部分)变得透明。 对应于遮罩的白色部分的各个部分保持不透明。 mask
属性使用 url()
值来指定用于遮罩的 SVG 元素。
SVG 的 <mask>
元素会根据其内容创建一个遮罩图像。 我在 <mask>
中创建的内容是白色矩形 (<rect>
) 和黑色文本 (<text>
)。 文本为黑色,因此在遮罩后,它会将后面的图像部分显示出来。
模糊、动画和过渡
CSS 遮罩打开了与 mix-blend-mode
相同的模糊和动画效果。
之前我们用过的那个发光文本也适用于这里,这次直接应用于 SVG 的<text>
元素
text {
font: bolder 12vw 'Alfa Slab One';
animation: glow 3s infinite;
}
@keyframes glow {
0% {
text-shadow: 0 0 10px white;
}
15% {
text-shadow: 2px 2px 10px rgba(255, 255, 255, 1),
-2px -2px 10px rgba(255, 255, 255, 1);
}
30% {
text-shadow: 2px 2px 4px rgba(255, 255, 255, .7),
-2px -2px 4px rgba(255, 255, 255, .7);
}
50% {
text-shadow: 20px 20px 50px rgba(255, 255, 255, .5),
-20px -20px 50px rgba(255, 255, 255, .5);
}
}
然而,与mix-blend-mode
不同,并非所有相同的属性都可以动画化。例如,text-indent
在这里不起作用,transform
也不起作用。确实,CSS 变换可以应用于 SVG 元素,但由于我们的蒙版实际上以其最真实的形态用作蒙版,因此浏览器可能不会应用这些变换。
我们始终可以使用 JavaScript 插入transform
SVG 属性,将这些变换传递给蒙版内的元素
t = document.querySelector('text');
b = document.querySelector('.backdrop');
b.onmouseover = ()=>{
t.setAttribute('transform', 'translate(20)');
}
b.onmouseout = ()=>{
t.removeAttribute('transform');
}
结论
在浏览器支持和生产安全代码方面,CSS 蒙版由于仅限于 Firefox 支持而落后。本文中提到的混合模式在几乎所有主流浏览器中都受支持,除了 Edge。background-clip
属性也受所有浏览器支持,但仍需要-webkit
前缀。
在结果方面,混合模式和蒙版都提供了类似的输出。在background-clip
和mix-blend-mode
值之间,将是设计的选择导致选择一个而不是另一个。只要您使用的是与页面主体匹配的黑色或白色背景,就可以通过混合来实现使用background-clip
可以实现的内容。
TLDR;淘汰文本方法uno:将四种淘汰友好混合模式之一应用于文本图像堆栈的顶层,并在文本及其外壳上使用深色/浅色(或黑色/白色)颜色组合。方法dos:在包含背景图像和透明文本的元素中将background-clip
设置为text
。方法tres:在带有图像的实色前景上使用 CSS 蒙版,并使用 SVG 文本蒙版来指示剪切。
好消息!感谢分享!
我写了一篇关于这项技术的博客文章,包括我自己创建的一篇。
使用 CSS 背景图像进行文本剪切 https://pickjb.com/blog/text-clipping-with-css-background-images/
干得好!
这是一篇很棒的文章!感谢您使其清晰易懂,易于学习,并提供了大量示例。学到了很多!
太棒了!!!
非常有用!谢谢!