这个项目标题打眼一看就容易让人想起那种“算了还是让设计出图吧”的场景。但我用 CSS 实际做下来之后,反而有些上瘾:只要把几个核心参数吃透,很多之前必须丢给 Photoshop 才能出片的效果,在网页里直接敲几十行样式就能出,甚至还能跟着鼠标动、跟着滚动动、跟着用户输入实时变。这篇文章就从我这个长期折腾前端动效的人的角度,把“用 CSS 做 3D 文字”这件事从头到尾拆一遍,包含原理、可复现代码、参数背后的取舍,以及踩坑记录。无论你是刚入门前端的小白,还是已经写了好几年样式想找点新玩法的老手,这套实操内容应该都能直接抄作业。
1. 动手前的设计思路:同样是3D文字,为什么我不开PS
1.1 纯CSS方案到底解决了什么问题
很多人第一反应是,做个 3D 文字而已,用 PS 拉个图层样式,导出 PNG 不就行了?如果你的页面内容永远不变,当然可以。但只要是做前端的人,迟早会遇到下面这些情况:
- 标题文字需要根据后台配置动态变化,比如用户昵称、随机生成的活动文案,总不能每次变化都让设计导出新图。
- 需要文字随着鼠标或滚动产生透视反馈,静态图完全做不到。
- 团队想减少页面图片体积。一个 3D 文字的 PNG 动辄几十上百 KB,而一段 CSS 往往只有 1~2KB,尤其在做落地页时,移动端性能差异很明显。
- 想要在运行时给文字加动画、加滤镜、加过渡,图片方案全都锁死了。
所以“用 CSS 干翻 PS”这个口号,并不是说 CSS 能完成 PS 的所有炫技,而是在“界面中的标题文字特效”这个具体场景里,CSS 更轻量、更可控、更贴近 Web 的交互模型。它能做到很多人低估的东西,甚至能模拟出“伪图层样式叠加”的效果,而且代码量并不多。
1.2 两条实现路线:假3D与真3D
做 3D 文字特效,行业内基本分两大流派。理解这两条路线的差异,比直接背代码重要得多。
第一条是“假 3D”路线,核心靠 text-shadow 的多层叠加。每隔 1px 或 2px 叠一层阴影,层数多了以后,视觉上会产生一种“文字从纸面上凸起来”或“凹陷下去”的错觉。这种方案的优点是兼容性极好、代码结构简单,缺点是它本质上是 2D 的,无法响应透视角度变化,但胜在普适性极高,适合做按钮文字、标题的立体质感、活动页主视觉。
第二条是“真 3D”路线,核心靠 CSS 的 transform-style: preserve-3d 和 perspective。把文字拆成多个元素或使用多层伪类,在 Z 轴方向拉开距离,再给父容器一个透视角度,那么文字就会真正拥有深度,旋转容器时能看到文字的前后层次。这种方案适合做产品展示、名片翻转、3D 相册、引导页里的动态标题。
搞清楚自己要哪种效果,后面实现思路完全不一样。我在实际项目里的习惯是,纯展示型、稳定型页面优先用 text-shadow 方案;需要交互、需要动起来,再去上 preserve-3d。
1.3 这套实战需要什么基础
这篇实战的内容前端小白完全可以跟下来。要准备的不多:
- 一个编辑器,VSCode 之类的就行。
- 一个现代浏览器,Chrome 或 Edge 都没有问题。
- 基本的 HTML/CSS 结构感就可以,至少知道
<h1>、<style>标签是干什么的,如果会一点 flex 布局更好,不会也不影响,我会尽量写得细。
下面的内容是完全可以从零复制粘贴运行起来的。建议不要把代码扫一眼就关掉,自己动手改几个参数,比如层数、透视值、颜色,那种手感才会积累成你自己的经验。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础中的基础:用text-shadow堆出立体感
2.1 为什么多层阴影会产生“厚度感”
text-shadow 的标准用法是“文字后面拖个模糊影子”,这很正常。但如果你去掉模糊半径,只保留偏移,再复制很多份,每一份都比上一份更暗一点,就会得到一个类似“文字的侧边被拉了厚度”的视觉结果。
原理并不复杂。光线如果从左上角照过来,文字朝右下方向的边缘会被照亮,反过来文字远离光线的左侧上侧就会落下一层层暗色投影。我们用 0 模糊的深色阴影一层一层向某个方向偏移,实际上是在模拟光线被文字遮挡后在侧边产生的厚度区域。层与层之间的色差越小,位移间隔越大,质感越接近硬边塑料;色差越大、位移间隔越小,质感越接近雕刻效果。
第一次看到效果时,很多人都会觉得这种“土办法”居然能有这么接近 PS 图层样式的效果。我当初也是这个感觉, PS 里加描边加斜面浮雕,导出图片,而 CSS 只需要在 text-shadow 上叠加几行数字。
2.2 新手向:最简单的凸起立体字怎么做
先把代码写出来,目标效果是:白字、从左上往下突出、有点类似糖果塑料质感。
html复制<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS 3D文字 - text-shadow 立体字</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #0d1b2a;
font-family: 'Arial Black', 'Microsoft YaHei', sans-serif;
}
.stereo-title {
font-size: clamp(2.5rem, 8vw, 6rem);
font-weight: 900;
color: #ffffff;
letter-spacing: 0.08em;
text-shadow:
0 1px 0 #e0e0e0,
0 2px 0 #d0d0d0,
0 3px 0 #c0c0c0,
0 4px 0 #b0b0b0,
0 5px 0 #a0a0a0,
0 6px 0 #909090,
0 7px 12px rgba(0, 0, 0, 0.6);
}
</style>
</head>
<body>
<h1 class="stereo-title">3D
