Close menu

Mastering CSS text-shadow

Our previous article about CSS shadows was all about applying shadows to structural elements (like divs, images, buttons etc) but sometimes, you might want to give text on the page a little extra visual punch with shadows too. This is where you need the text-shadow property.

It's pretty similar to box-shadow, but does not support inset (inner shadows) or spread.

text-shadow: [color] <x-offset> <y-offset> [blur]

Just like box-shadow, you can apply text-shadow in a few ways

Simplest form

In this usage you provide the 2 required length values: x-offset and y-offset. Just as with box-shadow, these are the horizontal and vertical distance from the text's top-left corner, at which the shadow will be drawn.

Positive values move the shadow to the right and bottom, while negative values offset it to the left and top.

In this form, the shadow will be sharp edged and fully opaque.

Unlike box-shadow if no colour is specified, there is no specific colour used, it is left up to the browser implementation, so our advice is to always treat the colour option as a required value, so your shadows are always what you expect across all the browsers.

text-shadow: 5px 5px;
Hello World


Explicitly set the colour of the shadow by providing a valid CSS colour either as the very first value, or the very last one.

em {
    text-shadow: #0000FF 5px 5px;

strong {
    text-shadow: 5px 5px #FF0000;
Hello World

Tip: use rgba values to control the shadow's transparency/opacity.


Just as with box-shadow, apply blur to the text shadow using a third length value, after specifying the x-offset and y-offset. As the shadow blurs, the dissipating edges become transparent.

Remember blur must be a positive length:

Think of this setting as changing the type of light given off by the light source. The lower the value, the more direct the light source, like a spotlight. The greater the value, the more diffuse the source, like a frosted bulb.

text-shadow: 5px 5px 8px rgba(0, 0, 0, 0.4);
Hello World

Applying blur will diffuse the shadow out from the boundaries made by the offset, this means that a blurred shadow may extend outward further than you intended. Unfortunately, unlike box-shadow which has spread to fine tune issues such as this, your only option is to tweak your offsets to adjust the distance at which the shadow comes to an end.

Compound Shadows

Like box-shadow, text-shadow allows us to create even more complex effects by setting multiple shadows. Just add comma separated values of the syntax for each shadow.

text-shadow: 3px 3px 1px rgb(255, 0, 0), 6px 6px 1px rgb(0, 255, 0), 9px 9px 1px rgb(0, 0, 255);
Hello World

Compounding shadows can allow us to make slick visuals with our text.

text-shadow: 2px 1px 2px rgba(0, 0, 0, 0.4), 4px 5px 8px rgba(0, 0, 0, 0.4), 13px 12px 27px rgb(255, 119, 5);
Hello World


When specifying multiple shadows, remember that they are 'cast' in the order provided, first on top, so keep this in mind when trying to achieve photorealistic effects. You may have to reorder the shadows in your declaration to get the look you're after.

Note on performance

Shadows are computationally expensive and so do have an effect on performance, in particular, the scrolling experience (frame rate).

Even though text shadows will be small, when applied to large blocks of text, that's still quite a lot of processing, which of course also effects energy use and hence contributes to battery drain. So use them sparingly.

It's a good idea to only apply shadows in larger viewports, because they usually indicate bigger devices that tend to have better processors and bigger batteries. Smaller smartphone size screen devices can usually make do without the bells and whistles that text shadows are part of; allowing you to squeeze out more performance. It's a good guess that a smooth scrolling experience will be more appreciated by your user than text shadows.

First published: 22/03/2021