Effects

box-shadow

Adding light and dark shadow effects around an element.

Overview

ClassDeclarations
shadow-xsbox-shadow: var(--shadow-xs);
shadow-smbox-shadow: var(--shadow-sm);
shadow-mdbox-shadow: var(--shadow-md);
shadow-lgbox-shadow: var(--shadow-lg);
shadow-xlbox-shadow: var(--shadow-xl);
shadow-2xlbox-shadow: var(--shadow-2xl);
shadow:<value>,<…>box-shadow: <value>,<…>;
shadow:inset|<offset-x>|<offset-y>|<color>box-shadow: inset <offset-x> <offset-y> <color>;

Basic usage

Use shadow tokens

Preset shadow:* tokens define common elevation levels. Switch the preview theme: the class stays the same while each token resolves to its mode-specific paint.

Use shadow tokens
box-shadow: Use shadow tokens controls
These are the browser’s actual shadow layers. The measured box excludes their paint; theme tokens may resolve differently in each mode.
<!-- Small elevation --><article id="target"  class="w:240px max-w:100% p-lg r-md bg-surface-base         text-body shadow-sm box-border">  <h4 class="m:0 font-lg">    Workspace library  </h4>  <p class="mx:0 mb:0 mt-sm font-sm">    Shared assets and components.  </p></article>
<!-- Large elevation --><article id="target"  class="w:240px max-w:100% p-lg r-md bg-surface-base         text-body shadow-lg box-border">  <h4 class="m:0 font-lg">    Workspace library  </h4>  <p class="mx:0 mb:0 mt-sm font-sm">    Shared assets and components.  </p></article>
Generated CSS
@layer theme {  :root,  :host {    --shadow-sm: 0 0 0 1px oklch(0% 0 none / .04), 0 1px 2px -1px oklch(0% 0 none / .06), 0 3px 6px -2px oklch(0% 0 none / .08);    --shadow-lg: 0 0 0 1px oklch(0% 0 none / .05), 0 4px 8px -4px oklch(0% 0 none / .08), 0 16px 32px -8px oklch(0% 0 none / .12)  }  @media (prefers-color-scheme:light) {    :root {      --shadow-sm: 0 0 0 1px oklch(0% 0 none / .04), 0 1px 2px -1px oklch(0% 0 none / .06), 0 3px 6px -2px oklch(0% 0 none / .08);      --shadow-lg: 0 0 0 1px oklch(0% 0 none / .05), 0 4px 8px -4px oklch(0% 0 none / .08), 0 16px 32px -8px oklch(0% 0 none / .12)    }  }  @media (prefers-color-scheme:light) {    :host {      --shadow-sm: 0 0 0 1px oklch(0% 0 none / .04), 0 1px 2px -1px oklch(0% 0 none / .06), 0 3px 6px -2px oklch(0% 0 none / .08);      --shadow-lg: 0 0 0 1px oklch(0% 0 none / .05), 0 4px 8px -4px oklch(0% 0 none / .08), 0 16px 32px -8px oklch(0% 0 none / .12)    }  }  @media (prefers-color-scheme:dark) {    :root {      --shadow-sm: 0 0 0 1px oklch(100% 0 none / .05), 0 1px 2px -1px oklch(0% 0 none / .34), 0 3px 6px -2px oklch(0% 0 none / .26);      --shadow-lg: 0 0 0 1px oklch(100% 0 none / .06), 0 4px 8px -4px oklch(0% 0 none / .42), 0 16px 32px -8px oklch(0% 0 none / .34)    }  }  @media (prefers-color-scheme:dark) {    :host {      --shadow-sm: 0 0 0 1px oklch(100% 0 none / .05), 0 1px 2px -1px oklch(0% 0 none / .34), 0 3px 6px -2px oklch(0% 0 none / .26);      --shadow-lg: 0 0 0 1px oklch(100% 0 none / .06), 0 4px 8px -4px oklch(0% 0 none / .42), 0 16px 32px -8px oklch(0% 0 none / .34)    }  }}@layer utilities {  .shadow-lg {    box-shadow: var(--shadow-lg)  }  .shadow-sm {    box-shadow: var(--shadow-sm)  }}

The shadow is visual ink outside the box; it does not add layout size or spacing. Leave enough room for its blur to remain visible.

