让我们看看如何使用 CSS text-shadow 属性来创建真正的 3D 效果文本。 您可能会认为 text-shadow 可以应用模糊的、渐变状的颜色到文本后面,而您是对的! 但就像 box-shadow 一样,您可以控制阴影的模糊程度,包括将其完全降到没有模糊。 结合使用逗号分隔的阴影并将其叠加,就是我们将在此处进行的 CSS 技巧。
最终我们将得到类似这样的效果

文字阴影快速回顾
语法如下
.el {
text-shadow: [x-offset] [y-offset] [blur] [color];
}
x-offset
: X 轴上的位置。 正值将阴影移动到右侧,负值将阴影移动到左侧。 (必需)y-offset
: Y 轴上的位置。 正值将阴影移动到底部,负值将阴影移动到顶部。 (必需)blur
: 阴影应该有多少模糊。 值越大,阴影越柔和。 默认值为 0px(无模糊)。 (可选)color
: 阴影的颜色。 (必需)
第一个阴影
让我们通过只添加一个阴影来开始创建我们的效果。 阴影将被推到右侧 6px,底部 6px
:root {
--text: #5362F6; /* Blue */
--shadow: #E485F8; /* Pink */
}
.playful {
color: var(--text);
text-shadow: 6px 6px var(--shadow);
}

使用更多阴影创建深度
此时我们只有一个平面阴影 - 它还没有太多 3D 效果。 我们可以通过向同一个元素添加更多 text-shadow
实例来创建深度并将阴影连接到实际文本。 只需要用逗号将它们分隔开。 让我们先添加一个中间阴影
.playful {
color: var(--text);
text-shadow: 6px 6px var(--shadow),
3px 3px var(--shadow);
}

