CSS - Text Shadow


Syntax and Basic Usage

The CSS text-shadow property lets you add shadows to text elements. It takes four values: the horizontal offset, vertical offset, blur radius, and color.

The basic syntax for applying a text shadow is:

Example: Basic Syntax

selector {
  text-shadow: horizontal-offset vertical-offset blur-radius color;

Here's what each value means:

  1. horizontal-offset: The distance, in pixels, the shadow should be offset horizontally from the text. A positive value moves the shadow to the right, while a negative value moves it to the left.

  2. vertical-offset: The distance, in pixels, the shadow should be offset vertically from the text. A positive value moves the shadow down, while a negative value moves it up.

  3. blur-radius: The amount of blur applied to the shadow. A higher value will create a softer shadow, while a lower value will result in a sharper shadow. Setting this to 0 will give the shadow a hard edge.

  4. color: The color of the shadow. This can be any valid CSS color value such as hex code, RGB, RGBA, HSL or named color.

Example: Using text-shadow

h1 {
  text-shadow: 2px 2px 4px #000000;

In this example, <h1> element will have a shadow that is offset 2 pixels to right and 2 pixels down with blur radius of 4 pixels and black color.

You can also use negative values for horizontal and vertical offsets:

Example: Using negative values

p {
  text-shadow: -1px -1px 2px #CCCCCC;

This creates light gray inset-like shadows as it's offset by one pixel up and left.

By adjusting these values you can create various text-shadow effects for your design needs.

Advanced Text Shadow Techniques

Multiple Text Shadows

You can apply multiple shadows to a single text element by separating each shadow with a comma. This lets you create more complex shadow effects.

Example: Using multiple shadows

h1 {
  text-shadow: 0 0 3px #FF0000, 0 0 5px #0000FF;

In this case, the text will have a red shadow with a 3px blur and a blue shadow with a 5px blur. The shadows will stack on top of each other.

Some creative uses of multiple shadows include:

  • Creating a neon glow effect by using a darker shadow on top of a lighter one
  • Simulating a 3D effect by offsetting shadows in opposite directions
  • Adding both drop and inner shadows for more style

When combining multiple shadows, it's best to:

  • Limit the number of shadows to avoid overwhelming the text
  • Use semi-transparent colors to allow better blending
  • Adjust blur radii for softer or sharper effects as needed

Text Shadow and Pseudo-elements

You can apply text shadows to pseudo-elements (::before and ::after) to create interesting effects without adding extra HTML elements.

Example: Adding an 'echo' effect with pseudo-elements

h1::after {
  content: attr(data-text);
  position: absolute;
  text-shadow: 2px 2px 4px #000;
  top: 0;
  left: 0;
  z-index: -1;

Here, the ::after pseudo-element duplicates the text content (using the attr() function), positions it behind the original text, and applies a shadow.

You can also combine text shadows with other CSS properties on pseudo-elements like transform, opacity, or filter for more advanced effects.

Text Shadow and CSS Animations

By using CSS animations, you can make text shadows dynamic. You can animate properties like offset, blur, and color.

Example: Animating shadow on hover

h1 {
  transition: text-shadow .3s;

h1:hover {
  box-shadow: .5em .5em .8em rgba(255, .25, .25, .75);

In this case, the header will get a red glow when hovered over smoothly within .3 seconds. You may also use keyframes for complex animations:

Example: Using keyframes for complex animations

@keyframes pulse {
  from {
    box-shadow: .15em -.15em .35em rgba(255, .25, .25, .75);
  via {
    box-shadow: .35em -.35em .55em rgba(255, .25, .25, .75);
  until {
    box-shadow: .15em -.15em .35em rgba(255, .25, .25, .75);

header {
  animation: pulse infinite ease-in-out;

This makes the header pulse between different shades indefinitely. When animating headers:

  • Use transitions for simple hovers and keyframes for complex ones.
  • Be mindful about performance since blurs are resource-intensive.
  • Ensure animation enhances user experience rather than distracting from content.