Tutorials Logic, IN info@tutorialslogic.com

CSS Drop Shadows box shadow text shadow

CSS Drop Shadows box shadow text shadow

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.

What are CSS Shadows?

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
Key Takeaways
  • 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.
Common Mistakes to Avoid
WRONG Using a dark heavy shadow on every card.
RIGHT Use subtle shadows for normal surfaces and stronger shadows only for overlays or active layers.
Too many strong shadows make the interface look noisy and less professional.
WRONG Using box-shadow on a transparent logo and expecting it to follow the logo shape.
RIGHT Use filter: drop-shadow() so the shadow follows the visible pixels.
box-shadow follows the rectangular box, not the transparent image outline.
WRONG Adding text-shadow to small paragraph text.
RIGHT Use text-shadow carefully on large headings or hero text where readability is tested.
Small text with shadows can become blurry and hard to read.

Practice Tasks

  • Create three cards with low, medium, and high elevation using different box-shadow values.
  • Compare box-shadow and filter: drop-shadow() on a transparent PNG icon.
  • Create a focused input ring using box-shadow without changing layout size.
  • Build a hero heading with a subtle text-shadow and check readability on a photo background.

Frequently Asked Questions

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.

No. Shadows are visual paint effects and do not take up layout space.

Ready to Level Up Your Skills?

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