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);
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);
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);
text-shadow:
-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
You can even use it with box-shadow
to extrude elements instead of text:
transform: rotateX(60deg) rotateZ(-45deg);
box-shadow:
-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;
Here are some CodePens in which I used this technique:
If you're interested in a different technique, I made these 3D text codepens by layering multiple elements instead of using text-shadow
: