想做凸起来的3D文字效果,用CSS分层堆叠真的能搞定吗?

2,247字
10–14 分钟
in

想在网页上整一个那种看起来鼓鼓的、像浮雕一样的3D文字效果,但又不确定从哪儿下手?别慌,这玩意儿看着唬人,其实用CSS里一个叫“分层堆叠”的野路子就能搞定。简单说,就是拿一堆长得一模一样但颜色有深浅的扁平图层,像叠扑克牌那样码起来,再给它们加个透视效果,眼睛就被骗过去了,文字自己就“站”起来了。

目录

3D文字咋分层

CSS确实能搞3D,能把元素在空间里转来转去,还能控制视角。但有个东西它给不了,就是实实在在的“厚度”。想用CSS搭个正方体,没法直接给个深度属性,得靠别的方法。一种是“拼积木法”,把六个面分别做出来,再拼到一起;另一种就是咱们要用的“叠叠乐法”,不追求真实体积,只堆叠无数层来制造视觉假象。这个方法尤其适合做文字,因为笔画复杂,一层层堆出来,鼓起来的感觉特别明显。

结构咋搭

先得把地基打好。需要一个容器把东西都包起来,里面放上原始文字和一堆用来堆叠的层。原始文字最好用span单独包一层,方便后面单独给它上色,这玩意儿以后要当最底下的阴影。那堆层得塞进一个叫layers的容器里,并且得给这个容器加上aria-hidden="true",不然屏幕阅读器会把这一大堆重复内容全读出来,那用户体验就炸了。

<div class="text">
  <span>凸起文字</span>
  <div class="layers" aria-hidden="true">
    <div class="layer" style="--i: 1;">凸起文字</div>
    <div class="layer" style="--i: 2;">凸起文字</div>
    <div class="layer" style="--i: 3;">凸起文字</div>
    <!-- 继续叠,越多层,鼓得越明显 -->
  </div>
</div>

这代码看着有点啰嗦,每个layer里都得填一遍文字,但好处是简单直接,不用搞什么黑科技。如果想偷懒,用Emmet快捷键一秒就能生成几十个带数字索引的层。

层索引咋玩

每个层都得有个身份编号,就是--i这个变量。第一个层是1,第二个是2,依此类推。这玩意儿后面有大用,计算每个层该往前挪多少、颜色该调多亮,全靠它了。上面代码里直接在style属性里写了,这样结构清晰,想改哪个层直接改数字就行,不用去样式表里翻来翻去。

咋把层叠到一起

层准备好了,得让它们全部叠在同一个位置。用CSS的定位大法,把text容器设成position: relative,里面的layers和所有layer都设成position: absolute,再给个inset: 0,这些层就严丝合缝地叠成厚厚一摞了。

.text {
  position: relative;
}

.text .layers,
.text .layer {
  position: absolute;
  inset: 0;
}

这时候看页面,可能还是平的,因为还没给透视。

厚度咋挤出来

要看到厚度,得加个“相机视角”。在外面套个scene容器,给它一个perspective属性,值越小,3D效果越夸张,就像凑近了看东西。然后,每个要参与3D空间的层,都得声明transform-style: preserve-3d,不然浏览器会偷懒,把所有东西拍扁,白忙活一场。

.scene {
  perspective: 400px;
}

.scene * {
  transform-style: preserve-3d;
}

现在每个层就能在Z轴(也就是屏幕里外)上移动了。用之前定义的--i编号和层间距--layer-offset,算出每个层该往前挪多少。

.text {
  --layers-count: 24;
  --layer-offset: 1px;
}

.layer {
  transform: translateZ(calc(var(--i) * var(--layer-offset)));
}

这么一搞,从侧面看,这堆层就变成了一个阶梯状的物体,文字自然就有了厚度感。

颜色咋渐变

光有厚度还不够,得用颜色把层次感“画”出来。因为每层都在不同的深度,越往前的层,应该越亮。用--i除以总层数--layers-count,得到一个0到1之间的归一化数值--n,然后用它来控制HSL颜色里的亮度。

.layer {
  --n: calc(var(--i) / var(--layers-count));
  color: hsl(200 30% calc(var(--n) * 100%));
}

最底下的层(--n接近0)颜色最暗,顶层的层(--n接近1)颜色最亮。为了更逼真,把最底层那个原始文字(就是span包裹的那个)涂成纯黑色,再加点蓝色阴影,让文字像是“陷”进去了一样。

.text span {
  color: black;
  text-shadow: 0 0 0.1em #003;
}
层位置颜色特性视觉作用
底层深色奠定阴影基础
中层渐变亮过渡与立体感
顶层高亮模拟受光面

整体咋微调

最后加点个人口味。换个粗壮的字体,比如Montserrat,加个900的字重,让文字看着敦实。再给整个文本容器来一个rotateX(30deg)的小旋转,让文字稍微仰起头,这样堆叠和渐变的效果会更明显。

.text {
  font-family: Montserrat, sans-serif;
  font-weight: 900;
  transform: rotateX(30deg);
}

折腾完这几步,一个不用图片、不用画图软件,纯靠HTML和CSS堆出来的凸起3D文字效果就落地了。这玩意儿现在还是个静态的,后面还有更带劲的玩法,比如让它动起来,或者跟着鼠标转,那才是真正的高潮。