| |

Tailwind CSS 23 🎨 Box Shadows, Drop Shadows, and Inset Shadow Styles

A shadow is a lie about light. It suggests depth, elevation, and hierarchy on a flat screen. It is one of the most effective tools for communicating which elements float above others and which sit recessed within a surface. Tailwind provides three distinct shadow mechanisms: shadow-* for box shadows, drop-shadow-* for filter-based shadows that follow irregular shapes, and inset-shadow-* for shadows drawn inside an element. They look similar in a screenshot but behave differently under the hood, and choosing the wrong one produces either the wrong visual effect or a performance penalty.

This chapter covers all three. You will learn the default shadow scale, how to apply shadows conditionally on hover and focus, how drop shadows differ from box shadows in what they follow, and how to create custom shadow values when the defaults are not enough. You will also see the shadow color utilities introduced in Tailwind v4.1 and how they change the way shadows can be styled.

Key point: Box shadows and inset shadows are part of the box-shadow CSS property. Drop shadows are a filter function. Box shadows follow the element’s border box, including its border radius. Drop shadows follow the shape of the element’s rendered content, including transparent regions and irregular shapes.


Why three shadow types exist

The elevation problem. Interfaces need to communicate hierarchy. A modal floats above a page. A dropdown floats above a button. A card sits slightly above its background. Box shadows express this hierarchy by drawing a shadow outside the element, offset and blurred to simulate light from above. The shadow-* scale provides a set of elevation levels, from shadow-sm for subtle lift to shadow-2xl for dramatic emphasis .

The shape problem. Box shadows follow the element’s rectangular border box. This is correct for cards, buttons, and modals. It is wrong for text, SVG icons, and images with transparent regions. A box shadow on transparent text produces a rectangle behind the letters. A drop shadow, by contrast, follows the rendered shape of the element, including its transparency, producing a shadow that traces the actual visible content .

The recession problem. Sometimes an element should appear pressed into its surface rather than floating above it. An input field, a well, or a pressed button benefits from an inset shadow—a shadow drawn inside the element’s border, making the surface appear to curve inward. The shadow-inner utility provides a default inset shadow, and arbitrary values allow custom inset shadows for more control .

The color problem. Before Tailwind v4.1, shadows were always the color specified in the shadow’s CSS value—usually black with some opacity. There was no way to change the shadow color without replacing the entire shadow definition. Tailwind v4.1 added shadow-{color} utilities that let you tint a shadow independently of its geometry, and drop-shadow-{color} utilities for colored drop shadows .

The performance problem. Box shadows are generally cheaper to render than drop shadows because they are rectangular and can be optimized by the browser. Drop shadows require the browser to compute the alpha channel of the element’s rendered content, which is more expensive. For regular elements, box shadows are the right choice. For text and irregular shapes, drop shadows are the only option that produces the correct result.


a. Box shadows: the shadow-* scale

Box shadows are the primary shadow mechanism in Tailwind. The default scale provides six elevation levels and one inset shadow.

<div class="shadow-sm">Subtle</div>
<div class="shadow">Default</div>
<div class="shadow-md">Medium</div>
<div class="shadow-lg">Large</div>
<div class="shadow-xl">Extra large</div>
<div class="shadow-2xl">Maximum</div>

The values progress from a tight, low-opacity shadow to a large, diffuse one. shadow-sm uses a single layer with a 1px vertical offset and 2px blur. shadow-2xl uses a single layer with a 25px vertical offset and 50px blur . The intermediate levels use two layers to produce a more natural falloff.

Shadows compose with other utilities. A card might combine rounded-lg, border, and shadow-md. The shadow follows the border radius automatically because box-shadow respects border-radius .

Conditional shadows are applied with variant prefixes. The most common are hover:shadow-lg for interactive elements and focus:shadow-lg for focus states .

<button class="shadow hover:shadow-lg transition-shadow">
  Hover me
</button>

The transition-shadow utility animates the shadow change over 150ms, which is usually enough to make the hover feel responsive without being slow .

Arbitrary values allow one-off shadows that are not part of the theme:

<div class="shadow-[0_35px_60px_-15px_rgba(0,0,0,0.3)]">

The underscores in the arbitrary value are converted to spaces by Tailwind, producing the CSS value 0 35px 60px -15px rgba(0,0,0,0.3) .


