3D text

A sass function for generating 3D text with a clever use of CSS text-shadow

There are many ways to create 3D text. The most common way is stack multiple layers of text on top of each other, either by duplicating elements or using CSS text-shadow. In this snippet i'm going to show how to use text-shadow to create 3D text, and have different colors for different sides to make it look more realistic.

The advantages of this approach over stacking elements is that it's less strenuous on the DOM (less elements). The disadvantage is that it doesn't play well with 3D transformations (like transform: rotateX(45deg)), but you can "fake" it to look good by manually orienting it in the right direction, as i will show in the upcoming examples.

@function extrude($layers, $color1, $color2) {
  $spread: 0.05rem;
  $scatter: 0.01;
  $gap: 0.02;
  $value: 0 0 $spread $color1;
  @for $i from 1 through $layers {
    // Each layer consists of 2 text shadows, each with a different color and offset.
    // The idea is to offset one layer to the left, and the other to the bottom, so that when
    // they overlay each other, each side of the text will have a different color.
    $value: #{$value}, #{($i * -2 - 1) * $gap - $scatter}rem #{($i * 2 - 1) * $gap - $scatter}rem $spread #{$color1};
    $value: #{$value}, #{$i * -2 * $gap + $scatter}rem #{$i * 2 * $gap + $scatter}rem $spread #{$color2};
  @return $value;

To use it, call the mixin with the desired breakpoint:

text-shadow: extrude(15, gray, lightgray);
3D Text

We can take it further and use transform and rotate the text to make it look even more realistic (notice that I had to increase the number of layers on this one).

transform: rotateX(60deg) rotateZ(-45deg);
text-shadow: extrude(30, gray, lightgray);
3D Text

We can even mix it with more text shadow layers to create a more realistic effect. In this example I added black edges around the top layer of the text, and some light glow on the bottom layer.

transform: rotateX(60deg) rotateZ(-45deg);
  -0.05rem 0.05rem 0.05rem black, // Top black edges
  extrude(30, #4b5563, #d1d5db),
  -1.30rem 1.27rem 0.3rem black, // Bottom shadow
  -1.33rem 1.3rem 2rem #d1d5db; // Bottom glow
3D Text

You can even use it with box-shadow to extrude elements instead of text:

transform: rotateX(60deg) rotateZ(-45deg);
  -0.05rem 0.05rem 0.1rem rgb(255, 255, 255, 50%),
  extrude(40, #2a3039, #676e78),
  -1.6rem 1.57rem 1.3rem black,
  -1.63rem 1.6rem 7rem #89919d;
3D Cube

Here are some CodePens in which I used this technique:

See the Pen 3D Color Picker by Yoav Kadosh (@ykadosh) on CodePen.
See the Pen CSS Mechanical Keyboard by Yoav Kadosh (@ykadosh) on CodePen.

If you're interested in a different technique, I made these 3D text codepens by layering multiple elements instead of using text-shadow:

See the Pen Primary Colors Isometric Text by Yoav Kadosh (@ykadosh) on CodePen.
See the Pen Isometric Text! by Yoav Kadosh (@ykadosh) on CodePen.

A newsletter for front-end web developers

Stay up-to-date with my latest articles, experiments, tools, and much more!

Issued monthly (or so). No spam. Unsubscribe any time.