This uses the ability to add multiple text-shadows within CSS. Since we are creating a hard shadow we only need to pass the offset and colour values.
/* offset-x | offset-y | color */
text-shadow: 0px 0px #000000;
/* Multiple shadows example */
text-shadow: 0px 0px #0000000, -1px 1px #000000, -2px 2px #000000;
Using a function in SCSS we can automate the process to create a basic shadow. By passing two values (length and colour) to this function we can easily create shadows of any size that mimic a three dimensional effect.
Note: for this approach to work we need to use solid colours. Using colours with opacity will just end up with the opacities stacked on top of each other creating a very murky dark shadow.
@function createShadowWithShadow($length_a, $length_b, $color_a, $color_b) {
$val: 0px 0px #{$color_a};
@for $i from 1 to $length_a + 1 {
$val: #{$val}, -#{$i}px #{$i}px #{$color_a};
}
@for $i from $length_a + 1 to $length_b + 1 {
$val: #{$val}, #{(-$length_a) + ($i - $length_a)}px #{$i}px #{$color_b};
}
@return $val;
}
We can expand this to have multiple directions by adding a couple of additional inputs to the function.
@function createShadowBetweenColors($length, $r1, $g1, $b1, $r2, $g2, $b2) {
$val: 0px 0px rgb($r1, $g1, $b1);
@for $i from 1 to $length {
$val: #{$val},
-#{$i}px
#{$i}px
rgb(
round($r1 - (($r1 - $r2) / $length) * $i),
round($g1 - (($g1 - $g2) / $length) * $i),
round($b1 - (($b1 - $b2) / $length) * $i)
);
}
@return $val;
}
This is cool but we can expand this approach further. If we pass RGB values to the function for two colours we can create the stops in between to blend between the two colours.
Using these basic approaches you could make any multitude of different shadow styles for text.
Note: This approach works in Figma too, but as I found out it only supports adding up to eight shadows which ultimately limits what you can do.