我最近遇到了带有空心/填充文本的运球/登陆页面概念。
首先,我不完全确定这个概念是否可以在 CSS 中重新创建。谷歌确实让我找到了 CSS 文本蒙版,但我找不到任何可以真正重现这种效果的帖子。
我如何能够重建空心/填充文本,具体取决于文本后面的背景是否有图像?
它可以用纯 HTML+CSS 完成(无需任何 SVG)。
我决定为 HTML+CSS 做这件事,因为我觉得这是一个挑战。
mask-image: element(#target)进一步简化,这意味着我们不需要仅遮罩文本,不幸的是 Chrome 似乎还不支持element()(但 Firefox 确实支持)。一个小问题是text-stroke轮廓与纯白色文本不完全对齐(至少在 Windows 10 上的 Chrome 中,我的计算机版本为Helvetica96dpi,但在同一浏览器和计算机中为 192dpi(2x,又名Retina ))看起来很完美。
以下是我的机器上 96dpi 下动画中不同点的外观:

下面的示例实现适用于以下浏览器(在撰写本文时):
body {
background-color: #dbdac2;
--solid-white: linear-gradient(white,white);
}
#container,
#container > #div1 {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-size:
153px 302px,
148px 302px,
154px 302px;
background-position:
131px 94px,
309px 28px,
480px 94px;
background-repeat:
no-repeat,
no-repeat,
no-repeat;
animation: moveImages 2s infinite;
animation-direction: alternate;
}
#container {
border: 1px solid white;
position: relative;
width: 711px;
height: 440px;
/* These are the 3 photo images, rendered as separate background-image layers: */
background-image:
url( "https://i.stack.imgur.com/hmwyh.png" ),
url( "https://i.stack.imgur.com/JeHEg.png" ),
url( "https://i.stack.imgur.com/pVgz6.png" );
}
#container p {
margin: 0;
position: static;
padding-top: 192px;
padding-left: 62px;
overflow: hidden;
font-family: Helvetica;
font-size: 99px;
letter-spacing: -2px;
font-weight: 600;
}
#container > #pStroke {
text-stroke: 1px white;
-webkit-text-stroke: 1px white;
color: transparent;
}
#container > #div1 {
/* #div1's background-image layers must match #container's: */
background-image:
var(--solid-white),
var(--solid-white),
var(--solid-white);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
@keyframes moveImages {
/* The `@keyframes from {}` rule is optional, btw. */
to {
background-size:
53px 302px,
58px 302px,
154px 302px;
background-position:
431px 94px,
209px 28px,
280px 194px;
}
}Run Code Online (Sandbox Code Playgroud)
<div id="container">
<div id="div1">
<p id="pWhite">Fashion Give<br />Impression.</p>
</div>
<p id="pStroke">Fashion Give<br />Impression.</p>
</div>Run Code Online (Sandbox Code Playgroud)
解释:
该div#container元素的background-image属性设置为 3 个不同的源图像(使用 meme 图像代替您发布的示例中的时尚照片)。
background-size和background-position属性独立定位和缩放。另一个元素 ( #div1)div#container通过absolute定位进行叠加,并具有相同的background-size和background-position属性,但使用单个纯白色背景图像(来自 a )而不是照片,然后使用的内部文本linear-gradient(white,white)遮盖这 3 个白色背景图像层。#div1<p>background-clip: text;
background-image: linear-gradient(或background-image: url("1x1px-white.png");) 而不是,background-color: white;因为它需要在 3 个单独的图层中重复,而background-color: white;不能用于定义背景内的矩形区域,也不能有多个 background-color图层(即使是半透明的)。#div1的<p>元素用于通过仅使用其内部padding而不是正确定位文本position: absolute;,因为不幸的是,定位的文本不能与 一起使用background-clip: text;。带有文本副本的另一个<p>元素用于描边文本(带有text-stroke: 1px white;)
虽然文本内容在 HTML 源中重复,但幸运的是,3 个图像(及其各自的白色蒙版)的更复杂的大小和位置信息不需要在 CSS 中重复;这要归功于 CSS 选择器的工作方式(因为#container和都由单个 CSS 规则设置#div1它们的background-size和属性)。background-position
可能的替代方法:
可以使用background-image单个(但非常复杂)clip-path跟踪 3 个框(就像蚀刻草图一样绘制的单线),而不是对纯白色部分使用重复的相同大小的图层#pWhite,但这不太可行。
我认为最好的方法是这样的:
<img />对 3 张照片使用 3 个独立的元素(而不是background-image),并absolute在新的<div id="images">.<p>(在 的同级元素中div#images)将被absolute-ly 定位在div#imagesby上z-index并用mask-image: element(#images);element()但据我所知,Chrome似乎不支持在HTML+CSS中使用,只有Firefox支持。<p>位于 后面的重复元素div#images。<img/>可以使用元素来定位元素,transform: translate而不必通过background-position或者position: absolute这将产生更好的性能和帧速率。不过,我想不出任何不需要复制文本内容的方法——至少在 CSS 的content:属性允许元素从其他元素复制文本之前是这样。