CSS Shadow

In modern web design, shadows are essential for creating elevation and visual hierarchy. By simulating how light hits an object, shadows help elements pop off the page, giving your layout a polished, three-dimensional feel. In CSS, we primarily work with two types of shadows: text-shadow for typography and box-shadow for containers and UI components.

Developer Tip: Think of shadows as a way to indicate "depth." Elements closer to the user (higher elevation) should usually have larger, softer shadows, while elements closer to the background should have smaller, sharper shadows.

Text Shadow

The text-shadow property adds depth specifically to your letters. It is an excellent tool for making text readable against busy background images or for creating stylized "glowing" or "retro" effects. You can apply multiple shadows to a single piece of text by separating them with commas.

  • Horizontal Offset (x-offset): Required. Defines how far the shadow moves horizontally. A positive value moves it right, while a negative value moves it left.
  • Vertical Offset (y-offset): Required. Defines how far the shadow moves vertically. A positive value moves it down, and a negative value moves it up.
  • Blur Radius: Optional. This determines how "fuzzy" the shadow looks. A value of 0 creates a sharp, solid edge. The higher the number, the softer and wider the shadow becomes.
  • Color: Optional. Sets the color of the shadow. If omitted, it usually defaults to the text color, but it's best practice to define it explicitly.

Syntax

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

Example

h1 {
    /* Moves shadow 2px right, 2px down, with a 4px blur */
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}

In this example, the shadow is pushed slightly away from the text to the bottom-right. By using a semi-transparent color (rgba), the shadow looks more natural against the background.

Common Mistake: Using pure black (#000000) for shadows. This often makes the design look "dirty" or dated. Instead, use a transparent version of your brand color or a soft rgba(0, 0, 0, 0.2) for a more professional look.

Box Shadow

The box-shadow property is far more versatile. It applies a shadow to the entire bounding box of an element, including any border-radius you've applied. It is widely used for buttons, cards, and modal windows to simulate physical layers on the screen.

  • Horizontal Offset: Required. Moves the shadow left or right.
  • Vertical Offset: Required. Moves the shadow up or down.
  • Blur Radius: Optional. Softens the shadow.
  • Spread Radius: Optional. This is unique to box-shadow. A positive value expands the shadow in all directions (making it larger than the element), while a negative value shrinks it.
  • Color: Optional. Defines the shadow's color.
  • Inset: Optional. By default, shadows are "outset" (outside the element). Adding the inset keyword moves the shadow inside the element, creating a "pressed-in" or hollow effect.

Syntax

box-shadow: horizontal-offset vertical-offset blur-radius spread-radius color inset;

Example

div {
    /* 5px right, 5px down, 10px blur, no extra spread */
    box-shadow: 5px 5px 10px 0px rgba(0, 0, 0, 0.15);
}

This creates a soft, subtle shadow that makes the <div> appear as if it is floating slightly above the page. This is the foundation of "Card" designs used in apps like Pinterest or Trello.

Best Practice: Use the Spread Radius to create "cleaner" shadows. By giving a shadow a large blur but a slightly negative spread (e.g., 0 10px 20px -5px rgba(0,0,0,0.2)), you can make the shadow look more realistic and focused under the element.

Example with Multiple Shadows

You can layer shadows to create complex lighting. In CSS, the first shadow in the list is the one on top (closest to the user).

/* Creating a "Neo-retro" layered text effect */
p {
    text-shadow: 1px 1px 0px #fff, 3px 3px 0px #333;
}

/* Creating a "Floating Button" with a highlight and a shadow */
.btn-ui {
    box-shadow: 
        0px 4px 6px rgba(0, 0, 0, 0.1), 
        inset 0px 1px 0px rgba(255, 255, 255, 0.5);
}

In this example:

  • The paragraph uses two shadows: a tiny white one to act as a "stroke" and a larger dark one to create a hard-edged 3D effect.
  • The button uses an outer shadow for depth and an inset shadow at the top to act as a "highlight," making the button look beveled and more tactile.
Watch Out: Shadows are calculated by the browser's rendering engine. Applying massive blur radii (like 100px) to many elements or animating shadows can cause significant lag during scrolling, especially on mobile devices.

Tips for Using Shadows

  1. Performance: If you need to animate a shadow (e.g., on :hover), it is often more performant to animate the opacity of a pseudo-element (::after) that contains the shadow, rather than animating the box-shadow property itself.
  2. Readability: For text-shadows, keep the blur low if the text is small. High blur on small font sizes can make the text look "smudged" and difficult to read.
  3. Design Consistency: Choose a "light source" for your entire page (e.g., top-left). This means all your shadows should have positive horizontal and vertical offsets so they all fall in the same direction.

Shadows are a powerful way to bridge the gap between flat design and a realistic UI. By mastering offsets, blur, and transparency, you can direct your users' attention and create a more intuitive browsing experience.