b. Drop shadows: shadowing irregular shapes

Drop shadows use the CSS filter property with the drop-shadow() function. They are applied with the drop-shadow-* utilities.

<div class="drop-shadow-sm">Subtle</div>
<div class="drop-shadow">Default</div>
<div class="drop-shadow-md">Medium</div>
<div class="drop-shadow-lg">Large</div>
<div class="drop-shadow-xl">Extra large</div>
<div class="drop-shadow-2xl">Maximum</div>

The visual difference from box shadows is most obvious with transparent or irregular content. A drop shadow applied to text traces the letters. A drop shadow applied to an SVG icon traces the icon’s shape. A drop shadow applied to a PNG with transparency traces the visible content, not the bounding box .

Drop shadows are the correct choice when:

  • The element has transparent regions.
  • The element is text or an inline SVG.
  • The element has a non-rectangular shape.
  • The shadow should follow the actual rendered content.

Drop shadows are the wrong choice when:

  • The element is a regular rectangular block (card, button, modal).
  • Performance is a concern for a large number of elements.
  • The shadow should follow the border radius rather than the content shape.

Tailwind v4.1 added colored drop shadows. The syntax is drop-shadow-{color}:

<div class="drop-shadow-indigo-500">Colored shadow</div>
<div class="drop-shadow-cyan-500/50">Semi-transparent</div>

The opacity modifier works as it does with other color utilities. This is useful for branding or for matching a shadow to a background color .


c. Inset shadows and shadow colors

Inset shadows are drawn inside the element’s border. They make the element appear recessed. Tailwind provides shadow-inner as a default inset shadow.

<div class="shadow-inner">Recessed</div>

The default inset shadow is inset 0 2px 4px 0 rgba(0,0,0,0.06) . It is subtle and intended for form inputs, wells, and pressed states.

Custom inset shadows use arbitrary values with the inset keyword:

<div class="shadow-[inset_0_-2px_4px_rgba(0,0,0,0.6)]">

The inset keyword must be the first token in the arbitrary value. Tailwind does not provide a shadow-inner-{size} scale because inset shadows are less common than outer shadows and usually require custom values .

Tailwind v4.1 added shadow color utilities that work with both outer and inset shadows. The syntax is shadow-{color} for outer shadows and inset-shadow-{color} for inset shadows:

<div class="shadow-lg shadow-blue-500/50">Blue shadow</div>
<div class="inset-shadow-md inset-shadow-red-500/30">Red inset</div>

The opacity modifier is supported, allowing shadows to be tinted with the theme palette. This is a change from earlier versions where shadow colors were baked into the shadow definition .

A note on transitions: the inset-shadow-none utility was fixed in a recent Tailwind release to include the inset keyword in its output. Without this, transitions between inset and non-inset shadows do not interpolate smoothly because CSS cannot animate between different shadow types. If you are using a version before this fix, transitions involving inset shadows may behave unexpectedly .


Complete Example Session

<!-- ============================================ -->
<!-- PART 1: BASIC BOX SHADOW SCALE -->
<!-- ============================================ -->
<div class="shadow-sm p-4 bg-white rounded">Subtle</div>
<div class="shadow p-4 bg-white rounded">Default</div>
<div class="shadow-md p-4 bg-white rounded">Medium</div>
<div class="shadow-lg p-4 bg-white rounded">Large</div>
<div class="shadow-xl p-4 bg-white rounded">Extra large</div>
<div class="shadow-2xl p-4 bg-white rounded">Maximum</div>
<!-- ============================================ -->
<!-- PART 2: SHADOW ON HOVER -->
<!-- ============================================ -->
<button class="shadow hover:shadow-lg transition-shadow px-4 py-2 rounded">
  Hover me
</button>
<!-- ============================================ -->
<!-- PART 3: SHADOW ON FOCUS -->
<!-- ============================================ -->
<input class="shadow-sm focus:shadow-md transition-shadow border rounded px-3 py-2" />
<!-- ============================================ -->
<!-- PART 4: INSET SHADOW -->
<!-- ============================================ -->
<div class="shadow-inner p-4 rounded bg-gray-50">Recessed</div>
<input class="shadow-inner border rounded px-3 py-2" />
<!-- ============================================ -->
<!-- PART 5: CUSTOM INSET SHADOW -->
<!-- ============================================ -->
<div class="shadow-[inset_0_-2px_4px_rgba(0,0,0,0.6)] p-4">
  Custom inset
