Tutorials Logic, IN info@tutorialslogic.com

CSS Drop Shadows box shadow text shadow

What are CSS Shadows?

CSS shadows are not only decoration; they communicate elevation, separation, and focus. A soft card shadow can show that a panel sits above the page, while a strong glow can highlight an active control.

The important decision is choosing the right shadow type. Use box-shadow for rectangular UI surfaces, text-shadow for large readable display text, and filter: drop-shadow() when the visible shape is not a rectangle, such as a transparent PNG or SVG icon.

CSS shadows are visual effects that create the illusion of depth and elevation in web design. They simulate how light interacts with objects in the real world, casting shadows that help users understand spatial relationships between elements. Shadows are fundamental to modern UI design, particularly in Material Design and neumorphism, where they indicate which elements are interactive, elevated, or layered above others.

CSS provides three main shadow properties: box-shadow for element boxes, text-shadow for text, and filter: drop-shadow() for complex shapes. Each serves different purposes and has unique characteristics. Understanding when and how to use each type is crucial for creating polished, professional interfaces.

1. box-shadow Property

The box-shadow property adds shadow effects around an element's frame (box). It's the most commonly used shadow property and is essential for creating cards, buttons, modals, and other elevated UI components.

Parameter Description Values Effect
offset-x Horizontal offset Positive = right, Negative = left Required
offset-y Vertical offset Positive = down, Negative = up Required
blur-radius Blur amount 0 = sharp, higher = softer Optional (default: 0)
spread-radius Shadow size Positive = expand, Negative = contract Optional (default: 0)
color Shadow color Any CSS color (rgba recommended) Optional (default: currentColor)
inset Inner shadow Keyword before other values Optional

box-shadow Syntax

box-shadow Syntax
/* Syntax: box-shadow: [inset] offset-x offset-y [blur-radius] [spread-radius] color */

.element {
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    /*          ↑ ↑   ↑   ↑
                │ │   │   └─ Color (with alpha transparency)
                │ │   └───── Blur radius (optional, default: 0)
                │ └───────── Vertical offset (required)
                └─────────── Horizontal offset (required)
    */
}

/* With all parameters */
.complete {
    box-shadow: 2px 4px 8px 2px rgba(0, 0, 0, 0.2);
    /*          ↑   ↑   ↑   ↑   ↑
                │   │   │   │   └─ Color
                │   │   │   └───── Spread radius (expands/contracts shadow)
                │   │   └───────── Blur radius (softness)
                │   └───────────── Vertical offset (down if positive)
                └───────────────── Horizontal offset (right if positive)
    */
}

/* Inset shadow (inner shadow) */
.inset {
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
}

Practical Shadow Recipes

Practical Shadow Recipes
/* 1. Subtle card Shadow (Material Design inspired) */
.card-subtle {
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12),
                0 1px 2px rgba(0, 0, 0, 0.24);
}

/* 2. Elevated card (Medium depth) */
.card-elevated {
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1),
                0 2px 4px rgba(0, 0, 0, 0.06);
}

/* 3. Floating card (High elevation) */
.card-floating {
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15),
                0 5px 10px rgba(0, 0, 0, 0.05);
}

/* 4. Button Shadow (Interactive) */
.button {
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
    transition: box-shadow 0.3s ease;
}

.button:hover {
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}

.button:active {
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

/* 5. Inset Shadow (Pressed/Sunken effect) */
.input-field {
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.06);
    border: 1px solid #e5e7eb;
}

.input-field:focus {
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.06),
                0 0 0 3px rgba(59, 130, 246, 0.1);
}

/* 6. Colored Shadow (Brand emphasis) */
.button-primary {
    background: #3b82f6;
    box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}

/* 7. Neumorphism (Soft UI) */
.neumorphic {
    background: #e0e5ec;
    box-shadow: 9px 9px 16px rgba(163, 177, 198, 0.6),
               -9px -9px 16px rgba(255, 255, 255, 0.5);
}

/* 8. Layered Modal Shadow */
.modal {
    box-shadow: 0 20px 25px rgba(0, 0, 0, 0.1),
                0 10px 10px rgba(0, 0, 0, 0.04),
                0 0 0 1px rgba(0, 0, 0, 0.05);
}

