# Use Tailwind Default Shadows

**SHOULD** · **ID:** `design-ibelick-default-shadows` · **Category:** design
**Source:** [@Ibelick](https://www.ui-skills.com/)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/design-ibelick-default-shadows

> SHOULD: Use Tailwind CSS default shadow scale (shadow-sm, shadow, shadow-md) unless explicitly requested. Custom shadows often clash with the design system.

Stick with Tailwind's default shadow scale instead of custom values

That is the rule verbatim from the baseline-ui skill; everything below is ours. The scale is designed as one ramp lit from a single source, so elevation reads as depth rather than as noise; hand-rolled shadows with different blur, offset, and direction give you three cards that no longer sit in the same room. Get the names right, because they moved in v4: the scale runs `shadow-2xs`, `shadow-xs`, `shadow-sm`, `shadow-md`, `shadow-lg`, `shadow-xl`, `shadow-2xl`, and there is no bare `shadow` class any more. Worse than missing, the old names silently changed meaning — v4's `shadow-sm` renders what v3's bare `shadow` did, and v3's `shadow-sm` is now `shadow-xs`. So a v3 codebase that upgrades without a codemod does not break loudly; every `shadow-sm` in it just quietly gets one step heavier.

## Bad — do not do this

`design-ibelick-default-shadows-bad`

```tsx
const cards = [
  { name: 'Card A', note: 'custom', shadow: '0 2px 14px rgba(0,0,0,0.28)' },
  { name: 'Card B', note: 'custom', shadow: '3px 3px 0 rgba(0,0,0,0.22)' },
  { name: 'Card C', note: 'custom', shadow: '0 12px 4px -6px rgba(0,0,0,0.35)' },
];

export function IbelickDefaultShadowsBad() {
  return (
    <div className="space-y-4">
      {/* Light plate: shadows are unreadable against the dark theme. */}
      <div className="rounded-xl bg-neutral-100 p-6">
        <div className="grid grid-cols-3 gap-4">
          {cards.map((c) => (
            <div key={c.name} className="rounded-lg bg-white p-3" style={{ boxShadow: c.shadow }}>
              <p className="text-sm font-medium text-neutral-900">{c.name}</p>
              <p className="text-xs text-neutral-500">{c.note}</p>
            </div>
          ))}
        </div>
      </div>
      <p className="text-xs text-destructive">
        Three hand-rolled shadows with different blur, offset and direction. Nothing tells you which card sits above
        which
      </p>
    </div>
  );
}
```

## Good — do this

`design-ibelick-default-shadows-good`

```tsx
// The v4 scale: 2xs, xs, sm, md, lg, xl, 2xl. There is no bare `shadow` class —
// and v4's `shadow-sm` renders what v3's bare `shadow` used to.
const cards = [
  { name: 'Card A', token: 'shadow-xs', cls: 'shadow-xs' },
  { name: 'Card B', token: 'shadow-sm', cls: 'shadow-sm' },
  { name: 'Card C', token: 'shadow-md', cls: 'shadow-md' },
];

export function IbelickDefaultShadowsGood() {
  return (
    <div className="space-y-4">
      {/* Same light plate as the Bad example, so the ramp is legible and the comparison fair. */}
      <div className="rounded-xl bg-neutral-100 p-6">
        <div className="grid grid-cols-3 gap-4">
          {cards.map((c) => (
            <div key={c.name} className={`rounded-lg bg-white p-3 ${c.cls}`}>
              <p className="text-sm font-medium text-neutral-900">{c.name}</p>
              <p className="text-xs text-neutral-500">{c.token}</p>
            </div>
          ))}
        </div>
      </div>
      <p className="text-xs text-success">
        Tailwind's default scale, one light source, increasing depth. The elevation order is obvious at a glance
      </p>
    </div>
  );
}
```

## References

- [ibelick — baseline-ui skill](https://raw.githubusercontent.com/ibelick/ui-skills/main/skills/baseline-ui/SKILL.md)
- [Tailwind v4: box-shadow](https://tailwindcss.com/docs/box-shadow)
- [Tailwind v4: Upgrade guide](https://tailwindcss.com/docs/upgrade-guide)