</div>
<!-- ============================================ -->
<!-- PART 6: DROP SHADOW ON TEXT -->
<!-- ============================================ -->
<h1 class="drop-shadow-lg text-4xl font-bold">Shadowed text</h1>
<!-- ============================================ -->
<!-- PART 7: DROP SHADOW ON SVG -->
<!-- ============================================ -->
<svg class="drop-shadow-md" viewBox="0 0 24 24">
  <path d="..." />
</svg>
<!-- ============================================ -->
<!-- PART 8: COLORED DROP SHADOW (v4.1+) -->
<!-- ============================================ -->
<div class="drop-shadow-indigo-500">Colored drop shadow</div>
<div class="drop-shadow-cyan-500/50">Semi-transparent</div>
<!-- ============================================ -->
<!-- PART 9: COLORED BOX SHADOW (v4.1+) -->
<!-- ============================================ -->
<div class="shadow-lg shadow-blue-500/50 p-4 rounded">Blue shadow</div>
<div class="shadow-lg shadow-red-500/30 p-4 rounded">Red shadow</div>
<!-- ============================================ -->
<!-- PART 10: ARBITRARY BOX SHADOW -->
<!-- ============================================ -->
<div class="shadow-[0_35px_60px_-15px_rgba(0,0,0,0.3)] p-4 rounded">
  Custom shadow
</div>

The ten parts covered the essential patterns: the box shadow scale, hover shadows, focus shadows, inset shadows, custom inset shadows, text drop shadows, SVG drop shadows, colored drop shadows, colored box shadows, and arbitrary values.


Quick Reference

Box Shadow Scale

ClassCSS ValueUse Case
shadow-sm0 1px 2px 0 rgb(0 0 0 / 0.05)Subtle lift
shadow0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)Default
shadow-md0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)Medium elevation
shadow-lg0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)Floating
shadow-xl0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)Modal
shadow-2xl0 25px 50px -12px rgb(0 0 0 / 0.25)Dramatic
shadow-innerinset 0 2px 4px 0 rgb(0 0 0 / 0.05)Recessed
shadow-none0 0 #0000Remove

Drop Shadow Scale

ClassCSS Value
drop-shadow-smdrop-shadow(0 1px 1px rgb(0 0 0 / 0.05))
drop-shadowdrop-shadow(0 1px 2px rgb(0 0 0 / 0.1)) drop-shadow(0 1px 1px rgb(0 0 0 / 0.06))
drop-shadow-mddrop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06))
drop-shadow-lgdrop-shadow(0 10px 8px rgb(0 0 0 / 0.04)) drop-shadow(0 4px 3px rgb(0 0 0 / 0.1))
drop-shadow-xldrop-shadow(0 20px 13px rgb(0 0 0 / 0.03)) drop-shadow(0 8px 5px rgb(0 0 0 / 0.08))
drop-shadow-2xldrop-shadow(0 25px 25px rgb(0 0 0 / 0.15))

Shadow Color Utilities (v4.1+)

ClassEffect
shadow-{color}Tint outer box shadow
shadow-{color}/{opacity}With opacity modifier
drop-shadow-{color}Tint drop shadow
inset-shadow-{color}Tint inset shadow

When to Use Each

Shadow TypeElement TypeFollows
shadow-*Rectangular blocksBorder box
drop-shadow-*Text, SVG, transparent imagesRendered content
shadow-innerInputs, wells, pressed statesInside border

Best Practices

✅ Do This:

<!-- Use box shadow for cards and buttons -->
<div class="shadow-md rounded-lg p-6">Card</div>              <!-- ✅ -->

<!-- Use drop shadow for text and SVG -->
<h1 class="drop-shadow-lg">Title</h1>                          <!-- ✅ -->

<!-- Transition shadow changes -->
<button class="shadow hover:shadow-lg transition-shadow">      <!-- ✅ -->

<!-- Use inset for form inputs -->
<input class="shadow-inner border rounded" />                  <!-- ✅ -->

<!-- Use colored shadows for branding -->
<div class="shadow-lg shadow-blue-500/50">Branded</div>        <!-- ✅ -->

