Tutorials Logic, IN info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Website Development
Practice
Quiz Challenge Interview Questions Certification Practice
Tools
Online Compiler JSON Formatter Regex Tester CSS Unit Converter Color Picker
Compiler Tools

CSS Drop Shadows — box-shadow and text-shadow

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.

Syntax and Parameters

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);
}

Understanding Shadow Parameters

ParameterDescriptionValuesEffect
offset-xHorizontal offsetPositive = right, Negative = leftRequired
offset-yVertical offsetPositive = down, Negative = upRequired
blur-radiusBlur amount0 = sharp, higher = softerOptional (default: 0)
spread-radiusShadow sizePositive = expand, Negative = contractOptional (default: 0)
colorShadow colorAny CSS color (rgba recommended)Optional (default: currentColor)
insetInner shadowKeyword before other valuesOptional

Common box-shadow Patterns

Practical Shadow Recipes
/* 1. Subtle tl-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 tl-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 tl-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. tl-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
/* 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
/* 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

Featurebox-shadowfilter: drop-shadow()
Shadow ShapeFollows element's boxFollows alpha channel (actual shape)
Transparency SupportNo - shadows rectangular boxYes - respects PNG/SVG transparency
Multiple ShadowsYes (comma-separated)Yes (multiple filter functions)
Inset SupportYes (inset keyword)No
Spread RadiusYes (4th parameter)No
PerformanceBetter (GPU accelerated)Slower (requires repainting)
Browser SupportExcellent (all modern browsers)Good (IE not supported)
Best ForCards, buttons, containersPNG images, SVG icons, complex shapes

Advanced Shadow Techniques

1. Layered Shadows for Depth

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

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 */
}

2. Animated Shadows

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

MistakeProblemSolution
Too dark shadowsLooks harsh and unrealisticUse opacity 0.1-0.3 instead of 0.5+
No blur radiusSharp, unnatural shadowsAlways add blur (4px-20px typical)
Inconsistent directionConfusing visual hierarchyKeep light source consistent
Using pure blackToo harsh, doesn't match real shadowsUse rgba(0, 0, 0, 0.1-0.3)
Too many shadowsPerformance issues, visual clutterLimit to 2-3 layers maximum
Wrong shadow typebox-shadow on transparent PNGsUse drop-shadow() for transparency

Browser Compatibility

PropertyChromeFirefoxSafariEdgeIE
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
  • box-shadow adds depth around an element's box - use for cards, buttons, and containers.
  • text-shadow creates shadows on text - perfect for headings, logos, and text effects.
  • filter: drop-shadow() follows the alpha channel - use for PNG images and SVG icons with transparency.
  • Layer multiple shadows (2-3) for realistic depth that mimics how light scatters in real life.
  • Use rgba() colors with low opacity (0.1-0.3) for subtle, natural-looking shadows.
  • Maintain consistent shadow direction across your interface for coherent visual hierarchy.
  • Animate shadows with transitions for smooth hover and interaction effects.
  • box-shadow is more performant than drop-shadow() - use it when possible.

Ready to Level Up Your Skills?

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