/* 9. Bottom-only Shadow */
.bottom-shadow {
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

/* 10. Glow Effect */
.glow {
    box-shadow: 0 0 20px rgba(59, 130, 246, 0.6),
                0 0 40px rgba(59, 130, 246, 0.4);
}

2. text-shadow Property

The text-shadow property adds shadow effects to text. Unlike box-shadow, it doesn't support the spread-radius or inset keyword. Text shadows are commonly used for headings, logos, and creating text effects like embossing or glowing text.

text-shadow Examples

text-shadow Examples
/* Syntax: text-shadow: offset-x offset-y blur-radius color */

/* 1. Simple Text Shadow */
.heading {
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}

/* 2. Multiple Text Shadows */
.logo {
    text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3),
                 0 0 10px rgba(255, 255, 255, 0.5);
}

/* 3. Embossed Text Effect */
.embossed {
    color: #333;
    background: #ddd;
    text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.8),
                -1px -1px 0 rgba(0, 0, 0, 0.3);
}

/* 4. Engraved Text Effect */
.engraved {
    color: #666;
    background: #ddd;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8),
                 0 -1px 0 rgba(0, 0, 0, 0.3);
}

/* 5. Glowing Text */
.glow-text {
    color: #fff;
    text-shadow: 0 0 10px #00ff00,
                 0 0 20px #00ff00,
                 0 0 30px #00ff00;
}

/* 6. 3D Text Effect */
.text-3d {
    color: #fff;
    text-shadow: 0 1px 0 #ccc,
                 0 2px 0 #c9c9c9,
                 0 3px 0 #bbb,
                 0 4px 0 #b9b9b9,
                 0 5px 0 #aaa,
                 0 6px 1px rgba(0, 0, 0, 0.1),
                 0 0 5px rgba(0, 0, 0, 0.1),
                 0 1px 3px rgba(0, 0, 0, 0.3),
                 0 3px 5px rgba(0, 0, 0, 0.2),
                 0 5px 10px rgba(0, 0, 0, 0.25);
}

/* 7. Outline Text */
.outline-text {
    color: #fff;
    text-shadow: -1px -1px 0 #000,
                  1px -1px 0 #000,
                 -1px  1px 0 #000,
                  1px  1px 0 #000;
}

/* 8. Soft Shadow for Readability */
.readable {
    color: #fff;
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
}

3. filter: drop-shadow()

The drop-shadow() filter function creates a shadow that follows the alpha channel of an image or element, rather than just the box. This is particularly useful for PNG images with transparency, SVG graphics, and elements with complex shapes. Unlike box-shadow, drop-shadow() respects the actual shape of the content.

drop-shadow() Examples

drop-shadow() Examples
/* Syntax: filter: drop-shadow(offset-x offset-y blur-radius color) */

/* 1. Basic Drop Shadow */
.icon {
    filter: drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.3));
}

/* 2. PNG Image with Transparency */
.logo-png {
    filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.2));
}

/* 3. SVG Icon Shadow */
.svg-icon {
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.15));
}

/* 4. Multiple Drop Shadows */
.complex-shape {
    filter: drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.2))
            drop-shadow(4px 4px 4px rgba(0, 0, 0, 0.1));
}

/* 5. Colored Drop Shadow */
.colored-icon {
    filter: drop-shadow(0 4px 8px rgba(59, 130, 246, 0.5));
}

/* Comparison: box-shadow vs drop-shadow */
.with-box-shadow {
    /* Shadow follows the rectangular box */
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.with-drop-shadow {
    /* Shadow follows the actual shape (alpha channel) */
    filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.2));
}

box-shadow vs drop-shadow() Comparison

Feature box-shadow filter: drop-shadow()
Shadow Shape Follows element's box Follows alpha channel (actual shape)
Transparency Support No - shadows rectangular box Yes - respects PNG/SVG transparency
Multiple Shadows Yes (comma-separated) Yes (multiple filter functions)
Inset Support Yes (inset keyword) No
Spread Radius Yes (4th parameter) No
Performance Better (GPU accelerated) Slower (requires repainting)
Browser Support Excellent (all modern browsers) Good (IE not supported)
Best For Cards, buttons, containers PNG images, SVG icons, complex shapes

Advanced Shadow Techniques

Combining multiple shadows creates more realistic depth by simulating how light scatters in the real world.

Layered Shadows

Layered Shadows
/* Material Design Elevation Levels */
.elevation-1 {
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12),
                0 1px 2px rgba(0, 0, 0, 0.24);
}

.elevation-2 {
    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16),
                0 3px 6px rgba(0, 0, 0, 0.23);
}