<!-- Use arbitrary values for one-off shadows -->
<div class="shadow-[0_10px_40px_-10px_rgba(0,0,0,0.3)]">       <!-- ✅ -->

❌ Don’t Do This:

<!-- Don't use box shadow on transparent text -->
<h1 class="shadow-lg">Text</h1>                                <!-- ❌ -->

<!-- Don't use drop shadow on cards -->
<div class="drop-shadow-md p-6">Card</div>                    <!-- ⚠️ works but slower -->

<!-- Don't forget transition for hover shadows -->
<button class="shadow hover:shadow-lg">                       <!-- ⚠️ abrupt -->

<!-- Don't use inset shadow for elevation -->
<div class="shadow-inner">Floating card</div>                 <!-- ❌ wrong metaphor -->

<!-- Don't use shadow-none without a reason -->
<div class="shadow-none">                                    <!-- ⚠️ only to remove existing -->

<!-- Don't use arbitrary inset without the inset keyword -->
<div class="shadow-[0_-2px_4px_rgba(0,0,0,0.6)]">             <!-- ❌ not inset -->

Common Pitfalls

PitfallWhy It HappensFix
Shadow appears as rectangleBox shadow on transparent textUse drop-shadow-*
Shadow doesn’t follow shapeBox shadow on SVGUse drop-shadow-*
Hover shadow is abruptNo transition-shadowAdd transition class
Inset arbitrary value ignoredMissing inset keywordStart with inset_
Shadow color not changingNo color utilityUse shadow-{color} in v4.1+
Performance issue with many elementsDrop shadow on large listUse box shadow for rectangles
Transition between inset types brokenOld version bugUpdate Tailwind

Real-World Examples

1. Card with Hover Lift

<div class="shadow-md hover:shadow-xl transition-shadow rounded-lg p-6">
  Card content
</div>

2. Modal Dialog

<div class="shadow-2xl rounded-xl bg-white p-8">
  Modal content
</div>

3. Text with Drop Shadow

<h1 class="drop-shadow-lg text-5xl font-bold text-white">
  Hero Title
</h1>

4. Inset Input Field

<input class="shadow-inner border rounded-lg px-4 py-2" />

5. Pressed Button State

<button class="shadow-md active:shadow-inner transition-shadow">
  Press me
</button>

6. Colored Brand Shadow

<button class="shadow-lg shadow-indigo-500/50 bg-indigo-500 text-white">
  Branded
</button>

7. Floating Action Button

<button class="shadow-xl hover:shadow-2xl transition-shadow rounded-full p-4">
  +
</button>

8. Drop Shadow on Logo

<img class="drop-shadow-md" src="logo.svg" alt="Logo" />

9. Depth on Dark Background

<div class="shadow-lg shadow-black/50 bg-gray-800 rounded-lg p-6">
  Dark card
</div>

10. Subtle Elevation

<div class="shadow-sm border rounded-lg p-4">
  Subtle card
</div>

Visual

Box Shadow vs Drop Shadow

┌─────────────────────────────────────────────────────────────┐
│  BOX SHADOW (Follows Border Box)                            │
│                                                             │
│  ┌───────────────────────────────────────────────┐          │
│  │ Element (rectangular)                         │          │
│  │ ┌─────────────────────────────────────────┐   │          │
│  │ │ Text or content                         │   │          │
│  │ └─────────────────────────────────────────┘   │          │
│  └───────────────────────────────────────────────┘          │
│  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   │
│  ▓▓ Shadow follows the rectangle, not the content ▓▓       │
│  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  DROP SHADOW (Follows Rendered Content)                     │
│                                                             │
│  ┌───────────────────────────────────────────────┐          │
│  │         TEXT                                  │          │
│  │        ╱    ╲                                 │          │
│  │       ╱      ╲                                │          │
│  └───────────────────────────────────────────────┘          │
│      ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓          │
│      ▓▓ Shadow follows the letters, not a box ▓▓            │
│      ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Shadow Scale Progression

