07 / 20
All 20 in 20 CSS Claymorphism
- 01Claymorphism Shadow Recipe Reference Build
- 02Inner Highlight and Inner Shadow Layering
- 03Border Radius Scale for Puffy Shapes
- 04Claymorphism vs Neumorphism Side by Side
- 05Claymorphism with Glassmorphism Hybrid
- 06Light Source Consistency Across a Clay Layout
- 07Clay Depth Tiers for Visual Hierarchy
- 08Tailwind CSS Claymorphism Implementation
- 09Clay Button Press and Squish States
- 10Clay Toggle Switch and Checkbox Set
- 11Clay Input Field and Search Bar
- 12Clay Badge & Pill Tag System
- 13Claymorphism Card Component
- 14Clay Modal Dialog with Floating Depth
- 15Clay Pricing Table with Raised Popular Tier
- 16Clay Bottom Tab Bar for Mobile
- 17Clay Icon Tiles and App Grid
- 18Clay Toast & Floating Alert Bubbles
- 19Clay Dark Mode Shadow Recalibration
- 20Clay Animation Performance & Transform Optimization
Clay Depth Tiers for Visual Hierarchy
Four elevation tiers — inset well, resting, raised, floating — driven by a single --elev number per element. Every shadow length, blur and highlight strength is computed from it with calc(), so a component changes tier by changing one integer. Hover promotes a card one tier, which is how clay communicates interactivity without borders or color changes.
Untitled UI Pro: a 10,000+ component Figma UI kit · from $129 one-time
Untitled UI · Affiliate link
The code
<section class="cl-07" aria-label="Clay depth tiers for visual hierarchy demo">
<div class="cl-07__stage">
<header class="cl-07__head">
<h2 class="cl-07__h">Four tiers, one number</h2>
<p class="cl-07__lede">Hover any tile: it is promoted exactly one tier. Every length below is calc()-derived from <code>--elev</code>.</p>
</header>
<div class="cl-07__well">
<p class="cl-07__wellLabel">Tier 0 — inset well · holds content</p>
<div class="cl-07__row">
<article class="cl-07__tile" style="--cl-07-elev:1">
<b class="cl-07__t">Tier 1</b>
<span class="cl-07__d">Resting surface</span>
<span class="cl-07__use">lists, groups, rows</span>
</article>
<article class="cl-07__tile" style="--cl-07-elev:2">
<b class="cl-07__t">Tier 2</b>
<span class="cl-07__d">Raised surface</span>
<span class="cl-07__use">cards, buttons, tabs</span>
</article>
<article class="cl-07__tile" style="--cl-07-elev:3">
<b class="cl-07__t">Tier 3</b>
<span class="cl-07__d">Floating surface</span>
<span class="cl-07__use">menus, popovers, FABs</span>
</article>
</div>
</div>
<p class="cl-07__chip" aria-hidden="true">--elev drives shadow length + blur + highlight + translate</p>
</div>
</section><section class="cl-07" aria-label="Clay depth tiers for visual hierarchy demo">
<div class="cl-07__stage">
<header class="cl-07__head">
<h2 class="cl-07__h">Four tiers, one number</h2>
<p class="cl-07__lede">Hover any tile: it is promoted exactly one tier. Every length below is calc()-derived from <code>--elev</code>.</p>
</header>
<div class="cl-07__well">
<p class="cl-07__wellLabel">Tier 0 — inset well · holds content</p>
<div class="cl-07__row">
<article class="cl-07__tile" style="--cl-07-elev:1">
<b class="cl-07__t">Tier 1</b>
<span class="cl-07__d">Resting surface</span>
<span class="cl-07__use">lists, groups, rows</span>
</article>
<article class="cl-07__tile" style="--cl-07-elev:2">
<b class="cl-07__t">Tier 2</b>
<span class="cl-07__d">Raised surface</span>
<span class="cl-07__use">cards, buttons, tabs</span>
</article>
<article class="cl-07__tile" style="--cl-07-elev:3">
<b class="cl-07__t">Tier 3</b>
<span class="cl-07__d">Floating surface</span>
<span class="cl-07__use">menus, popovers, FABs</span>
</article>
</div>
</div>
<p class="cl-07__chip" aria-hidden="true">--elev drives shadow length + blur + highlight + translate</p>
</div>
</section>.cl-07,
.cl-07 *,
.cl-07 *::before,
.cl-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-07 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--cl-07-bg);
--cl-07-bg: oklch(0.93 0.03 15);
--cl-07-clay: oklch(0.88 0.06 20);
--cl-07-shade: oklch(0.58 0.1 18/.55);
--cl-07-light: oklch(1 0.015 40/.95);
--cl-07-ink: oklch(0.3 0.05 20);
--cl-07-mut: oklch(0.51 0.04 20);
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-07-ink);
}
.cl-07__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: clamp(22px,4vw,36px);
padding: clamp(20px,5vw,58px);
background: radial-gradient(80% 55% at 50% 0%,oklch(0.97 0.03 30),transparent 66%);
}
.cl-07__head {
text-align: center;
max-width: 58ch;
display: grid;
gap: 9px;
}
.cl-07__h {
font-size: clamp(24px,3.8vw,34px);
font-weight: 780;
letter-spacing: -.02em;
text-wrap: balance;
}
.cl-07__lede {
font-size: 15px;
line-height: 1.6;
color: var(--cl-07-mut);
text-wrap: pretty;
}
.cl-07__lede code {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 13.5px;
}
.cl-07__well {
width: min(100%,900px);
display: grid;
gap: 16px;
padding: clamp(20px,3vw,32px);
border-radius: 44px;
background: color-mix(in oklch,var(--cl-07-bg) 94%,oklch(0.7 0.06 20));
box-shadow: inset 0 14px 26px -10px var(--cl-07-shade),inset 0 -12px 22px -12px var(--cl-07-light);
}
.cl-07__wellLabel {
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--cl-07-mut);
text-align: center;
}
.cl-07__row {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(196px,1fr));
gap: clamp(16px,2.6vw,26px);
align-items: center;
}
.cl-07__tile {
--cl-07-elev: 2;
display: grid;
gap: 5px;
align-content: center;
min-height: 150px;
padding: 24px;
border-radius: 34px;
background: var(--cl-07-clay);
translate: 0 calc(var(--cl-07-elev) * -1px);
box-shadow: 0 calc(var(--cl-07-elev) * 9px) calc(var(--cl-07-elev) * 18px) calc(var(--cl-07-elev) * -5px) var(--cl-07-shade),inset 0 calc(var(--cl-07-elev) * -5px) calc(var(--cl-07-elev) * 9px) -8px var(--cl-07-shade),inset 0 calc(var(--cl-07-elev) * 6px) calc(var(--cl-07-elev) * 9px) -6px var(--cl-07-light);
transition: box-shadow .4s cubic-bezier(.4,0,.2,1),translate .4s cubic-bezier(.34,1.3,.5,1),scale .4s cubic-bezier(.34,1.3,.5,1);
cursor: pointer;
}
.cl-07__tile:nth-child(1):hover,
.cl-07__tile:nth-child(1):focus-visible {
--cl-07-elev: 2;
}
.cl-07__tile:nth-child(2):hover,
.cl-07__tile:nth-child(2):focus-visible {
--cl-07-elev: 3;
}
.cl-07__tile:nth-child(3):hover,
.cl-07__tile:nth-child(3):focus-visible {
--cl-07-elev: 4;
scale: 1.02;
}
.cl-07__tile:active {
--cl-07-elev: 0;
translate: 0;
box-shadow: inset 0 12px 22px -8px var(--cl-07-shade),inset 0 -10px 18px -10px var(--cl-07-light);
}
.cl-07__t {
font-size: 12px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: color-mix(in oklch,var(--cl-07-ink) 60%,transparent);
}
.cl-07__d {
font-size: 19px;
font-weight: 740;
letter-spacing: -.015em;
}
.cl-07__use {
font-size: 13px;
color: color-mix(in oklch,var(--cl-07-ink) 72%,transparent);
}
.cl-07__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--cl-07-mut);
padding: 9px 16px;
border-radius: 99px;
text-align: center;
background: oklch(1 0 0/.55);
box-shadow: inset 0 -4px 10px -8px var(--cl-07-shade),inset 0 6px 10px -6px oklch(1 0 0);
}
@media (prefers-reduced-motion: reduce) {
.cl-07 * {
transition-duration: .01ms !important;
}
}.cl-07,
.cl-07 *,
.cl-07 *::before,
.cl-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-07 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--cl-07-bg);
--cl-07-bg: oklch(0.93 0.03 15);
--cl-07-clay: oklch(0.88 0.06 20);
--cl-07-shade: oklch(0.58 0.1 18/.55);
--cl-07-light: oklch(1 0.015 40/.95);
--cl-07-ink: oklch(0.3 0.05 20);
--cl-07-mut: oklch(0.51 0.04 20);
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-07-ink);
}
.cl-07__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: clamp(22px,4vw,36px);
padding: clamp(20px,5vw,58px);
background: radial-gradient(80% 55% at 50% 0%,oklch(0.97 0.03 30),transparent 66%);
}
.cl-07__head {
text-align: center;
max-width: 58ch;
display: grid;
gap: 9px;
}
.cl-07__h {
font-size: clamp(24px,3.8vw,34px);
font-weight: 780;
letter-spacing: -.02em;
text-wrap: balance;
}
.cl-07__lede {
font-size: 15px;
line-height: 1.6;
color: var(--cl-07-mut);
text-wrap: pretty;
}
.cl-07__lede code {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 13.5px;
}
.cl-07__well {
width: min(100%,900px);
display: grid;
gap: 16px;
padding: clamp(20px,3vw,32px);
border-radius: 44px;
background: color-mix(in oklch,var(--cl-07-bg) 94%,oklch(0.7 0.06 20));
box-shadow: inset 0 14px 26px -10px var(--cl-07-shade),inset 0 -12px 22px -12px var(--cl-07-light);
}
.cl-07__wellLabel {
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--cl-07-mut);
text-align: center;
}
.cl-07__row {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(196px,1fr));
gap: clamp(16px,2.6vw,26px);
align-items: center;
}
.cl-07__tile {
--cl-07-elev: 2;
display: grid;
gap: 5px;
align-content: center;
min-height: 150px;
padding: 24px;
border-radius: 34px;
background: var(--cl-07-clay);
translate: 0 calc(var(--cl-07-elev) * -1px);
box-shadow: 0 calc(var(--cl-07-elev) * 9px) calc(var(--cl-07-elev) * 18px) calc(var(--cl-07-elev) * -5px) var(--cl-07-shade),inset 0 calc(var(--cl-07-elev) * -5px) calc(var(--cl-07-elev) * 9px) -8px var(--cl-07-shade),inset 0 calc(var(--cl-07-elev) * 6px) calc(var(--cl-07-elev) * 9px) -6px var(--cl-07-light);
transition: box-shadow .4s cubic-bezier(.4,0,.2,1),translate .4s cubic-bezier(.34,1.3,.5,1),scale .4s cubic-bezier(.34,1.3,.5,1);
cursor: pointer;
}
.cl-07__tile:nth-child(1):hover,
.cl-07__tile:nth-child(1):focus-visible {
--cl-07-elev: 2;
}
.cl-07__tile:nth-child(2):hover,
.cl-07__tile:nth-child(2):focus-visible {
--cl-07-elev: 3;
}
.cl-07__tile:nth-child(3):hover,
.cl-07__tile:nth-child(3):focus-visible {
--cl-07-elev: 4;
scale: 1.02;
}
.cl-07__tile:active {
--cl-07-elev: 0;
translate: 0;
box-shadow: inset 0 12px 22px -8px var(--cl-07-shade),inset 0 -10px 18px -10px var(--cl-07-light);
}
.cl-07__t {
font-size: 12px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: color-mix(in oklch,var(--cl-07-ink) 60%,transparent);
}
.cl-07__d {
font-size: 19px;
font-weight: 740;
letter-spacing: -.015em;
}
.cl-07__use {
font-size: 13px;
color: color-mix(in oklch,var(--cl-07-ink) 72%,transparent);
}
.cl-07__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--cl-07-mut);
padding: 9px 16px;
border-radius: 99px;
text-align: center;
background: oklch(1 0 0/.55);
box-shadow: inset 0 -4px 10px -8px var(--cl-07-shade),inset 0 6px 10px -6px oklch(1 0 0);
}
@media (prefers-reduced-motion: reduce) {
.cl-07 * {
transition-duration: .01ms !important;
}
}Here's a working CSS Claymorphism from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Clay Depth Tiers for Visual Hierarchy
Source: https://codefronts.com/design-styles/css-claymorphism/clay-depth-tiers-for-visual-hierarchy/
Four elevation tiers — inset well, resting, raised, floating — driven by a single --elev number per element. Every shadow length, blur and highlight strength is computed from it with calc(), so a component changes tier by changing one integer. Hover promotes a card one tier, which is how clay communicates interactivity without borders or color changes.
## HTML
```html
<section class="cl-07" aria-label="Clay depth tiers for visual hierarchy demo">
<div class="cl-07__stage">
<header class="cl-07__head">
<h2 class="cl-07__h">Four tiers, one number</h2>
<p class="cl-07__lede">Hover any tile: it is promoted exactly one tier. Every length below is calc()-derived from <code>--elev</code>.</p>
</header>
<div class="cl-07__well">
<p class="cl-07__wellLabel">Tier 0 — inset well · holds content</p>
<div class="cl-07__row">
<article class="cl-07__tile" style="--cl-07-elev:1">
<b class="cl-07__t">Tier 1</b>
<span class="cl-07__d">Resting surface</span>
<span class="cl-07__use">lists, groups, rows</span>
</article>
<article class="cl-07__tile" style="--cl-07-elev:2">
<b class="cl-07__t">Tier 2</b>
<span class="cl-07__d">Raised surface</span>
<span class="cl-07__use">cards, buttons, tabs</span>
</article>
<article class="cl-07__tile" style="--cl-07-elev:3">
<b class="cl-07__t">Tier 3</b>
<span class="cl-07__d">Floating surface</span>
<span class="cl-07__use">menus, popovers, FABs</span>
</article>
</div>
</div>
<p class="cl-07__chip" aria-hidden="true">--elev drives shadow length + blur + highlight + translate</p>
</div>
</section>
```
## CSS
```css
.cl-07,
.cl-07 *,
.cl-07 *::before,
.cl-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-07 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--cl-07-bg);
--cl-07-bg: oklch(0.93 0.03 15);
--cl-07-clay: oklch(0.88 0.06 20);
--cl-07-shade: oklch(0.58 0.1 18/.55);
--cl-07-light: oklch(1 0.015 40/.95);
--cl-07-ink: oklch(0.3 0.05 20);
--cl-07-mut: oklch(0.51 0.04 20);
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-07-ink);
}
.cl-07__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: clamp(22px,4vw,36px);
padding: clamp(20px,5vw,58px);
background: radial-gradient(80% 55% at 50% 0%,oklch(0.97 0.03 30),transparent 66%);
}
.cl-07__head {
text-align: center;
max-width: 58ch;
display: grid;
gap: 9px;
}
.cl-07__h {
font-size: clamp(24px,3.8vw,34px);
font-weight: 780;
letter-spacing: -.02em;
text-wrap: balance;
}
.cl-07__lede {
font-size: 15px;
line-height: 1.6;
color: var(--cl-07-mut);
text-wrap: pretty;
}
.cl-07__lede code {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 13.5px;
}
.cl-07__well {
width: min(100%,900px);
display: grid;
gap: 16px;
padding: clamp(20px,3vw,32px);
border-radius: 44px;
background: color-mix(in oklch,var(--cl-07-bg) 94%,oklch(0.7 0.06 20));
box-shadow: inset 0 14px 26px -10px var(--cl-07-shade),inset 0 -12px 22px -12px var(--cl-07-light);
}
.cl-07__wellLabel {
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--cl-07-mut);
text-align: center;
}
.cl-07__row {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(196px,1fr));
gap: clamp(16px,2.6vw,26px);
align-items: center;
}
.cl-07__tile {
--cl-07-elev: 2;
display: grid;
gap: 5px;
align-content: center;
min-height: 150px;
padding: 24px;
border-radius: 34px;
background: var(--cl-07-clay);
translate: 0 calc(var(--cl-07-elev) * -1px);
box-shadow: 0 calc(var(--cl-07-elev) * 9px) calc(var(--cl-07-elev) * 18px) calc(var(--cl-07-elev) * -5px) var(--cl-07-shade),inset 0 calc(var(--cl-07-elev) * -5px) calc(var(--cl-07-elev) * 9px) -8px var(--cl-07-shade),inset 0 calc(var(--cl-07-elev) * 6px) calc(var(--cl-07-elev) * 9px) -6px var(--cl-07-light);
transition: box-shadow .4s cubic-bezier(.4,0,.2,1),translate .4s cubic-bezier(.34,1.3,.5,1),scale .4s cubic-bezier(.34,1.3,.5,1);
cursor: pointer;
}
.cl-07__tile:nth-child(1):hover,
.cl-07__tile:nth-child(1):focus-visible {
--cl-07-elev: 2;
}
.cl-07__tile:nth-child(2):hover,
.cl-07__tile:nth-child(2):focus-visible {
--cl-07-elev: 3;
}
.cl-07__tile:nth-child(3):hover,
.cl-07__tile:nth-child(3):focus-visible {
--cl-07-elev: 4;
scale: 1.02;
}
.cl-07__tile:active {
--cl-07-elev: 0;
translate: 0;
box-shadow: inset 0 12px 22px -8px var(--cl-07-shade),inset 0 -10px 18px -10px var(--cl-07-light);
}
.cl-07__t {
font-size: 12px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: color-mix(in oklch,var(--cl-07-ink) 60%,transparent);
}
.cl-07__d {
font-size: 19px;
font-weight: 740;
letter-spacing: -.015em;
}
.cl-07__use {
font-size: 13px;
color: color-mix(in oklch,var(--cl-07-ink) 72%,transparent);
}
.cl-07__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--cl-07-mut);
padding: 9px 16px;
border-radius: 99px;
text-align: center;
background: oklch(1 0 0/.55);
box-shadow: inset 0 -4px 10px -8px var(--cl-07-shade),inset 0 6px 10px -6px oklch(1 0 0);
}
@media (prefers-reduced-motion: reduce) {
.cl-07 * {
transition-duration: .01ms !important;
}
}
```Here's a working CSS Claymorphism from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Clay Depth Tiers for Visual Hierarchy
Source: https://codefronts.com/design-styles/css-claymorphism/clay-depth-tiers-for-visual-hierarchy/
Four elevation tiers — inset well, resting, raised, floating — driven by a single --elev number per element. Every shadow length, blur and highlight strength is computed from it with calc(), so a component changes tier by changing one integer. Hover promotes a card one tier, which is how clay communicates interactivity without borders or color changes.
## HTML
```html
<section class="cl-07" aria-label="Clay depth tiers for visual hierarchy demo">
<div class="cl-07__stage">
<header class="cl-07__head">
<h2 class="cl-07__h">Four tiers, one number</h2>
<p class="cl-07__lede">Hover any tile: it is promoted exactly one tier. Every length below is calc()-derived from <code>--elev</code>.</p>
</header>
<div class="cl-07__well">
<p class="cl-07__wellLabel">Tier 0 — inset well · holds content</p>
<div class="cl-07__row">
<article class="cl-07__tile" style="--cl-07-elev:1">
<b class="cl-07__t">Tier 1</b>
<span class="cl-07__d">Resting surface</span>
<span class="cl-07__use">lists, groups, rows</span>
</article>
<article class="cl-07__tile" style="--cl-07-elev:2">
<b class="cl-07__t">Tier 2</b>
<span class="cl-07__d">Raised surface</span>
<span class="cl-07__use">cards, buttons, tabs</span>
</article>
<article class="cl-07__tile" style="--cl-07-elev:3">
<b class="cl-07__t">Tier 3</b>
<span class="cl-07__d">Floating surface</span>
<span class="cl-07__use">menus, popovers, FABs</span>
</article>
</div>
</div>
<p class="cl-07__chip" aria-hidden="true">--elev drives shadow length + blur + highlight + translate</p>
</div>
</section>
```
## CSS
```css
.cl-07,
.cl-07 *,
.cl-07 *::before,
.cl-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-07 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--cl-07-bg);
--cl-07-bg: oklch(0.93 0.03 15);
--cl-07-clay: oklch(0.88 0.06 20);
--cl-07-shade: oklch(0.58 0.1 18/.55);
--cl-07-light: oklch(1 0.015 40/.95);
--cl-07-ink: oklch(0.3 0.05 20);
--cl-07-mut: oklch(0.51 0.04 20);
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-07-ink);
}
.cl-07__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: clamp(22px,4vw,36px);
padding: clamp(20px,5vw,58px);
background: radial-gradient(80% 55% at 50% 0%,oklch(0.97 0.03 30),transparent 66%);
}
.cl-07__head {
text-align: center;
max-width: 58ch;
display: grid;
gap: 9px;
}
.cl-07__h {
font-size: clamp(24px,3.8vw,34px);
font-weight: 780;
letter-spacing: -.02em;
text-wrap: balance;
}
.cl-07__lede {
font-size: 15px;
line-height: 1.6;
color: var(--cl-07-mut);
text-wrap: pretty;
}
.cl-07__lede code {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 13.5px;
}
.cl-07__well {
width: min(100%,900px);
display: grid;
gap: 16px;
padding: clamp(20px,3vw,32px);
border-radius: 44px;
background: color-mix(in oklch,var(--cl-07-bg) 94%,oklch(0.7 0.06 20));
box-shadow: inset 0 14px 26px -10px var(--cl-07-shade),inset 0 -12px 22px -12px var(--cl-07-light);
}
.cl-07__wellLabel {
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--cl-07-mut);
text-align: center;
}
.cl-07__row {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(196px,1fr));
gap: clamp(16px,2.6vw,26px);
align-items: center;
}
.cl-07__tile {
--cl-07-elev: 2;
display: grid;
gap: 5px;
align-content: center;
min-height: 150px;
padding: 24px;
border-radius: 34px;
background: var(--cl-07-clay);
translate: 0 calc(var(--cl-07-elev) * -1px);
box-shadow: 0 calc(var(--cl-07-elev) * 9px) calc(var(--cl-07-elev) * 18px) calc(var(--cl-07-elev) * -5px) var(--cl-07-shade),inset 0 calc(var(--cl-07-elev) * -5px) calc(var(--cl-07-elev) * 9px) -8px var(--cl-07-shade),inset 0 calc(var(--cl-07-elev) * 6px) calc(var(--cl-07-elev) * 9px) -6px var(--cl-07-light);
transition: box-shadow .4s cubic-bezier(.4,0,.2,1),translate .4s cubic-bezier(.34,1.3,.5,1),scale .4s cubic-bezier(.34,1.3,.5,1);
cursor: pointer;
}
.cl-07__tile:nth-child(1):hover,
.cl-07__tile:nth-child(1):focus-visible {
--cl-07-elev: 2;
}
.cl-07__tile:nth-child(2):hover,
.cl-07__tile:nth-child(2):focus-visible {
--cl-07-elev: 3;
}
.cl-07__tile:nth-child(3):hover,
.cl-07__tile:nth-child(3):focus-visible {
--cl-07-elev: 4;
scale: 1.02;
}
.cl-07__tile:active {
--cl-07-elev: 0;
translate: 0;
box-shadow: inset 0 12px 22px -8px var(--cl-07-shade),inset 0 -10px 18px -10px var(--cl-07-light);
}
.cl-07__t {
font-size: 12px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: color-mix(in oklch,var(--cl-07-ink) 60%,transparent);
}
.cl-07__d {
font-size: 19px;
font-weight: 740;
letter-spacing: -.015em;
}
.cl-07__use {
font-size: 13px;
color: color-mix(in oklch,var(--cl-07-ink) 72%,transparent);
}
.cl-07__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--cl-07-mut);
padding: 9px 16px;
border-radius: 99px;
text-align: center;
background: oklch(1 0 0/.55);
box-shadow: inset 0 -4px 10px -8px var(--cl-07-shade),inset 0 6px 10px -6px oklch(1 0 0);
}
@media (prefers-reduced-motion: reduce) {
.cl-07 * {
transition-duration: .01ms !important;
}
}
```How this works
Material's elevation scale works because it is arithmetic, not taste. Same here — one number feeds every layer:
.clay{
--elev: 2; /* 0 = inset well, 1..3 = lifted */
box-shadow:
0 calc(var(--elev) * 9px) calc(var(--elev) * 18px) calc(var(--elev) * -5px) var(--shade),
inset 0 calc(var(--elev) * -5px) calc(var(--elev) * 9px) -8px var(--shade),
inset 0 calc(var(--elev) * 6px) calc(var(--elev) * 9px) -6px var(--light);
translate: 0 calc(var(--elev) * -1px);
}
.clay:hover{ --elev: 3; } /* promote one tier */Tier 0 is the special case: instead of a drop shadow it flips the insets, producing a well — the container things sit in. That gives you a complete vocabulary: wells hold, resting surfaces group, raised surfaces act, floating surfaces interrupt.
The tiny translate tied to the same number is what sells it. Real objects rise as their shadow grows; moving the element up 1-3px while the shadow lengthens reads as lift rather than as a shadow that mysteriously got bigger. Because translate is compositor-only, the movement is free even while the shadow repaints.
Discipline rule: never skip a tier. A jump from resting to floating on hover looks like a bug; one tier per interaction step is the entire trick.
Make it yours
- Add a tier 4 for modals and toasts (
--elev:4plus a page scrim) — demo 14 and 18 use exactly that. - Tone the shade alpha with the tier as well:
color-mix(in oklch, var(--shade) calc(var(--elev) * 22%), transparent)makes high tiers read heavier, not just longer. - Pressed state = tier 0: set
--elev:0on:activeand any raised control becomes a well while held. One line, physically correct. - Container queries: drop every tier by 1 inside narrow containers so mobile layouts stay flat and fast.
Gotchas — read before shipping
- calc() inside box-shadow cannot use a unitless var directly for lengths — multiply by a unit (
calc(var(--elev) * 9px)), nevercalc(var(--elev)px). - Tier 0 must not also carry an outer drop shadow; a well that casts a shadow is visually incoherent.
- More than 4 tiers stops being perceivable. If you need more separation, change hue or size instead of depth.
- Shadows do not stack cleanly across overflow:hidden boundaries — a floating child inside a clipped well gets its shadow cut. Promote it out of the well in the DOM.
- Hover-only tier promotion is invisible on touch. Pair it with :active and :focus-visible.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 114+ | 17.5+ | 121+ | 114+ |
Floor set by oklch(), color-mix(), text-wrap as this demo is written. The core technique itself goes back further — Chrome 88+.
calc() in box-shadow lengths and the translate property are broadly supported (translate as a standalone property: Chrome 104 / Safari 14.1 / Firefox 72). oklch()/color-mix() theming is the only modern floor.