.elevation-3 {
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19),
                0 6px 6px rgba(0, 0, 0, 0.23);
}

.elevation-4 {
    box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25),
                0 10px 10px rgba(0, 0, 0, 0.22);
}

.elevation-5 {
    box-shadow: 0 19px 38px rgba(0, 0, 0, 0.30),
                0 15px 12px rgba(0, 0, 0, 0.22);
}

/* Realistic Shadow (3 layers) */
.realistic-card {
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05),    /* Ambient shadow */
                0 8px 16px rgba(0, 0, 0, 0.1),     /* Penumbra */
                0 16px 32px rgba(0, 0, 0, 0.05);   /* Umbra */
}

Shadow Animations

Shadow Animations
/* Hover Lift Effect */
.card-lift {
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card-lift:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
}

/* Button Press Effect */
.button-press {
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
    transition: all 0.1s ease;
}

.button-press:active {
    transform: translateY(2px);
    box-shadow: 0 2px 3px rgba(0, 0, 0, 0.2);
}

/* Pulsing Glow Animation */
@keyframes pulse-glow {
    0%, 100% {
        box-shadow: 0 0 10px rgba(59, 130, 246, 0.5);
    }
    50% {
        box-shadow: 0 0 20px rgba(59, 130, 246, 0.8),
                    0 0 30px rgba(59, 130, 246, 0.6);
    }
}

.pulse {
    animation: pulse-glow 2s ease-in-out infinite;
}

Best Practices for Shadows

  • Use subtle shadows - Overly dark or large shadows look unrealistic and dated
  • Maintain consistency - Keep shadow direction and intensity consistent across your design
  • Use rgba() for colors - Allows precise control over opacity and works with any background
  • Layer multiple shadows - Creates more realistic depth than a single shadow
  • Consider performance - Excessive shadows can impact rendering performance
  • Match elevation to importance - More important elements should have stronger shadows
  • Use transitions - Animate shadow changes for smooth interactions
  • Test on different backgrounds - Ensure shadows are visible on both light and dark backgrounds
  • Avoid pure black - Use dark grays (rgba(0, 0, 0, 0.1-0.3)) for more natural shadows
  • Consider accessibility - Don't rely solely on shadows to convey information

Common Shadow Mistakes

Mistake Problem Solution
Too dark shadows Looks harsh and unrealistic Use opacity 0.1-0.3 instead of 0.5+
No blur radius Sharp, unnatural shadows Always add blur (4px-20px typical)
Inconsistent direction Confusing visual hierarchy Keep light source consistent
Using pure black Too harsh, doesn't match real shadows Use rgba(0, 0, 0, 0.1-0.3)
Too many shadows Performance issues, visual clutter Limit to 2-3 layers maximum
Wrong shadow type box-shadow on transparent PNGs Use drop-shadow() for transparency

Browser Compatibility

Property Chrome Firefox Safari Edge IE
box-shadow ✓ 10+ ✓ 4+ ✓ 5.1+ ✓ 12+ ✓ 9+
text-shadow ✓ 4+ ✓ 3.5+ ✓ 4+ ✓ 12+ ✓ 10+
drop-shadow() ✓ 18+ ✓ 35+ ✓ 9+ ✓ 79+ ✗ No

Performance Considerations

  • GPU Acceleration - box-shadow is GPU-accelerated in most browsers
  • Avoid animating blur - Animating blur radius is expensive; animate opacity or transform instead
  • Use will-change - Add will-change: box-shadow for frequently animated shadows
  • Limit shadow count - Each additional shadow increases rendering cost
  • Prefer box-shadow - Use drop-shadow() only when necessary (transparency)
  • Test on mobile - Shadows can impact performance on lower-end devices
Before you move on

CSS Drop Shadows box shadow text shadow Mastery Check

5 checks
  • Use box-shadow for cards, buttons, inputs, modals, and rectangular UI surfaces.
  • Use text-shadow only when it improves large text readability or creates a deliberate display effect.
  • Use filter: drop-shadow() for transparent images, SVGs, and non-rectangular shapes.
  • Keep shadow direction consistent so the page feels like it has one light source.
  • Use rgba or hsla colors with low opacity instead of harsh pure black shadows.

CSS Questions Learners Ask

box-shadow follows the element rectangular box. drop-shadow follows the rendered visible shape, including transparency.

Yes. Separate shadow layers with commas. Multiple subtle layers often look more natural than one harsh shadow.

The opacity may be too high, the blur may be too low, or the spread may be too large.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.