┌─────────────────────────────────────────────────────────────┐
│  ELEVATION SCALE                                            │
│                                                             │
│  shadow-sm     ▓▓▓  Low, tight                             │
│  shadow        ▓▓▓▓▓  Subtle lift                          │
│  shadow-md     ▓▓▓▓▓▓▓  Medium                             │
│  shadow-lg     ▓▓▓▓▓▓▓▓▓▓  Floating                        │
│  shadow-xl     ▓▓▓▓▓▓▓▓▓▓▓▓▓▓  Modal                       │
│  shadow-2xl    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  Dramatic               │
│                                                             │
│  As elevation increases, offset and blur increase,          │
│  and opacity usually increases as well.                     │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Inset Shadow Effect

┌─────────────────────────────────────────────────────────────┐
│  OUTER SHADOW (Elevation)                                   │
│                                                             │
│  ┌───────────────────────┐                                  │
│  │                       │                                  │
│  │      Element          │                                  │
│  │                       │                                  │
│  └───────────────────────┘                                  │
│  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   │
│  ▓▓ Shadow outside, element floats above surface ▓▓         │
│  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  INSET SHADOW (Recession)                                   │
│                                                             │
│  ┌───────────────────────┐                                  │
│  │▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│                                  │
│  │▓                   ▓▓▓│                                  │
│  │▓      Element      ▓▓▓│                                  │
│  │▓                   ▓▓▓│                                  │
│  │▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│                                  │
│  └───────────────────────┘                                  │
│                                                             │
│  Shadow inside, element appears pressed into surface.       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Shadow Composition

┌─────────────────────────────────────────────────────────────┐
│  SHADOW LAYERS                                              │
│                                                             │
│  A box-shadow can have multiple layers:                     │
│                                                             │
│  box-shadow:                                                │
│    0 1px 3px 0 rgb(0 0 0 / 0.1),   ← layer 1 (closest)      │
│    0 1px 2px -1px rgb(0 0 0 / 0.1); ← layer 2              │
│                                                             │
│  Tailwind's shadow utilities encode multiple layers         │
│  for realistic falloff.                                     │
│                                                             │
│  Rings, inset shadows, and regular shadows can all          │
│  be combined on the same element through CSS variables.     │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Summary

ItemValue
Box shadowshadow-{size} for elevation
Box shadow scalesm, “ (default), md, lg, xl, 2xl
Inset shadowshadow-inner for recession
Drop shadowdrop-shadow-{size} for irregular shapes
Shadow colorshadow-{color} (v4.1+)
Drop shadow colordrop-shadow-{color} (v4.1+)
Hover varianthover:shadow-lg
Focus variantfocus:shadow-md
Transitiontransition-shadow
Remove shadowshadow-none
Arbitrary valueshadow-[...]
Custom insetshadow-[inset_...]

Key takeaways:

  • Box shadows follow the border box; drop shadows follow the rendered content. Use shadow-* for cards, buttons, and modals. Use drop-shadow-* for text, SVG icons, and images with transparency.
  • The default scale provides six elevation levels. shadow-sm through shadow-2xl cover the range from subtle lift to dramatic emphasis. The intermediate levels use multiple shadow layers for a more natural falloff .
  • Inset shadows simulate recession. shadow-inner is the default inset shadow, useful for inputs and wells. Custom inset shadows require the inset keyword at the start of an arbitrary value .
  • Shadow colors are independent of shadow geometry. Tailwind v4.1 added shadow-{color} and drop-shadow-{color} utilities, allowing shadows to be tinted with any theme color and opacity modifier .
  • Transition shadow changes for smooth interaction. transition-shadow animates the shadow over 150ms, which is usually enough for hover and focus effects .
  • Arbitrary values handle one-off shadows. The shadow-[...] syntax generates a custom box-shadow on the fly. Underscores become spaces in the output.
  • Drop shadows are more expensive than box shadows. The browser must compute the alpha channel of the element’s rendered content. For large lists of rectangular elements, box shadows are the better choice.

Remember: Shadows communicate depth, and depth communicates hierarchy. Box shadows are the workhorse: they follow rectangles, render efficiently, and cover most elevation needs. Drop shadows are the specialist: they follow the actual shape of text and transparent images, producing results that box shadows cannot. Inset shadows are the counterpoint: they press an element into the surface rather than lifting it above. Tailwind’s shadow scale gives you a consistent set of elevation levels, and v4.1’s color utilities let you tint any shadow to match your design system. Choose the mechanism that matches the shape, use the scale that matches the elevation, and transition the change so the interface feels alive.



Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!