11 / 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 Input Field and Search Bar
Inputs are the one place clay inverts: a field you type into must be a well, not a lifted object. This set gets it right — an inset search bar with a suggestion tray on focus, a floating-label field, a textarea that grows with field-sizing:content, and validation styled with :user-invalid so errors appear only after the user finishes.
Untitled UI Pro: a 10,000+ component Figma UI kit · from $129 one-time
Untitled UI · Affiliate link
The code
<section class="cl-11" aria-label="Clay input field and search bar demo">
<div class="cl-11__stage">
<div class="cl-11__panel">
<div class="cl-11__searchWrap">
<label class="cl-11__lab" for="cl-11-search">Search lessons</label>
<div class="cl-11__shell cl-11__shell--search">
<svg class="cl-11__icon" viewBox="0 0 24 24" width="20" height="20" aria-hidden="true"><path d="M10.5 3a7.5 7.5 0 015.9 12.1l4.3 4.3-1.4 1.4-4.3-4.3A7.5 7.5 0 1110.5 3zm0 2a5.5 5.5 0 100 11 5.5 5.5 0 000-11z" fill="currentColor"/></svg>
<input class="cl-11__input" type="search" id="cl-11-search" placeholder="Try "inset shadows"" autocomplete="off">
<kbd class="cl-11__kbd">/</kbd>
</div>
<ul class="cl-11__tray" role="listbox" aria-label="Suggestions">
<li role="option" aria-selected="false"><b>inset box-shadow</b> · technique</li>
<li role="option" aria-selected="false"><b>clay vs neumorphism</b> · comparison</li>
<li role="option" aria-selected="false"><b>puffy radius scale</b> · reference</li>
</ul>
</div>
<div class="cl-11__grid">
<div class="cl-11__floatWrap">
<div class="cl-11__shell">
<input class="cl-11__input cl-11__input--float" type="text" id="cl-11-name" placeholder=" ">
<label class="cl-11__float" for="cl-11-name">Display name</label>
</div>
</div>
<div class="cl-11__floatWrap">
<div class="cl-11__shell">
<input class="cl-11__input cl-11__input--float" type="email" id="cl-11-mail" placeholder=" " required>
<label class="cl-11__float" for="cl-11-mail">Email address</label>
</div>
<p class="cl-11__hint">We only email your weekly streak.</p>
</div>
</div>
<div>
<label class="cl-11__lab" for="cl-11-note">Practice note</label>
<div class="cl-11__shell cl-11__shell--area">
<textarea class="cl-11__area" id="cl-11-note" rows="2" placeholder="What did you learn today?"></textarea>
</div>
</div>
</div>
<p class="cl-11__chip" aria-hidden="true">field = well · :focus-within ring · :user-invalid · @starting-style tray · field-sizing</p>
</div>
</section><section class="cl-11" aria-label="Clay input field and search bar demo">
<div class="cl-11__stage">
<div class="cl-11__panel">
<div class="cl-11__searchWrap">
<label class="cl-11__lab" for="cl-11-search">Search lessons</label>
<div class="cl-11__shell cl-11__shell--search">
<svg class="cl-11__icon" viewBox="0 0 24 24" width="20" height="20" aria-hidden="true"><path d="M10.5 3a7.5 7.5 0 015.9 12.1l4.3 4.3-1.4 1.4-4.3-4.3A7.5 7.5 0 1110.5 3zm0 2a5.5 5.5 0 100 11 5.5 5.5 0 000-11z" fill="currentColor"/></svg>
<input class="cl-11__input" type="search" id="cl-11-search" placeholder="Try "inset shadows"" autocomplete="off">
<kbd class="cl-11__kbd">/</kbd>
</div>
<ul class="cl-11__tray" role="listbox" aria-label="Suggestions">
<li role="option" aria-selected="false"><b>inset box-shadow</b> · technique</li>
<li role="option" aria-selected="false"><b>clay vs neumorphism</b> · comparison</li>
<li role="option" aria-selected="false"><b>puffy radius scale</b> · reference</li>
</ul>
</div>
<div class="cl-11__grid">
<div class="cl-11__floatWrap">
<div class="cl-11__shell">
<input class="cl-11__input cl-11__input--float" type="text" id="cl-11-name" placeholder=" ">
<label class="cl-11__float" for="cl-11-name">Display name</label>
</div>
</div>
<div class="cl-11__floatWrap">
<div class="cl-11__shell">
<input class="cl-11__input cl-11__input--float" type="email" id="cl-11-mail" placeholder=" " required>
<label class="cl-11__float" for="cl-11-mail">Email address</label>
</div>
<p class="cl-11__hint">We only email your weekly streak.</p>
</div>
</div>
<div>
<label class="cl-11__lab" for="cl-11-note">Practice note</label>
<div class="cl-11__shell cl-11__shell--area">
<textarea class="cl-11__area" id="cl-11-note" rows="2" placeholder="What did you learn today?"></textarea>
</div>
</div>
</div>
<p class="cl-11__chip" aria-hidden="true">field = well · :focus-within ring · :user-invalid · @starting-style tray · field-sizing</p>
</div>
</section>.cl-11,
.cl-11 *,
.cl-11 *::before,
.cl-11 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-11 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--cl-11-bg);
--cl-11-bg: oklch(0.94 0.025 230);
--cl-11-clay: oklch(0.89 0.045 235);
--cl-11-accent: oklch(0.72 0.14 240);
--cl-11-error: oklch(0.62 0.19 25);
--cl-11-shade: oklch(0.55 0.08 235/.6);
--cl-11-light: oklch(1 0.01 235/.95);
--cl-11-ink: oklch(0.28 0.045 235);
--cl-11-mut: oklch(0.5 0.035 235);
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-11-ink);
}
.cl-11__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: 20px;
padding: clamp(20px,5vw,56px);
}
.cl-11__panel {
width: min(100%,600px);
display: grid;
gap: clamp(18px,3vw,24px);
padding: clamp(22px,3.4vw,34px);
border-radius: 42px;
background: color-mix(in oklch,var(--cl-11-bg) 92%,white);
box-shadow: 0 30px 60px -24px var(--cl-11-shade),inset 0 -16px 28px -16px var(--cl-11-shade),inset 0 18px 28px -12px var(--cl-11-light);
}
.cl-11__lab {
display: block;
margin-bottom: 9px;
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--cl-11-mut);
}
.cl-11__searchWrap {
position: relative;
}
.cl-11__shell {
display: flex;
align-items: center;
gap: 12px;
padding: 0 18px;
border-radius: 24px;
background: color-mix(in oklch,var(--cl-11-bg) 93%,oklch(0.6 0.06 235));
box-shadow: inset 0 10px 18px -6px var(--cl-11-shade),inset 0 -8px 14px -10px var(--cl-11-light);
transition: box-shadow .28s;
}
.cl-11__shell:focus-within {
box-shadow: inset 0 8px 14px -8px var(--cl-11-shade),inset 0 -6px 12px -10px var(--cl-11-light),0 0 0 4px color-mix(in oklch,var(--cl-11-accent) 42%,transparent);
}
.cl-11__shell--search {
border-radius: 99px;
}
.cl-11__shell--area {
border-radius: 24px;
padding: 14px 18px;
}
.cl-11__icon {
flex: none;
color: var(--cl-11-mut);
}
.cl-11__input {
flex: 1;
min-width: 0;
min-height: 56px;
border: 0;
background: none;
font: inherit;
font-size: 15px;
color: var(--cl-11-ink);
outline: none;
}
.cl-11__input::placeholder {
color: color-mix(in oklch,var(--cl-11-mut) 88%,transparent);
}
.cl-11__input::-webkit-search-cancel-button {
filter: grayscale(1) opacity(.6);
}
.cl-11__kbd {
flex: none;
display: grid;
place-items: center;
width: 26px;
height: 26px;
border-radius: 9px;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 12px;
color: var(--cl-11-mut);
background: color-mix(in oklch,var(--cl-11-bg) 82%,white);
box-shadow: 0 4px 8px -5px var(--cl-11-shade),inset 0 5px 7px -5px var(--cl-11-light);
}
.cl-11__tray {
position: absolute;
left: 0;
right: 0;
top: calc(100% + 10px);
z-index: 2;
list-style: none;
display: none;
opacity: 0;
translate: 0 -8px;
padding: 10px;
border-radius: 26px;
background: color-mix(in oklch,var(--cl-11-bg) 96%,white);
box-shadow: 0 26px 50px -20px var(--cl-11-shade),inset 0 -12px 22px -16px var(--cl-11-shade),inset 0 14px 22px -12px var(--cl-11-light);
transition: opacity .26s,translate .26s,display .26s allow-discrete;
}
.cl-11__searchWrap:focus-within .cl-11__tray {
display: grid;
opacity: 1;
translate: 0;
}
@starting-style {
.cl-11__searchWrap:focus-within .cl-11__tray {
opacity: 0;
translate: 0 -8px;
}
}
.cl-11__tray li {
padding: 12px 16px;
border-radius: 18px;
font-size: 13.5px;
color: var(--cl-11-mut);
cursor: pointer;
transition: background .2s;
}
.cl-11__tray li b {
color: var(--cl-11-ink);
font-weight: 660;
}
.cl-11__tray li:hover {
background: color-mix(in oklch,var(--cl-11-accent) 16%,transparent);
}
.cl-11__grid {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(210px,1fr));
gap: 16px;
}
.cl-11__floatWrap .cl-11__shell {
position: relative;
padding-top: 6px;
}
.cl-11__input--float {
min-height: 60px;
padding-top: 14px;
}
.cl-11__float {
position: absolute;
left: 19px;
top: 19px;
font-size: 15px;
color: var(--cl-11-mut);
pointer-events: none;
transition: translate .22s cubic-bezier(.2,.8,.3,1),font-size .22s,color .22s;
}
.cl-11__input--float:focus+.cl-11__float,
.cl-11__input--float:not(:placeholder-shown)+.cl-11__float {
translate: 0 -13px;
font-size: 11px;
font-weight: 700;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--cl-11-accent);
}
.cl-11__hint {
margin-top: 8px;
padding-left: 6px;
font-size: 12.5px;
color: var(--cl-11-mut);
transition: color .25s;
}
.cl-11__floatWrap:has(:user-invalid) .cl-11__shell {
box-shadow: inset 0 10px 18px -6px color-mix(in oklch,var(--cl-11-error) 55%,transparent),inset 0 -8px 14px -10px var(--cl-11-light),0 0 0 3px color-mix(in oklch,var(--cl-11-error) 55%,transparent);
}
.cl-11__floatWrap:has(:user-invalid) .cl-11__hint {
color: var(--cl-11-error);
}
.cl-11__floatWrap:has(:user-invalid) .cl-11__hint::before {
content: 'Check this address — ';
font-weight: 680;
}
.cl-11__area {
width: 100%;
border: 0;
background: none;
font: inherit;
font-size: 15px;
line-height: 1.6;
color: var(--cl-11-ink);
outline: none;
resize: none;
field-sizing: content;
min-height: 64px;
max-height: 180px;
}
.cl-11__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--cl-11-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-11-shade),inset 0 6px 10px -6px oklch(1 0 0);
}
@media (prefers-reduced-motion: reduce) {
.cl-11 * {
transition-duration: .01ms !important;
}
}.cl-11,
.cl-11 *,
.cl-11 *::before,
.cl-11 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-11 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--cl-11-bg);
--cl-11-bg: oklch(0.94 0.025 230);
--cl-11-clay: oklch(0.89 0.045 235);
--cl-11-accent: oklch(0.72 0.14 240);
--cl-11-error: oklch(0.62 0.19 25);
--cl-11-shade: oklch(0.55 0.08 235/.6);
--cl-11-light: oklch(1 0.01 235/.95);
--cl-11-ink: oklch(0.28 0.045 235);
--cl-11-mut: oklch(0.5 0.035 235);
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-11-ink);
}
.cl-11__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: 20px;
padding: clamp(20px,5vw,56px);
}
.cl-11__panel {
width: min(100%,600px);
display: grid;
gap: clamp(18px,3vw,24px);
padding: clamp(22px,3.4vw,34px);
border-radius: 42px;
background: color-mix(in oklch,var(--cl-11-bg) 92%,white);
box-shadow: 0 30px 60px -24px var(--cl-11-shade),inset 0 -16px 28px -16px var(--cl-11-shade),inset 0 18px 28px -12px var(--cl-11-light);
}
.cl-11__lab {
display: block;
margin-bottom: 9px;
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--cl-11-mut);
}
.cl-11__searchWrap {
position: relative;
}
.cl-11__shell {
display: flex;
align-items: center;
gap: 12px;
padding: 0 18px;
border-radius: 24px;
background: color-mix(in oklch,var(--cl-11-bg) 93%,oklch(0.6 0.06 235));
box-shadow: inset 0 10px 18px -6px var(--cl-11-shade),inset 0 -8px 14px -10px var(--cl-11-light);
transition: box-shadow .28s;
}
.cl-11__shell:focus-within {
box-shadow: inset 0 8px 14px -8px var(--cl-11-shade),inset 0 -6px 12px -10px var(--cl-11-light),0 0 0 4px color-mix(in oklch,var(--cl-11-accent) 42%,transparent);
}
.cl-11__shell--search {
border-radius: 99px;
}
.cl-11__shell--area {
border-radius: 24px;
padding: 14px 18px;
}
.cl-11__icon {
flex: none;
color: var(--cl-11-mut);
}
.cl-11__input {
flex: 1;
min-width: 0;
min-height: 56px;
border: 0;
background: none;
font: inherit;
font-size: 15px;
color: var(--cl-11-ink);
outline: none;
}
.cl-11__input::placeholder {
color: color-mix(in oklch,var(--cl-11-mut) 88%,transparent);
}
.cl-11__input::-webkit-search-cancel-button {
filter: grayscale(1) opacity(.6);
}
.cl-11__kbd {
flex: none;
display: grid;
place-items: center;
width: 26px;
height: 26px;
border-radius: 9px;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 12px;
color: var(--cl-11-mut);
background: color-mix(in oklch,var(--cl-11-bg) 82%,white);
box-shadow: 0 4px 8px -5px var(--cl-11-shade),inset 0 5px 7px -5px var(--cl-11-light);
}
.cl-11__tray {
position: absolute;
left: 0;
right: 0;
top: calc(100% + 10px);
z-index: 2;
list-style: none;
display: none;
opacity: 0;
translate: 0 -8px;
padding: 10px;
border-radius: 26px;
background: color-mix(in oklch,var(--cl-11-bg) 96%,white);
box-shadow: 0 26px 50px -20px var(--cl-11-shade),inset 0 -12px 22px -16px var(--cl-11-shade),inset 0 14px 22px -12px var(--cl-11-light);
transition: opacity .26s,translate .26s,display .26s allow-discrete;
}
.cl-11__searchWrap:focus-within .cl-11__tray {
display: grid;
opacity: 1;
translate: 0;
}
@starting-style {
.cl-11__searchWrap:focus-within .cl-11__tray {
opacity: 0;
translate: 0 -8px;
}
}
.cl-11__tray li {
padding: 12px 16px;
border-radius: 18px;
font-size: 13.5px;
color: var(--cl-11-mut);
cursor: pointer;
transition: background .2s;
}
.cl-11__tray li b {
color: var(--cl-11-ink);
font-weight: 660;
}
.cl-11__tray li:hover {
background: color-mix(in oklch,var(--cl-11-accent) 16%,transparent);
}
.cl-11__grid {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(210px,1fr));
gap: 16px;
}
.cl-11__floatWrap .cl-11__shell {
position: relative;
padding-top: 6px;
}
.cl-11__input--float {
min-height: 60px;
padding-top: 14px;
}
.cl-11__float {
position: absolute;
left: 19px;
top: 19px;
font-size: 15px;
color: var(--cl-11-mut);
pointer-events: none;
transition: translate .22s cubic-bezier(.2,.8,.3,1),font-size .22s,color .22s;
}
.cl-11__input--float:focus+.cl-11__float,
.cl-11__input--float:not(:placeholder-shown)+.cl-11__float {
translate: 0 -13px;
font-size: 11px;
font-weight: 700;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--cl-11-accent);
}
.cl-11__hint {
margin-top: 8px;
padding-left: 6px;
font-size: 12.5px;
color: var(--cl-11-mut);
transition: color .25s;
}
.cl-11__floatWrap:has(:user-invalid) .cl-11__shell {
box-shadow: inset 0 10px 18px -6px color-mix(in oklch,var(--cl-11-error) 55%,transparent),inset 0 -8px 14px -10px var(--cl-11-light),0 0 0 3px color-mix(in oklch,var(--cl-11-error) 55%,transparent);
}
.cl-11__floatWrap:has(:user-invalid) .cl-11__hint {
color: var(--cl-11-error);
}
.cl-11__floatWrap:has(:user-invalid) .cl-11__hint::before {
content: 'Check this address — ';
font-weight: 680;
}
.cl-11__area {
width: 100%;
border: 0;
background: none;
font: inherit;
font-size: 15px;
line-height: 1.6;
color: var(--cl-11-ink);
outline: none;
resize: none;
field-sizing: content;
min-height: 64px;
max-height: 180px;
}
.cl-11__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--cl-11-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-11-shade),inset 0 6px 10px -6px oklch(1 0 0);
}
@media (prefers-reduced-motion: reduce) {
.cl-11 * {
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 Input Field and Search Bar
Source: https://codefronts.com/design-styles/css-claymorphism/clay-input-field-and-search-bar/
Inputs are the one place clay inverts: a field you type into must be a well, not a lifted object. This set gets it right — an inset search bar with a suggestion tray on focus, a floating-label field, a textarea that grows with field-sizing:content, and validation styled with :user-invalid so errors appear only after the user finishes.
## HTML
```html
<section class="cl-11" aria-label="Clay input field and search bar demo">
<div class="cl-11__stage">
<div class="cl-11__panel">
<div class="cl-11__searchWrap">
<label class="cl-11__lab" for="cl-11-search">Search lessons</label>
<div class="cl-11__shell cl-11__shell--search">
<svg class="cl-11__icon" viewBox="0 0 24 24" width="20" height="20" aria-hidden="true"><path d="M10.5 3a7.5 7.5 0 015.9 12.1l4.3 4.3-1.4 1.4-4.3-4.3A7.5 7.5 0 1110.5 3zm0 2a5.5 5.5 0 100 11 5.5 5.5 0 000-11z" fill="currentColor"/></svg>
<input class="cl-11__input" type="search" id="cl-11-search" placeholder="Try "inset shadows"" autocomplete="off">
<kbd class="cl-11__kbd">/</kbd>
</div>
<ul class="cl-11__tray" role="listbox" aria-label="Suggestions">
<li role="option" aria-selected="false"><b>inset box-shadow</b> · technique</li>
<li role="option" aria-selected="false"><b>clay vs neumorphism</b> · comparison</li>
<li role="option" aria-selected="false"><b>puffy radius scale</b> · reference</li>
</ul>
</div>
<div class="cl-11__grid">
<div class="cl-11__floatWrap">
<div class="cl-11__shell">
<input class="cl-11__input cl-11__input--float" type="text" id="cl-11-name" placeholder=" ">
<label class="cl-11__float" for="cl-11-name">Display name</label>
</div>
</div>
<div class="cl-11__floatWrap">
<div class="cl-11__shell">
<input class="cl-11__input cl-11__input--float" type="email" id="cl-11-mail" placeholder=" " required>
<label class="cl-11__float" for="cl-11-mail">Email address</label>
</div>
<p class="cl-11__hint">We only email your weekly streak.</p>
</div>
</div>
<div>
<label class="cl-11__lab" for="cl-11-note">Practice note</label>
<div class="cl-11__shell cl-11__shell--area">
<textarea class="cl-11__area" id="cl-11-note" rows="2" placeholder="What did you learn today?"></textarea>
</div>
</div>
</div>
<p class="cl-11__chip" aria-hidden="true">field = well · :focus-within ring · :user-invalid · @starting-style tray · field-sizing</p>
</div>
</section>
```
## CSS
```css
.cl-11,
.cl-11 *,
.cl-11 *::before,
.cl-11 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-11 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--cl-11-bg);
--cl-11-bg: oklch(0.94 0.025 230);
--cl-11-clay: oklch(0.89 0.045 235);
--cl-11-accent: oklch(0.72 0.14 240);
--cl-11-error: oklch(0.62 0.19 25);
--cl-11-shade: oklch(0.55 0.08 235/.6);
--cl-11-light: oklch(1 0.01 235/.95);
--cl-11-ink: oklch(0.28 0.045 235);
--cl-11-mut: oklch(0.5 0.035 235);
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-11-ink);
}
.cl-11__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: 20px;
padding: clamp(20px,5vw,56px);
}
.cl-11__panel {
width: min(100%,600px);
display: grid;
gap: clamp(18px,3vw,24px);
padding: clamp(22px,3.4vw,34px);
border-radius: 42px;
background: color-mix(in oklch,var(--cl-11-bg) 92%,white);
box-shadow: 0 30px 60px -24px var(--cl-11-shade),inset 0 -16px 28px -16px var(--cl-11-shade),inset 0 18px 28px -12px var(--cl-11-light);
}
.cl-11__lab {
display: block;
margin-bottom: 9px;
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--cl-11-mut);
}
.cl-11__searchWrap {
position: relative;
}
.cl-11__shell {
display: flex;
align-items: center;
gap: 12px;
padding: 0 18px;
border-radius: 24px;
background: color-mix(in oklch,var(--cl-11-bg) 93%,oklch(0.6 0.06 235));
box-shadow: inset 0 10px 18px -6px var(--cl-11-shade),inset 0 -8px 14px -10px var(--cl-11-light);
transition: box-shadow .28s;
}
.cl-11__shell:focus-within {
box-shadow: inset 0 8px 14px -8px var(--cl-11-shade),inset 0 -6px 12px -10px var(--cl-11-light),0 0 0 4px color-mix(in oklch,var(--cl-11-accent) 42%,transparent);
}
.cl-11__shell--search {
border-radius: 99px;
}
.cl-11__shell--area {
border-radius: 24px;
padding: 14px 18px;
}
.cl-11__icon {
flex: none;
color: var(--cl-11-mut);
}
.cl-11__input {
flex: 1;
min-width: 0;
min-height: 56px;
border: 0;
background: none;
font: inherit;
font-size: 15px;
color: var(--cl-11-ink);
outline: none;
}
.cl-11__input::placeholder {
color: color-mix(in oklch,var(--cl-11-mut) 88%,transparent);
}
.cl-11__input::-webkit-search-cancel-button {
filter: grayscale(1) opacity(.6);
}
.cl-11__kbd {
flex: none;
display: grid;
place-items: center;
width: 26px;
height: 26px;
border-radius: 9px;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 12px;
color: var(--cl-11-mut);
background: color-mix(in oklch,var(--cl-11-bg) 82%,white);
box-shadow: 0 4px 8px -5px var(--cl-11-shade),inset 0 5px 7px -5px var(--cl-11-light);
}
.cl-11__tray {
position: absolute;
left: 0;
right: 0;
top: calc(100% + 10px);
z-index: 2;
list-style: none;
display: none;
opacity: 0;
translate: 0 -8px;
padding: 10px;
border-radius: 26px;
background: color-mix(in oklch,var(--cl-11-bg) 96%,white);
box-shadow: 0 26px 50px -20px var(--cl-11-shade),inset 0 -12px 22px -16px var(--cl-11-shade),inset 0 14px 22px -12px var(--cl-11-light);
transition: opacity .26s,translate .26s,display .26s allow-discrete;
}
.cl-11__searchWrap:focus-within .cl-11__tray {
display: grid;
opacity: 1;
translate: 0;
}
@starting-style {
.cl-11__searchWrap:focus-within .cl-11__tray {
opacity: 0;
translate: 0 -8px;
}
}
.cl-11__tray li {
padding: 12px 16px;
border-radius: 18px;
font-size: 13.5px;
color: var(--cl-11-mut);
cursor: pointer;
transition: background .2s;
}
.cl-11__tray li b {
color: var(--cl-11-ink);
font-weight: 660;
}
.cl-11__tray li:hover {
background: color-mix(in oklch,var(--cl-11-accent) 16%,transparent);
}
.cl-11__grid {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(210px,1fr));
gap: 16px;
}
.cl-11__floatWrap .cl-11__shell {
position: relative;
padding-top: 6px;
}
.cl-11__input--float {
min-height: 60px;
padding-top: 14px;
}
.cl-11__float {
position: absolute;
left: 19px;
top: 19px;
font-size: 15px;
color: var(--cl-11-mut);
pointer-events: none;
transition: translate .22s cubic-bezier(.2,.8,.3,1),font-size .22s,color .22s;
}
.cl-11__input--float:focus+.cl-11__float,
.cl-11__input--float:not(:placeholder-shown)+.cl-11__float {
translate: 0 -13px;
font-size: 11px;
font-weight: 700;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--cl-11-accent);
}
.cl-11__hint {
margin-top: 8px;
padding-left: 6px;
font-size: 12.5px;
color: var(--cl-11-mut);
transition: color .25s;
}
.cl-11__floatWrap:has(:user-invalid) .cl-11__shell {
box-shadow: inset 0 10px 18px -6px color-mix(in oklch,var(--cl-11-error) 55%,transparent),inset 0 -8px 14px -10px var(--cl-11-light),0 0 0 3px color-mix(in oklch,var(--cl-11-error) 55%,transparent);
}
.cl-11__floatWrap:has(:user-invalid) .cl-11__hint {
color: var(--cl-11-error);
}
.cl-11__floatWrap:has(:user-invalid) .cl-11__hint::before {
content: 'Check this address — ';
font-weight: 680;
}
.cl-11__area {
width: 100%;
border: 0;
background: none;
font: inherit;
font-size: 15px;
line-height: 1.6;
color: var(--cl-11-ink);
outline: none;
resize: none;
field-sizing: content;
min-height: 64px;
max-height: 180px;
}
.cl-11__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--cl-11-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-11-shade),inset 0 6px 10px -6px oklch(1 0 0);
}
@media (prefers-reduced-motion: reduce) {
.cl-11 * {
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 Input Field and Search Bar
Source: https://codefronts.com/design-styles/css-claymorphism/clay-input-field-and-search-bar/
Inputs are the one place clay inverts: a field you type into must be a well, not a lifted object. This set gets it right — an inset search bar with a suggestion tray on focus, a floating-label field, a textarea that grows with field-sizing:content, and validation styled with :user-invalid so errors appear only after the user finishes.
## HTML
```html
<section class="cl-11" aria-label="Clay input field and search bar demo">
<div class="cl-11__stage">
<div class="cl-11__panel">
<div class="cl-11__searchWrap">
<label class="cl-11__lab" for="cl-11-search">Search lessons</label>
<div class="cl-11__shell cl-11__shell--search">
<svg class="cl-11__icon" viewBox="0 0 24 24" width="20" height="20" aria-hidden="true"><path d="M10.5 3a7.5 7.5 0 015.9 12.1l4.3 4.3-1.4 1.4-4.3-4.3A7.5 7.5 0 1110.5 3zm0 2a5.5 5.5 0 100 11 5.5 5.5 0 000-11z" fill="currentColor"/></svg>
<input class="cl-11__input" type="search" id="cl-11-search" placeholder="Try "inset shadows"" autocomplete="off">
<kbd class="cl-11__kbd">/</kbd>
</div>
<ul class="cl-11__tray" role="listbox" aria-label="Suggestions">
<li role="option" aria-selected="false"><b>inset box-shadow</b> · technique</li>
<li role="option" aria-selected="false"><b>clay vs neumorphism</b> · comparison</li>
<li role="option" aria-selected="false"><b>puffy radius scale</b> · reference</li>
</ul>
</div>
<div class="cl-11__grid">
<div class="cl-11__floatWrap">
<div class="cl-11__shell">
<input class="cl-11__input cl-11__input--float" type="text" id="cl-11-name" placeholder=" ">
<label class="cl-11__float" for="cl-11-name">Display name</label>
</div>
</div>
<div class="cl-11__floatWrap">
<div class="cl-11__shell">
<input class="cl-11__input cl-11__input--float" type="email" id="cl-11-mail" placeholder=" " required>
<label class="cl-11__float" for="cl-11-mail">Email address</label>
</div>
<p class="cl-11__hint">We only email your weekly streak.</p>
</div>
</div>
<div>
<label class="cl-11__lab" for="cl-11-note">Practice note</label>
<div class="cl-11__shell cl-11__shell--area">
<textarea class="cl-11__area" id="cl-11-note" rows="2" placeholder="What did you learn today?"></textarea>
</div>
</div>
</div>
<p class="cl-11__chip" aria-hidden="true">field = well · :focus-within ring · :user-invalid · @starting-style tray · field-sizing</p>
</div>
</section>
```
## CSS
```css
.cl-11,
.cl-11 *,
.cl-11 *::before,
.cl-11 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-11 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--cl-11-bg);
--cl-11-bg: oklch(0.94 0.025 230);
--cl-11-clay: oklch(0.89 0.045 235);
--cl-11-accent: oklch(0.72 0.14 240);
--cl-11-error: oklch(0.62 0.19 25);
--cl-11-shade: oklch(0.55 0.08 235/.6);
--cl-11-light: oklch(1 0.01 235/.95);
--cl-11-ink: oklch(0.28 0.045 235);
--cl-11-mut: oklch(0.5 0.035 235);
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-11-ink);
}
.cl-11__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: 20px;
padding: clamp(20px,5vw,56px);
}
.cl-11__panel {
width: min(100%,600px);
display: grid;
gap: clamp(18px,3vw,24px);
padding: clamp(22px,3.4vw,34px);
border-radius: 42px;
background: color-mix(in oklch,var(--cl-11-bg) 92%,white);
box-shadow: 0 30px 60px -24px var(--cl-11-shade),inset 0 -16px 28px -16px var(--cl-11-shade),inset 0 18px 28px -12px var(--cl-11-light);
}
.cl-11__lab {
display: block;
margin-bottom: 9px;
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--cl-11-mut);
}
.cl-11__searchWrap {
position: relative;
}
.cl-11__shell {
display: flex;
align-items: center;
gap: 12px;
padding: 0 18px;
border-radius: 24px;
background: color-mix(in oklch,var(--cl-11-bg) 93%,oklch(0.6 0.06 235));
box-shadow: inset 0 10px 18px -6px var(--cl-11-shade),inset 0 -8px 14px -10px var(--cl-11-light);
transition: box-shadow .28s;
}
.cl-11__shell:focus-within {
box-shadow: inset 0 8px 14px -8px var(--cl-11-shade),inset 0 -6px 12px -10px var(--cl-11-light),0 0 0 4px color-mix(in oklch,var(--cl-11-accent) 42%,transparent);
}
.cl-11__shell--search {
border-radius: 99px;
}
.cl-11__shell--area {
border-radius: 24px;
padding: 14px 18px;
}
.cl-11__icon {
flex: none;
color: var(--cl-11-mut);
}
.cl-11__input {
flex: 1;
min-width: 0;
min-height: 56px;
border: 0;
background: none;
font: inherit;
font-size: 15px;
color: var(--cl-11-ink);
outline: none;
}
.cl-11__input::placeholder {
color: color-mix(in oklch,var(--cl-11-mut) 88%,transparent);
}
.cl-11__input::-webkit-search-cancel-button {
filter: grayscale(1) opacity(.6);
}
.cl-11__kbd {
flex: none;
display: grid;
place-items: center;
width: 26px;
height: 26px;
border-radius: 9px;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 12px;
color: var(--cl-11-mut);
background: color-mix(in oklch,var(--cl-11-bg) 82%,white);
box-shadow: 0 4px 8px -5px var(--cl-11-shade),inset 0 5px 7px -5px var(--cl-11-light);
}
.cl-11__tray {
position: absolute;
left: 0;
right: 0;
top: calc(100% + 10px);
z-index: 2;
list-style: none;
display: none;
opacity: 0;
translate: 0 -8px;
padding: 10px;
border-radius: 26px;
background: color-mix(in oklch,var(--cl-11-bg) 96%,white);
box-shadow: 0 26px 50px -20px var(--cl-11-shade),inset 0 -12px 22px -16px var(--cl-11-shade),inset 0 14px 22px -12px var(--cl-11-light);
transition: opacity .26s,translate .26s,display .26s allow-discrete;
}
.cl-11__searchWrap:focus-within .cl-11__tray {
display: grid;
opacity: 1;
translate: 0;
}
@starting-style {
.cl-11__searchWrap:focus-within .cl-11__tray {
opacity: 0;
translate: 0 -8px;
}
}
.cl-11__tray li {
padding: 12px 16px;
border-radius: 18px;
font-size: 13.5px;
color: var(--cl-11-mut);
cursor: pointer;
transition: background .2s;
}
.cl-11__tray li b {
color: var(--cl-11-ink);
font-weight: 660;
}
.cl-11__tray li:hover {
background: color-mix(in oklch,var(--cl-11-accent) 16%,transparent);
}
.cl-11__grid {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(210px,1fr));
gap: 16px;
}
.cl-11__floatWrap .cl-11__shell {
position: relative;
padding-top: 6px;
}
.cl-11__input--float {
min-height: 60px;
padding-top: 14px;
}
.cl-11__float {
position: absolute;
left: 19px;
top: 19px;
font-size: 15px;
color: var(--cl-11-mut);
pointer-events: none;
transition: translate .22s cubic-bezier(.2,.8,.3,1),font-size .22s,color .22s;
}
.cl-11__input--float:focus+.cl-11__float,
.cl-11__input--float:not(:placeholder-shown)+.cl-11__float {
translate: 0 -13px;
font-size: 11px;
font-weight: 700;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--cl-11-accent);
}
.cl-11__hint {
margin-top: 8px;
padding-left: 6px;
font-size: 12.5px;
color: var(--cl-11-mut);
transition: color .25s;
}
.cl-11__floatWrap:has(:user-invalid) .cl-11__shell {
box-shadow: inset 0 10px 18px -6px color-mix(in oklch,var(--cl-11-error) 55%,transparent),inset 0 -8px 14px -10px var(--cl-11-light),0 0 0 3px color-mix(in oklch,var(--cl-11-error) 55%,transparent);
}
.cl-11__floatWrap:has(:user-invalid) .cl-11__hint {
color: var(--cl-11-error);
}
.cl-11__floatWrap:has(:user-invalid) .cl-11__hint::before {
content: 'Check this address — ';
font-weight: 680;
}
.cl-11__area {
width: 100%;
border: 0;
background: none;
font: inherit;
font-size: 15px;
line-height: 1.6;
color: var(--cl-11-ink);
outline: none;
resize: none;
field-sizing: content;
min-height: 64px;
max-height: 180px;
}
.cl-11__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--cl-11-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-11-shade),inset 0 6px 10px -6px oklch(1 0 0);
}
@media (prefers-reduced-motion: reduce) {
.cl-11 * {
transition-duration: .01ms !important;
}
}
```How this works
Reverse the recipe: no outer drop, insets swapped so the shade sits at the top.
.field{ /* a hole in the page */
background: color-mix(in oklch, var(--page) 94%, var(--shade));
box-shadow: inset 0 10px 18px -6px var(--shade),
inset 0 -8px 14px -10px var(--light);
}
.field:focus-within{ /* fill with light, don't lift */
box-shadow: inset 0 8px 14px -8px var(--shade),
inset 0 -6px 12px -10px var(--light),
0 0 0 4px color-mix(in oklch, var(--accent) 40%, transparent);
}Focus must not turn the well into an object — that would look like the field popped out while you type. Instead the insets soften and an outer ring appears: still a hole, now clearly active. :focus-within on the wrapper is what lets the whole clay shell respond while the real focus stays on the <input>.
Two modern niceties. The suggestion tray uses :focus-within plus @starting-style so it animates in from display:none in pure CSS. And validation uses :user-invalid rather than :invalid:
input:user-invalid ~ .hint{ color:var(--error); }
input:user-invalid{ box-shadow: inset 0 10px 18px -6px var(--error-shade), 0 0 0 3px var(--error); }:invalid matches an empty required field before the user has typed anything — it paints the form red on load. :user-invalid waits until the field has been interacted with and blurred, which is the behaviour every design review asks for.
Make it yours
- Leading icons: put the SVG inside the shell with
flex, not as a background-image, so it inherits the label color and stays crisp at any zoom. - Auto-growing textarea:
field-sizing:contentplusmin-height/max-heightreplaces the classic JS scrollHeight hack entirely. - Clear button: an
<input type="search">gives a native clear affordance for free in WebKit — or add a real button and show it with.shell:has(input:not(:placeholder-shown)) .clear. - Character counter:
.shell:has(input:not(:placeholder-shown)) .count{opacity:1}reveals metadata only once typing starts.
Gotchas — read before shipping
- Never remove the focus ring on a well. The inset change alone is far too subtle for low-vision users — keep an outer ring or a 3px outline.
- Placeholder text is not a label. Every field here has a real <label>; the floating variant animates the label, it does not replace it.
- Placeholder contrast must still hit 4.5:1 against the well's fill, which is darker than the page — check it separately from body copy.
- field-sizing:content is Chromium-only for now; always pair it with a rows attribute or min-height so other engines get a usable size.
- @starting-style must be declared for the element's own opening state and needs display:none to be transitioned via transition-behavior:allow-discrete — omit either and the tray snaps.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 123+ | 17.5+ | 129+ | 123+ |
:user-invalid: Chrome 119 / Safari 16.5 / Firefox 88. @starting-style + allow-discrete: Chrome 117 / Safari 17.5 / Firefox 129. field-sizing: Chromium only — all three degrade gracefully to a normal, fully usable field.