Use raw values

Use literal shadow layers for a specific effect. The first listed layer paints above later layers. These blue shadows retain the same raw color values across themes.

Use raw values
box-shadow: Use raw values controls
These are the browser’s actual shadow layers. The measured box excludes their paint; theme tokens may resolve differently in each mode.
<!-- Two raw layers · literal color --><article id="target"  class="w:240px max-w:100% p-lg r-md bg-surface-base         text-body         shadow:0|2px|4px|color-mix(in|oklab,var(--color-blue-50)|20%,transparent),0|8px|16px|color-mix(in|oklab,var(--color-blue-50)|12%,transparent)         box-border">  <h4 class="m:0 font-lg">    Workspace library  </h4>  <p class="mx:0 mb:0 mt-sm font-sm">    Shared assets and components.  </p></article>

Raw values do not automatically acquire a separate dark-mode design. Compare against the actual surface, then promote recurring decisions into a theme token.

Use inset shadows

inset paints the shadow inside the border edge. Compare the same 4px vertical offset and 12px blur outside and inside the surface.

Use inset shadows
box-shadow: Use inset shadows controls
These are the browser’s actual shadow layers. The measured box excludes their paint; theme tokens may resolve differently in each mode.
<!-- Outer shadow --><article id="target"  class="w:240px max-w:100% p-lg r-md bg-surface-base         text-body shadow:0|4px|12px|color-mix(in|oklab,var(--color-blue-50)|20%,transparent)         box-border">  <h4 class="m:0 font-lg">    Workspace library  </h4>  <p class="mx:0 mb:0 mt-sm font-sm">    Shared assets and components.  </p></article>
<!-- Inset shadow --><article id="target"  class="w:240px max-w:100% p-lg r-md bg-surface-base         text-body shadow:inset|0|4px|12px|color-mix(in|oklab,var(--color-blue-50)|20%,transparent)         box-border">  <h4 class="m:0 font-lg">    Workspace library  </h4>  <p class="mx:0 mb:0 mt-sm font-sm">    Shared assets and components.  </p></article>

Neither shadow changes the box’s dimensions. An inset shadow paints over the background and beneath the content.

Apply conditionally

Hover or keyboard-focus the button to move from a small to a large shadow token. Print removes the shadow while preserving its border and label.

Apply conditionally
box-shadow: Apply conditionally controls
These are the browser’s actual shadow layers. The measured box excludes their paint; theme tokens may resolve differently in each mode.
<!-- Small → large elevation on interaction --><button id="target" type="button"  class="inline-flex items-center justify-center         min-h:44px max-w:100% px-md py-sm         b:1px|solid|var(--color-line-base) r-sm font-md         bg-surface-base text-body shadow-sm         box-border bg-surface-muted:focus-visible         shadow:none@print shadow-lg:hover@screen         shadow-lg:focus-visible@screen">  Open library</button>

The independent focus outline remains visible; a shadow alone should not be the only indication of keyboard focus.

Customize mode-specific tokens

Override a shared shadow token separately in light and dark themes. The live preview compiles these exact declarations; use its theme control to compare the resolved layers.

Customize mode-specific tokens
box-shadow: Customize mode-specific tokens controls
These are the browser’s actual shadow layers. The measured box excludes their paint; theme tokens may resolve differently in each mode.
index.css
@theme light {  --shadow-sm: 0 0 0 1px oklch(0% 0 none / .08),    0 6px 12px -2px oklch(0% 0 none / .14);}@theme dark {  --shadow-sm: 0 0 0 1px oklch(100% 0 none / .16),    0 6px 12px -2px oklch(0% 0 none / .5);}
<!-- Configured small shadow · two theme definitions --><article id="target"  class="w:240px max-w:100% p-lg r-md bg-surface-base         text-body shadow-sm box-border">  <h4 class="m:0 font-lg">    Workspace library  </h4>  <p class="mx:0 mb:0 mt-sm font-sm">    Shared assets and components.  </p></article>

The subtle edge layer helps separate the surface in dark mode. The shadow still occupies no layout space. Prefer shared tokens when the same elevation decision appears across a product.



© 2026 Aoyue Design LLC.MIT License
Trademark Policy