box-shadow
Adding light and dark shadow effects around an element.
Overview
| Class | Declarations |
|---|---|
shadow-xs | box-shadow: var(--shadow-xs);
|
shadow-sm | box-shadow: var(--shadow-sm);
|
shadow-md | box-shadow: var(--shadow-md);
|
shadow-lg | box-shadow: var(--shadow-lg);
|
shadow-xl | box-shadow: var(--shadow-xl);
|
shadow-2xl | box-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.
<!-- 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.
<!-- 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.
<!-- 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.
<!-- 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.
@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.