这已经开始有点样子了,但我们需要添加更多阴影才能让它看起来更好。 我们添加的步骤越多,最终结果就越详细。 在此示例中,我们将从 6px 6px 开始,并以 0.25px 为增量逐渐下降,直到我们达到 0。
.playful {
color: var(--text);
text-shadow:
6px 6px var(--shadow),
5.75px 5.75px var(--shadow),
5.5px 5.5px var(--shadow),
5.25px 5.25px var(--shadow),
5px 5px var(--shadow),
4.75px 4.75px var(--shadow),
4.5px 4.5px var(--shadow),
4.25px 4.25px var(--shadow),
4px 4px var(--shadow),
3.75px 3.75px var(--shadow),
3.5px 3.5px var(--shadow),
3.25px 3.25px var(--shadow),
3px 3px var(--shadow),
2.75px 2.75px var(--shadow),
2.5px 2.5px var(--shadow),
2.25px 2.25px var(--shadow),
2px 2px var(--shadow),
1.75px 1.75px var(--shadow),
1.5px 1.5px var(--shadow),
1.25px 1.25px var(--shadow),
1px 1px var(--shadow),
0.75px 0.75px var(--shadow),
0.5px 0.5px var(--shadow),
0.25px 0.25px var(--shadow);
}
使用 Sass 简化代码
结果可能看起来不错,但目前的代码很难阅读和编辑。 如果我们想让阴影更大,就需要进行大量复制粘贴才能实现。 例如,将阴影大小增加到 10px 意味着手动添加 16 个阴影。
这就是 SCSS 登场的地方。 我们可以使用函数来自动生成所有阴影。
@function textShadow($precision, $size, $color){
$value: null;
$offset: 0;
$length: $size * (1 / $precision) - 1;
@for $i from 0 through $length {
$offset: $offset + $precision;
$shadow: $offset + px $offset + px $color;
$value: append($value, $shadow, comma);
}
@return $value;
}
.playful {
color: #5362F6;
text-shadow: textShadow(0.25, 6, #E485F8);
}
函数 textShadow
接受三个不同的参数:阴影的精度、大小和颜色。 然后它创建一个循环,其中偏移量增加 $precision
(在本例中为 0.25px),直到它达到阴影的总大小(在本例中为 6px)。
这样,我们可以轻松地增加阴影的大小或精度。 例如,要创建一个大小为 10px 且以 0.1px 为增量的阴影,我们只需要在代码中更改以下内容即可
text-shadow: textShadow(0.1, 10, #E485F8);
交替颜色
我们希望通过使用交替颜色来使事情变得更有趣。 我们将文本拆分为用 span 包裹的单个字母(这可以通过手动完成,也可以使用 React 或 JavaScript 自动完成)。 输出将如下所示
<p class="playful" aria-label="Wash your hands!">
<span aria-hidden="true">W</span><span aria-hidden="true">a</span><span aria-hidden="true">s</span><span aria-hidden="true">h</span> ...
</p>
然后,我们可以对 span 使用 :nth-child()
选择器来更改其文本和阴影的颜色。
.playful span:nth-child(2n) {
color: #ED625C;
text-shadow: textShadow(0.25, 6, #F2A063);
}
如果我们在纯 CSS 中完成此操作,那么最终将得到以下结果
.playful span {
color: var(--text);
text-shadow:
6px 6px var(--shadow),
5.75px 5.75px var(--shadow),
5.5px 5.5px var(--shadow),
5.25px 5.25px var(--shadow),
5px 5px var(--shadow),
4.75px 4.75px var(--shadow),
4.5px 4.5px var(--shadow),
4.25px 4.25px var(--shadow),
4px 4px var(--shadow),
3.75px 3.75px var(--shadow),
3.5px 3.5px var(--shadow),
3.25px 3.25px var(--shadow),
3px 3px var(--shadow),
2.75px 2.75px var(--shadow),
2.5px 2.5px var(--shadow),
2.25px 2.25px var(--shadow),
2px 2px var(--shadow),
1.75px 1.75px var(--shadow),
1.5px 1.5px var(--shadow),
1.25px 1.25px var(--shadow),
1px 1px var(--shadow),
0.75px 0.75px var(--shadow),
0.5px 0.5px var(--shadow),
0.25px 0.25px var(--shadow);
}
.playful span:nth-child(2n) {
--text: #ED625C;
--shadow: #F2A063;
}
我们可以重复几次,使用其他颜色和索引,直到我们达到我们喜欢的模式
加分项:添加动画
使用相同的原理,我们可以通过添加动画来使文本更加生动。 首先,我们将添加一个重复动画,使每个 span 上下移动
.playful span {
color: #5362F6;
text-shadow: textShadow(0.25, 6, #E485F8);
position: relative;
animation: scatter 1.75s infinite;
}
我们可以通过使用 prefers-reduced-motion
媒体查询来进一步优化它。 这样,不想使用动画的人就不会看到它。
.playful span {
color: #5362F6;
text-shadow: textShadow(0.25, 6, #E485F8);
position: relative;
animation: scatter 1.75s infinite;
}
@media screen and (prefers-reduced-motion: reduce) {
animation: none;
}
然后,在每个 nth-child(n)
中,我们将添加不同的动画延迟。
.playful span:nth-child(2n) {
color: #ED625C;
text-shadow: textShadow(0.25, 6, #F2A063);
animation-delay: 0.3s;
}
这些技巧会影响网站的加载速度吗?
它不应该显著影响加载速度,尽管在大量文本上使用此效果可能会减慢移动端的渲染速度(数十个下拉阴影可能并不便宜)。
不错! 我感谢这里的无障碍处理。
如果您使用 transform 属性来动画化,动画可能会更平滑。 translate 不适用于内联属性,所以我包装了这些词语并将所有内容设置为 display: inline-block。 我不知道是否有更简洁的方法来做到这一点......但能够进行换行仍然很有用。 我认为我已经保留了相同的无障碍性,但不能 100% 确定。
https://codepen.io/jerome-toole/full/bGVwXqe
非常感谢,我刚刚在我的 Hugo 网站中实现了这个 css,它真的很不错
这个技巧在我的网站中效果很好!