10 / 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 Toggle Switch and Checkbox Set
A complete clay form-control set: a switch whose track is an inset well and whose knob is a puffy clay pebble, checkboxes with a drawn-on tick, and a segmented radio group with a sliding clay thumb. All native inputs — real focus rings, real keyboard, real screen-reader state — with no appearance:none hacks beyond the visually-hidden pattern.
Untitled UI Pro: a 10,000+ component Figma UI kit · from $129 one-time
Untitled UI · Affiliate link
The code
<section class="cl-10" aria-label="Clay toggle switch and checkbox set demo">
<div class="cl-10__stage">
<div class="cl-10__panel">
<h2 class="cl-10__h">Preferences</h2>
<ul class="cl-10__list">
<li class="cl-10__rowItem">
<span class="cl-10__rowText"><b>Daily practice reminder</b><span>A nudge at 8:00, your time</span></span>
<input class="cl-10__in" type="checkbox" id="cl-10-sw1" checked>
<label class="cl-10__switch" for="cl-10-sw1"><span class="cl-10__knob" aria-hidden="true"></span><span class="cl-10__sr">Daily practice reminder</span></label>
</li>
<li class="cl-10__rowItem">
<span class="cl-10__rowText"><b>Sound effects</b><span>Clicks, chimes and streak fanfare</span></span>
<input class="cl-10__in" type="checkbox" id="cl-10-sw2">
<label class="cl-10__switch" for="cl-10-sw2"><span class="cl-10__knob" aria-hidden="true"></span><span class="cl-10__sr">Sound effects</span></label>
</li>
</ul>
<fieldset class="cl-10__fs">
<legend class="cl-10__legend">Weekly digest includes</legend>
<div class="cl-10__checks">
<input class="cl-10__in" type="checkbox" id="cl-10-c1" checked>
<label class="cl-10__check" for="cl-10-c1"><span class="cl-10__box" aria-hidden="true"></span>Progress summary</label>
<input class="cl-10__in" type="checkbox" id="cl-10-c2" checked>
<label class="cl-10__check" for="cl-10-c2"><span class="cl-10__box" aria-hidden="true"></span>New lessons</label>
<input class="cl-10__in" type="checkbox" id="cl-10-c3">
<label class="cl-10__check" for="cl-10-c3"><span class="cl-10__box" aria-hidden="true"></span>Community picks</label>
</div>
</fieldset>
<fieldset class="cl-10__fs">
<legend class="cl-10__legend">Difficulty</legend>
<div class="cl-10__seg">
<span class="cl-10__thumb" aria-hidden="true"></span>
<input class="cl-10__in" type="radio" name="cl-10-diff" id="cl-10-d1">
<label class="cl-10__segOpt" for="cl-10-d1">Gentle</label>
<input class="cl-10__in" type="radio" name="cl-10-diff" id="cl-10-d2" checked>
<label class="cl-10__segOpt" for="cl-10-d2">Steady</label>
<input class="cl-10__in" type="radio" name="cl-10-diff" id="cl-10-d3">
<label class="cl-10__segOpt" for="cl-10-d3">Intense</label>
</div>
</fieldset>
</div>
<p class="cl-10__chip" aria-hidden="true">track = well · knob = object · tick = two borders, rotated and sprung · :has() thumb</p>
</div>
</section><section class="cl-10" aria-label="Clay toggle switch and checkbox set demo">
<div class="cl-10__stage">
<div class="cl-10__panel">
<h2 class="cl-10__h">Preferences</h2>
<ul class="cl-10__list">
<li class="cl-10__rowItem">
<span class="cl-10__rowText"><b>Daily practice reminder</b><span>A nudge at 8:00, your time</span></span>
<input class="cl-10__in" type="checkbox" id="cl-10-sw1" checked>
<label class="cl-10__switch" for="cl-10-sw1"><span class="cl-10__knob" aria-hidden="true"></span><span class="cl-10__sr">Daily practice reminder</span></label>
</li>
<li class="cl-10__rowItem">
<span class="cl-10__rowText"><b>Sound effects</b><span>Clicks, chimes and streak fanfare</span></span>
<input class="cl-10__in" type="checkbox" id="cl-10-sw2">
<label class="cl-10__switch" for="cl-10-sw2"><span class="cl-10__knob" aria-hidden="true"></span><span class="cl-10__sr">Sound effects</span></label>
</li>
</ul>
<fieldset class="cl-10__fs">
<legend class="cl-10__legend">Weekly digest includes</legend>
<div class="cl-10__checks">
<input class="cl-10__in" type="checkbox" id="cl-10-c1" checked>
<label class="cl-10__check" for="cl-10-c1"><span class="cl-10__box" aria-hidden="true"></span>Progress summary</label>
<input class="cl-10__in" type="checkbox" id="cl-10-c2" checked>
<label class="cl-10__check" for="cl-10-c2"><span class="cl-10__box" aria-hidden="true"></span>New lessons</label>
<input class="cl-10__in" type="checkbox" id="cl-10-c3">
<label class="cl-10__check" for="cl-10-c3"><span class="cl-10__box" aria-hidden="true"></span>Community picks</label>
</div>
</fieldset>
<fieldset class="cl-10__fs">
<legend class="cl-10__legend">Difficulty</legend>
<div class="cl-10__seg">
<span class="cl-10__thumb" aria-hidden="true"></span>
<input class="cl-10__in" type="radio" name="cl-10-diff" id="cl-10-d1">
<label class="cl-10__segOpt" for="cl-10-d1">Gentle</label>
<input class="cl-10__in" type="radio" name="cl-10-diff" id="cl-10-d2" checked>
<label class="cl-10__segOpt" for="cl-10-d2">Steady</label>
<input class="cl-10__in" type="radio" name="cl-10-diff" id="cl-10-d3">
<label class="cl-10__segOpt" for="cl-10-d3">Intense</label>
</div>
</fieldset>
</div>
<p class="cl-10__chip" aria-hidden="true">track = well · knob = object · tick = two borders, rotated and sprung · :has() thumb</p>
</div>
</section>.cl-10,
.cl-10 *,
.cl-10 *::before,
.cl-10 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-10 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--cl-10-bg);
--cl-10-bg: oklch(0.94 0.028 275);
--cl-10-clay: oklch(0.89 0.05 280);
--cl-10-accent: oklch(0.78 0.13 290);
--cl-10-shade: oklch(0.56 0.09 280/.55);
--cl-10-light: oklch(1 0.012 280/.95);
--cl-10-ink: oklch(0.29 0.05 280);
--cl-10-mut: oklch(0.51 0.04 280);
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-10-ink);
}
.cl-10__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: 20px;
padding: clamp(20px,5vw,56px);
}
.cl-10__panel {
width: min(100%,540px);
display: grid;
gap: clamp(18px,3vw,26px);
padding: clamp(22px,3.4vw,34px);
border-radius: 42px;
background: color-mix(in oklch,var(--cl-10-bg) 92%,white);
box-shadow: 0 30px 60px -24px var(--cl-10-shade),inset 0 -16px 28px -16px var(--cl-10-shade),inset 0 18px 28px -12px var(--cl-10-light);
}
.cl-10__h {
font-size: clamp(21px,3vw,27px);
font-weight: 780;
letter-spacing: -.02em;
}
.cl-10__list {
list-style: none;
display: grid;
gap: 12px;
}
.cl-10__rowItem {
display: flex;
align-items: center;
justify-content: space-between;
gap: 18px;
padding: 16px 18px;
border-radius: 26px;
background: color-mix(in oklch,var(--cl-10-bg) 96%,oklch(0.7 0.05 280));
box-shadow: inset 0 8px 16px -10px var(--cl-10-shade),inset 0 -6px 12px -10px var(--cl-10-light);
}
.cl-10__rowText {
display: grid;
gap: 3px;
}
.cl-10__rowText b {
font-size: 14.5px;
font-weight: 660;
}
.cl-10__rowText span {
font-size: 12.5px;
color: var(--cl-10-mut);
}
.cl-10__in {
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
clip-path: inset(50%);
}
.cl-10__sr {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
.cl-10__switch {
position: relative;
flex: none;
display: block;
width: 62px;
height: 36px;
border-radius: 99px;
cursor: pointer;
background: color-mix(in oklch,var(--cl-10-bg) 90%,oklch(0.62 0.06 280));
box-shadow: inset 0 9px 16px -6px var(--cl-10-shade),inset 0 -6px 12px -8px var(--cl-10-light);
transition: background .3s;
}
.cl-10__knob {
position: absolute;
top: 4px;
left: 4px;
width: 28px;
height: 28px;
border-radius: 50%;
background: color-mix(in oklch,var(--cl-10-clay) 60%,white);
box-shadow: 0 8px 14px -6px var(--cl-10-shade),inset 0 -6px 10px -7px var(--cl-10-shade),inset 0 8px 10px -6px var(--cl-10-light);
transition: translate .3s cubic-bezier(.34,1.5,.5,1),scale .3s cubic-bezier(.34,1.5,.5,1),background .3s;
}
.cl-10__in:checked+.cl-10__switch {
background: color-mix(in oklch,var(--cl-10-accent) 62%,white);
}
.cl-10__in:checked+.cl-10__switch .cl-10__knob {
translate: 26px 0;
scale: 1.05;
background: oklch(0.99 0.01 290);
}
.cl-10__in:focus-visible+.cl-10__switch,
.cl-10__in:focus-visible+.cl-10__check .cl-10__box,
.cl-10__in:focus-visible+.cl-10__segOpt {
outline: 3px solid var(--cl-10-ink);
outline-offset: 3px;
}
.cl-10__fs {
border: 0;
display: grid;
gap: 12px;
}
.cl-10__legend {
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--cl-10-mut);
padding-bottom: 4px;
}
.cl-10__checks {
display: grid;
gap: 10px;
}
.cl-10__check {
display: flex;
align-items: center;
gap: 14px;
min-height: 48px;
padding: 0 18px;
border-radius: 24px;
font-size: 14.5px;
font-weight: 600;
cursor: pointer;
background: color-mix(in oklch,var(--cl-10-bg) 92%,white);
box-shadow: 0 12px 20px -16px var(--cl-10-shade),inset 0 -8px 14px -12px var(--cl-10-shade),inset 0 10px 14px -9px var(--cl-10-light);
transition: translate .25s cubic-bezier(.34,1.4,.5,1),background .25s;
}
.cl-10__check:hover {
translate: 3px 0;
}
.cl-10__box {
position: relative;
flex: none;
width: 28px;
height: 28px;
border-radius: 10px;
background: color-mix(in oklch,var(--cl-10-bg) 84%,oklch(0.6 0.055 280));
box-shadow: inset 0 0 0 1px color-mix(in oklch,var(--cl-10-shade) 30%,transparent),inset 0 8px 13px -5px var(--cl-10-shade),inset 0 -5px 10px -7px var(--cl-10-light);
transition: background .25s,box-shadow .25s;
}
.cl-10__box::after {
content: '';
position: absolute;
left: 50%;
top: 50%;
width: 8px;
height: 14px;
border-right: 3px solid oklch(0.99 0.01 290);
border-bottom: 3px solid oklch(0.99 0.01 290);
border-radius: 1.5px;
translate: -50% -62%;
rotate: 45deg;
scale: 0;
opacity: 0;
transition: scale .26s cubic-bezier(.34,1.6,.5,1),opacity .2s;
}
.cl-10__check:hover .cl-10__box::after {
scale: .7;
opacity: .3;
}
.cl-10__in:checked+.cl-10__check {
background: color-mix(in oklch,var(--cl-10-accent) 26%,white);
}
.cl-10__in:checked+.cl-10__check .cl-10__box {
background: var(--cl-10-accent);
box-shadow: 0 8px 14px -8px var(--cl-10-shade),inset 0 -6px 10px -8px var(--cl-10-shade),inset 0 8px 10px -6px var(--cl-10-light);
}
.cl-10__in:checked+.cl-10__check .cl-10__box::after {
scale: 1;
opacity: 1;
}
.cl-10__seg {
position: relative;
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 4px;
padding: 5px;
border-radius: 26px;
background: color-mix(in oklch,var(--cl-10-bg) 92%,oklch(0.66 0.05 280));
box-shadow: inset 0 9px 16px -7px var(--cl-10-shade),inset 0 -6px 12px -9px var(--cl-10-light);
}
.cl-10__thumb {
position: absolute;
top: 5px;
left: 5px;
width: calc((100% - 18px) / 3);
height: calc(100% - 10px);
border-radius: 22px;
background: var(--cl-10-accent);
box-shadow: 0 10px 18px -8px var(--cl-10-shade),inset 0 -7px 12px -8px var(--cl-10-shade),inset 0 9px 12px -6px var(--cl-10-light);
transition: translate .34s cubic-bezier(.34,1.4,.5,1);
}
.cl-10__seg:has(#cl-10-d2:checked) .cl-10__thumb {
translate: calc(100% + 4px) 0;
}
.cl-10__seg:has(#cl-10-d3:checked) .cl-10__thumb {
translate: calc(200% + 8px) 0;
}
.cl-10__segOpt {
position: relative;
display: grid;
place-items: center;
min-height: 46px;
border-radius: 22px;
font-size: 14px;
font-weight: 640;
color: var(--cl-10-mut);
cursor: pointer;
transition: color .3s;
}
.cl-10__in:checked+.cl-10__segOpt {
color: oklch(0.99 0.01 290);
}
@media (prefers-reduced-motion: reduce) {
.cl-10 * {
transition-duration: .01ms !important;
}
}.cl-10,
.cl-10 *,
.cl-10 *::before,
.cl-10 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-10 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--cl-10-bg);
--cl-10-bg: oklch(0.94 0.028 275);
--cl-10-clay: oklch(0.89 0.05 280);
--cl-10-accent: oklch(0.78 0.13 290);
--cl-10-shade: oklch(0.56 0.09 280/.55);
--cl-10-light: oklch(1 0.012 280/.95);
--cl-10-ink: oklch(0.29 0.05 280);
--cl-10-mut: oklch(0.51 0.04 280);
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-10-ink);
}
.cl-10__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: 20px;
padding: clamp(20px,5vw,56px);
}
.cl-10__panel {
width: min(100%,540px);
display: grid;
gap: clamp(18px,3vw,26px);
padding: clamp(22px,3.4vw,34px);
border-radius: 42px;
background: color-mix(in oklch,var(--cl-10-bg) 92%,white);
box-shadow: 0 30px 60px -24px var(--cl-10-shade),inset 0 -16px 28px -16px var(--cl-10-shade),inset 0 18px 28px -12px var(--cl-10-light);
}
.cl-10__h {
font-size: clamp(21px,3vw,27px);
font-weight: 780;
letter-spacing: -.02em;
}
.cl-10__list {
list-style: none;
display: grid;
gap: 12px;
}
.cl-10__rowItem {
display: flex;
align-items: center;
justify-content: space-between;
gap: 18px;
padding: 16px 18px;
border-radius: 26px;
background: color-mix(in oklch,var(--cl-10-bg) 96%,oklch(0.7 0.05 280));
box-shadow: inset 0 8px 16px -10px var(--cl-10-shade),inset 0 -6px 12px -10px var(--cl-10-light);
}
.cl-10__rowText {
display: grid;
gap: 3px;
}
.cl-10__rowText b {
font-size: 14.5px;
font-weight: 660;
}
.cl-10__rowText span {
font-size: 12.5px;
color: var(--cl-10-mut);
}
.cl-10__in {
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
clip-path: inset(50%);
}
.cl-10__sr {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
.cl-10__switch {
position: relative;
flex: none;
display: block;
width: 62px;
height: 36px;
border-radius: 99px;
cursor: pointer;
background: color-mix(in oklch,var(--cl-10-bg) 90%,oklch(0.62 0.06 280));
box-shadow: inset 0 9px 16px -6px var(--cl-10-shade),inset 0 -6px 12px -8px var(--cl-10-light);
transition: background .3s;
}
.cl-10__knob {
position: absolute;
top: 4px;
left: 4px;
width: 28px;
height: 28px;
border-radius: 50%;
background: color-mix(in oklch,var(--cl-10-clay) 60%,white);
box-shadow: 0 8px 14px -6px var(--cl-10-shade),inset 0 -6px 10px -7px var(--cl-10-shade),inset 0 8px 10px -6px var(--cl-10-light);
transition: translate .3s cubic-bezier(.34,1.5,.5,1),scale .3s cubic-bezier(.34,1.5,.5,1),background .3s;
}
.cl-10__in:checked+.cl-10__switch {
background: color-mix(in oklch,var(--cl-10-accent) 62%,white);
}
.cl-10__in:checked+.cl-10__switch .cl-10__knob {
translate: 26px 0;
scale: 1.05;
background: oklch(0.99 0.01 290);
}
.cl-10__in:focus-visible+.cl-10__switch,
.cl-10__in:focus-visible+.cl-10__check .cl-10__box,
.cl-10__in:focus-visible+.cl-10__segOpt {
outline: 3px solid var(--cl-10-ink);
outline-offset: 3px;
}
.cl-10__fs {
border: 0;
display: grid;
gap: 12px;
}
.cl-10__legend {
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--cl-10-mut);
padding-bottom: 4px;
}
.cl-10__checks {
display: grid;
gap: 10px;
}
.cl-10__check {
display: flex;
align-items: center;
gap: 14px;
min-height: 48px;
padding: 0 18px;
border-radius: 24px;
font-size: 14.5px;
font-weight: 600;
cursor: pointer;
background: color-mix(in oklch,var(--cl-10-bg) 92%,white);
box-shadow: 0 12px 20px -16px var(--cl-10-shade),inset 0 -8px 14px -12px var(--cl-10-shade),inset 0 10px 14px -9px var(--cl-10-light);
transition: translate .25s cubic-bezier(.34,1.4,.5,1),background .25s;
}
.cl-10__check:hover {
translate: 3px 0;
}
.cl-10__box {
position: relative;
flex: none;
width: 28px;
height: 28px;
border-radius: 10px;
background: color-mix(in oklch,var(--cl-10-bg) 84%,oklch(0.6 0.055 280));
box-shadow: inset 0 0 0 1px color-mix(in oklch,var(--cl-10-shade) 30%,transparent),inset 0 8px 13px -5px var(--cl-10-shade),inset 0 -5px 10px -7px var(--cl-10-light);
transition: background .25s,box-shadow .25s;
}
.cl-10__box::after {
content: '';
position: absolute;
left: 50%;
top: 50%;
width: 8px;
height: 14px;
border-right: 3px solid oklch(0.99 0.01 290);
border-bottom: 3px solid oklch(0.99 0.01 290);
border-radius: 1.5px;
translate: -50% -62%;
rotate: 45deg;
scale: 0;
opacity: 0;
transition: scale .26s cubic-bezier(.34,1.6,.5,1),opacity .2s;
}
.cl-10__check:hover .cl-10__box::after {
scale: .7;
opacity: .3;
}
.cl-10__in:checked+.cl-10__check {
background: color-mix(in oklch,var(--cl-10-accent) 26%,white);
}
.cl-10__in:checked+.cl-10__check .cl-10__box {
background: var(--cl-10-accent);
box-shadow: 0 8px 14px -8px var(--cl-10-shade),inset 0 -6px 10px -8px var(--cl-10-shade),inset 0 8px 10px -6px var(--cl-10-light);
}
.cl-10__in:checked+.cl-10__check .cl-10__box::after {
scale: 1;
opacity: 1;
}
.cl-10__seg {
position: relative;
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 4px;
padding: 5px;
border-radius: 26px;
background: color-mix(in oklch,var(--cl-10-bg) 92%,oklch(0.66 0.05 280));
box-shadow: inset 0 9px 16px -7px var(--cl-10-shade),inset 0 -6px 12px -9px var(--cl-10-light);
}
.cl-10__thumb {
position: absolute;
top: 5px;
left: 5px;
width: calc((100% - 18px) / 3);
height: calc(100% - 10px);
border-radius: 22px;
background: var(--cl-10-accent);
box-shadow: 0 10px 18px -8px var(--cl-10-shade),inset 0 -7px 12px -8px var(--cl-10-shade),inset 0 9px 12px -6px var(--cl-10-light);
transition: translate .34s cubic-bezier(.34,1.4,.5,1);
}
.cl-10__seg:has(#cl-10-d2:checked) .cl-10__thumb {
translate: calc(100% + 4px) 0;
}
.cl-10__seg:has(#cl-10-d3:checked) .cl-10__thumb {
translate: calc(200% + 8px) 0;
}
.cl-10__segOpt {
position: relative;
display: grid;
place-items: center;
min-height: 46px;
border-radius: 22px;
font-size: 14px;
font-weight: 640;
color: var(--cl-10-mut);
cursor: pointer;
transition: color .3s;
}
.cl-10__in:checked+.cl-10__segOpt {
color: oklch(0.99 0.01 290);
}
@media (prefers-reduced-motion: reduce) {
.cl-10 * {
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 Toggle Switch and Checkbox Set
Source: https://codefronts.com/design-styles/css-claymorphism/clay-toggle-switch-and-checkbox-set/
A complete clay form-control set: a switch whose track is an inset well and whose knob is a puffy clay pebble, checkboxes with a drawn-on tick, and a segmented radio group with a sliding clay thumb. All native inputs — real focus rings, real keyboard, real screen-reader state — with no appearance:none hacks beyond the visually-hidden pattern.
## HTML
```html
<section class="cl-10" aria-label="Clay toggle switch and checkbox set demo">
<div class="cl-10__stage">
<div class="cl-10__panel">
<h2 class="cl-10__h">Preferences</h2>
<ul class="cl-10__list">
<li class="cl-10__rowItem">
<span class="cl-10__rowText"><b>Daily practice reminder</b><span>A nudge at 8:00, your time</span></span>
<input class="cl-10__in" type="checkbox" id="cl-10-sw1" checked>
<label class="cl-10__switch" for="cl-10-sw1"><span class="cl-10__knob" aria-hidden="true"></span><span class="cl-10__sr">Daily practice reminder</span></label>
</li>
<li class="cl-10__rowItem">
<span class="cl-10__rowText"><b>Sound effects</b><span>Clicks, chimes and streak fanfare</span></span>
<input class="cl-10__in" type="checkbox" id="cl-10-sw2">
<label class="cl-10__switch" for="cl-10-sw2"><span class="cl-10__knob" aria-hidden="true"></span><span class="cl-10__sr">Sound effects</span></label>
</li>
</ul>
<fieldset class="cl-10__fs">
<legend class="cl-10__legend">Weekly digest includes</legend>
<div class="cl-10__checks">
<input class="cl-10__in" type="checkbox" id="cl-10-c1" checked>
<label class="cl-10__check" for="cl-10-c1"><span class="cl-10__box" aria-hidden="true"></span>Progress summary</label>
<input class="cl-10__in" type="checkbox" id="cl-10-c2" checked>
<label class="cl-10__check" for="cl-10-c2"><span class="cl-10__box" aria-hidden="true"></span>New lessons</label>
<input class="cl-10__in" type="checkbox" id="cl-10-c3">
<label class="cl-10__check" for="cl-10-c3"><span class="cl-10__box" aria-hidden="true"></span>Community picks</label>
</div>
</fieldset>
<fieldset class="cl-10__fs">
<legend class="cl-10__legend">Difficulty</legend>
<div class="cl-10__seg">
<span class="cl-10__thumb" aria-hidden="true"></span>
<input class="cl-10__in" type="radio" name="cl-10-diff" id="cl-10-d1">
<label class="cl-10__segOpt" for="cl-10-d1">Gentle</label>
<input class="cl-10__in" type="radio" name="cl-10-diff" id="cl-10-d2" checked>
<label class="cl-10__segOpt" for="cl-10-d2">Steady</label>
<input class="cl-10__in" type="radio" name="cl-10-diff" id="cl-10-d3">
<label class="cl-10__segOpt" for="cl-10-d3">Intense</label>
</div>
</fieldset>
</div>
<p class="cl-10__chip" aria-hidden="true">track = well · knob = object · tick = two borders, rotated and sprung · :has() thumb</p>
</div>
</section>
```
## CSS
```css
.cl-10,
.cl-10 *,
.cl-10 *::before,
.cl-10 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-10 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--cl-10-bg);
--cl-10-bg: oklch(0.94 0.028 275);
--cl-10-clay: oklch(0.89 0.05 280);
--cl-10-accent: oklch(0.78 0.13 290);
--cl-10-shade: oklch(0.56 0.09 280/.55);
--cl-10-light: oklch(1 0.012 280/.95);
--cl-10-ink: oklch(0.29 0.05 280);
--cl-10-mut: oklch(0.51 0.04 280);
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-10-ink);
}
.cl-10__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: 20px;
padding: clamp(20px,5vw,56px);
}
.cl-10__panel {
width: min(100%,540px);
display: grid;
gap: clamp(18px,3vw,26px);
padding: clamp(22px,3.4vw,34px);
border-radius: 42px;
background: color-mix(in oklch,var(--cl-10-bg) 92%,white);
box-shadow: 0 30px 60px -24px var(--cl-10-shade),inset 0 -16px 28px -16px var(--cl-10-shade),inset 0 18px 28px -12px var(--cl-10-light);
}
.cl-10__h {
font-size: clamp(21px,3vw,27px);
font-weight: 780;
letter-spacing: -.02em;
}
.cl-10__list {
list-style: none;
display: grid;
gap: 12px;
}
.cl-10__rowItem {
display: flex;
align-items: center;
justify-content: space-between;
gap: 18px;
padding: 16px 18px;
border-radius: 26px;
background: color-mix(in oklch,var(--cl-10-bg) 96%,oklch(0.7 0.05 280));
box-shadow: inset 0 8px 16px -10px var(--cl-10-shade),inset 0 -6px 12px -10px var(--cl-10-light);
}
.cl-10__rowText {
display: grid;
gap: 3px;
}
.cl-10__rowText b {
font-size: 14.5px;
font-weight: 660;
}
.cl-10__rowText span {
font-size: 12.5px;
color: var(--cl-10-mut);
}
.cl-10__in {
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
clip-path: inset(50%);
}
.cl-10__sr {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
.cl-10__switch {
position: relative;
flex: none;
display: block;
width: 62px;
height: 36px;
border-radius: 99px;
cursor: pointer;
background: color-mix(in oklch,var(--cl-10-bg) 90%,oklch(0.62 0.06 280));
box-shadow: inset 0 9px 16px -6px var(--cl-10-shade),inset 0 -6px 12px -8px var(--cl-10-light);
transition: background .3s;
}
.cl-10__knob {
position: absolute;
top: 4px;
left: 4px;
width: 28px;
height: 28px;
border-radius: 50%;
background: color-mix(in oklch,var(--cl-10-clay) 60%,white);
box-shadow: 0 8px 14px -6px var(--cl-10-shade),inset 0 -6px 10px -7px var(--cl-10-shade),inset 0 8px 10px -6px var(--cl-10-light);
transition: translate .3s cubic-bezier(.34,1.5,.5,1),scale .3s cubic-bezier(.34,1.5,.5,1),background .3s;
}
.cl-10__in:checked+.cl-10__switch {
background: color-mix(in oklch,var(--cl-10-accent) 62%,white);
}
.cl-10__in:checked+.cl-10__switch .cl-10__knob {
translate: 26px 0;
scale: 1.05;
background: oklch(0.99 0.01 290);
}
.cl-10__in:focus-visible+.cl-10__switch,
.cl-10__in:focus-visible+.cl-10__check .cl-10__box,
.cl-10__in:focus-visible+.cl-10__segOpt {
outline: 3px solid var(--cl-10-ink);
outline-offset: 3px;
}
.cl-10__fs {
border: 0;
display: grid;
gap: 12px;
}
.cl-10__legend {
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--cl-10-mut);
padding-bottom: 4px;
}
.cl-10__checks {
display: grid;
gap: 10px;
}
.cl-10__check {
display: flex;
align-items: center;
gap: 14px;
min-height: 48px;
padding: 0 18px;
border-radius: 24px;
font-size: 14.5px;
font-weight: 600;
cursor: pointer;
background: color-mix(in oklch,var(--cl-10-bg) 92%,white);
box-shadow: 0 12px 20px -16px var(--cl-10-shade),inset 0 -8px 14px -12px var(--cl-10-shade),inset 0 10px 14px -9px var(--cl-10-light);
transition: translate .25s cubic-bezier(.34,1.4,.5,1),background .25s;
}
.cl-10__check:hover {
translate: 3px 0;
}
.cl-10__box {
position: relative;
flex: none;
width: 28px;
height: 28px;
border-radius: 10px;
background: color-mix(in oklch,var(--cl-10-bg) 84%,oklch(0.6 0.055 280));
box-shadow: inset 0 0 0 1px color-mix(in oklch,var(--cl-10-shade) 30%,transparent),inset 0 8px 13px -5px var(--cl-10-shade),inset 0 -5px 10px -7px var(--cl-10-light);
transition: background .25s,box-shadow .25s;
}
.cl-10__box::after {
content: '';
position: absolute;
left: 50%;
top: 50%;
width: 8px;
height: 14px;
border-right: 3px solid oklch(0.99 0.01 290);
border-bottom: 3px solid oklch(0.99 0.01 290);
border-radius: 1.5px;
translate: -50% -62%;
rotate: 45deg;
scale: 0;
opacity: 0;
transition: scale .26s cubic-bezier(.34,1.6,.5,1),opacity .2s;
}
.cl-10__check:hover .cl-10__box::after {
scale: .7;
opacity: .3;
}
.cl-10__in:checked+.cl-10__check {
background: color-mix(in oklch,var(--cl-10-accent) 26%,white);
}
.cl-10__in:checked+.cl-10__check .cl-10__box {
background: var(--cl-10-accent);
box-shadow: 0 8px 14px -8px var(--cl-10-shade),inset 0 -6px 10px -8px var(--cl-10-shade),inset 0 8px 10px -6px var(--cl-10-light);
}
.cl-10__in:checked+.cl-10__check .cl-10__box::after {
scale: 1;
opacity: 1;
}
.cl-10__seg {
position: relative;
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 4px;
padding: 5px;
border-radius: 26px;
background: color-mix(in oklch,var(--cl-10-bg) 92%,oklch(0.66 0.05 280));
box-shadow: inset 0 9px 16px -7px var(--cl-10-shade),inset 0 -6px 12px -9px var(--cl-10-light);
}
.cl-10__thumb {
position: absolute;
top: 5px;
left: 5px;
width: calc((100% - 18px) / 3);
height: calc(100% - 10px);
border-radius: 22px;
background: var(--cl-10-accent);
box-shadow: 0 10px 18px -8px var(--cl-10-shade),inset 0 -7px 12px -8px var(--cl-10-shade),inset 0 9px 12px -6px var(--cl-10-light);
transition: translate .34s cubic-bezier(.34,1.4,.5,1);
}
.cl-10__seg:has(#cl-10-d2:checked) .cl-10__thumb {
translate: calc(100% + 4px) 0;
}
.cl-10__seg:has(#cl-10-d3:checked) .cl-10__thumb {
translate: calc(200% + 8px) 0;
}
.cl-10__segOpt {
position: relative;
display: grid;
place-items: center;
min-height: 46px;
border-radius: 22px;
font-size: 14px;
font-weight: 640;
color: var(--cl-10-mut);
cursor: pointer;
transition: color .3s;
}
.cl-10__in:checked+.cl-10__segOpt {
color: oklch(0.99 0.01 290);
}
@media (prefers-reduced-motion: reduce) {
.cl-10 * {
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 Toggle Switch and Checkbox Set
Source: https://codefronts.com/design-styles/css-claymorphism/clay-toggle-switch-and-checkbox-set/
A complete clay form-control set: a switch whose track is an inset well and whose knob is a puffy clay pebble, checkboxes with a drawn-on tick, and a segmented radio group with a sliding clay thumb. All native inputs — real focus rings, real keyboard, real screen-reader state — with no appearance:none hacks beyond the visually-hidden pattern.
## HTML
```html
<section class="cl-10" aria-label="Clay toggle switch and checkbox set demo">
<div class="cl-10__stage">
<div class="cl-10__panel">
<h2 class="cl-10__h">Preferences</h2>
<ul class="cl-10__list">
<li class="cl-10__rowItem">
<span class="cl-10__rowText"><b>Daily practice reminder</b><span>A nudge at 8:00, your time</span></span>
<input class="cl-10__in" type="checkbox" id="cl-10-sw1" checked>
<label class="cl-10__switch" for="cl-10-sw1"><span class="cl-10__knob" aria-hidden="true"></span><span class="cl-10__sr">Daily practice reminder</span></label>
</li>
<li class="cl-10__rowItem">
<span class="cl-10__rowText"><b>Sound effects</b><span>Clicks, chimes and streak fanfare</span></span>
<input class="cl-10__in" type="checkbox" id="cl-10-sw2">
<label class="cl-10__switch" for="cl-10-sw2"><span class="cl-10__knob" aria-hidden="true"></span><span class="cl-10__sr">Sound effects</span></label>
</li>
</ul>
<fieldset class="cl-10__fs">
<legend class="cl-10__legend">Weekly digest includes</legend>
<div class="cl-10__checks">
<input class="cl-10__in" type="checkbox" id="cl-10-c1" checked>
<label class="cl-10__check" for="cl-10-c1"><span class="cl-10__box" aria-hidden="true"></span>Progress summary</label>
<input class="cl-10__in" type="checkbox" id="cl-10-c2" checked>
<label class="cl-10__check" for="cl-10-c2"><span class="cl-10__box" aria-hidden="true"></span>New lessons</label>
<input class="cl-10__in" type="checkbox" id="cl-10-c3">
<label class="cl-10__check" for="cl-10-c3"><span class="cl-10__box" aria-hidden="true"></span>Community picks</label>
</div>
</fieldset>
<fieldset class="cl-10__fs">
<legend class="cl-10__legend">Difficulty</legend>
<div class="cl-10__seg">
<span class="cl-10__thumb" aria-hidden="true"></span>
<input class="cl-10__in" type="radio" name="cl-10-diff" id="cl-10-d1">
<label class="cl-10__segOpt" for="cl-10-d1">Gentle</label>
<input class="cl-10__in" type="radio" name="cl-10-diff" id="cl-10-d2" checked>
<label class="cl-10__segOpt" for="cl-10-d2">Steady</label>
<input class="cl-10__in" type="radio" name="cl-10-diff" id="cl-10-d3">
<label class="cl-10__segOpt" for="cl-10-d3">Intense</label>
</div>
</fieldset>
</div>
<p class="cl-10__chip" aria-hidden="true">track = well · knob = object · tick = two borders, rotated and sprung · :has() thumb</p>
</div>
</section>
```
## CSS
```css
.cl-10,
.cl-10 *,
.cl-10 *::before,
.cl-10 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-10 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--cl-10-bg);
--cl-10-bg: oklch(0.94 0.028 275);
--cl-10-clay: oklch(0.89 0.05 280);
--cl-10-accent: oklch(0.78 0.13 290);
--cl-10-shade: oklch(0.56 0.09 280/.55);
--cl-10-light: oklch(1 0.012 280/.95);
--cl-10-ink: oklch(0.29 0.05 280);
--cl-10-mut: oklch(0.51 0.04 280);
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-10-ink);
}
.cl-10__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: 20px;
padding: clamp(20px,5vw,56px);
}
.cl-10__panel {
width: min(100%,540px);
display: grid;
gap: clamp(18px,3vw,26px);
padding: clamp(22px,3.4vw,34px);
border-radius: 42px;
background: color-mix(in oklch,var(--cl-10-bg) 92%,white);
box-shadow: 0 30px 60px -24px var(--cl-10-shade),inset 0 -16px 28px -16px var(--cl-10-shade),inset 0 18px 28px -12px var(--cl-10-light);
}
.cl-10__h {
font-size: clamp(21px,3vw,27px);
font-weight: 780;
letter-spacing: -.02em;
}
.cl-10__list {
list-style: none;
display: grid;
gap: 12px;
}
.cl-10__rowItem {
display: flex;
align-items: center;
justify-content: space-between;
gap: 18px;
padding: 16px 18px;
border-radius: 26px;
background: color-mix(in oklch,var(--cl-10-bg) 96%,oklch(0.7 0.05 280));
box-shadow: inset 0 8px 16px -10px var(--cl-10-shade),inset 0 -6px 12px -10px var(--cl-10-light);
}
.cl-10__rowText {
display: grid;
gap: 3px;
}
.cl-10__rowText b {
font-size: 14.5px;
font-weight: 660;
}
.cl-10__rowText span {
font-size: 12.5px;
color: var(--cl-10-mut);
}
.cl-10__in {
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
clip-path: inset(50%);
}
.cl-10__sr {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
.cl-10__switch {
position: relative;
flex: none;
display: block;
width: 62px;
height: 36px;
border-radius: 99px;
cursor: pointer;
background: color-mix(in oklch,var(--cl-10-bg) 90%,oklch(0.62 0.06 280));
box-shadow: inset 0 9px 16px -6px var(--cl-10-shade),inset 0 -6px 12px -8px var(--cl-10-light);
transition: background .3s;
}
.cl-10__knob {
position: absolute;
top: 4px;
left: 4px;
width: 28px;
height: 28px;
border-radius: 50%;
background: color-mix(in oklch,var(--cl-10-clay) 60%,white);
box-shadow: 0 8px 14px -6px var(--cl-10-shade),inset 0 -6px 10px -7px var(--cl-10-shade),inset 0 8px 10px -6px var(--cl-10-light);
transition: translate .3s cubic-bezier(.34,1.5,.5,1),scale .3s cubic-bezier(.34,1.5,.5,1),background .3s;
}
.cl-10__in:checked+.cl-10__switch {
background: color-mix(in oklch,var(--cl-10-accent) 62%,white);
}
.cl-10__in:checked+.cl-10__switch .cl-10__knob {
translate: 26px 0;
scale: 1.05;
background: oklch(0.99 0.01 290);
}
.cl-10__in:focus-visible+.cl-10__switch,
.cl-10__in:focus-visible+.cl-10__check .cl-10__box,
.cl-10__in:focus-visible+.cl-10__segOpt {
outline: 3px solid var(--cl-10-ink);
outline-offset: 3px;
}
.cl-10__fs {
border: 0;
display: grid;
gap: 12px;
}
.cl-10__legend {
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--cl-10-mut);
padding-bottom: 4px;
}
.cl-10__checks {
display: grid;
gap: 10px;
}
.cl-10__check {
display: flex;
align-items: center;
gap: 14px;
min-height: 48px;
padding: 0 18px;
border-radius: 24px;
font-size: 14.5px;
font-weight: 600;
cursor: pointer;
background: color-mix(in oklch,var(--cl-10-bg) 92%,white);
box-shadow: 0 12px 20px -16px var(--cl-10-shade),inset 0 -8px 14px -12px var(--cl-10-shade),inset 0 10px 14px -9px var(--cl-10-light);
transition: translate .25s cubic-bezier(.34,1.4,.5,1),background .25s;
}
.cl-10__check:hover {
translate: 3px 0;
}
.cl-10__box {
position: relative;
flex: none;
width: 28px;
height: 28px;
border-radius: 10px;
background: color-mix(in oklch,var(--cl-10-bg) 84%,oklch(0.6 0.055 280));
box-shadow: inset 0 0 0 1px color-mix(in oklch,var(--cl-10-shade) 30%,transparent),inset 0 8px 13px -5px var(--cl-10-shade),inset 0 -5px 10px -7px var(--cl-10-light);
transition: background .25s,box-shadow .25s;
}
.cl-10__box::after {
content: '';
position: absolute;
left: 50%;
top: 50%;
width: 8px;
height: 14px;
border-right: 3px solid oklch(0.99 0.01 290);
border-bottom: 3px solid oklch(0.99 0.01 290);
border-radius: 1.5px;
translate: -50% -62%;
rotate: 45deg;
scale: 0;
opacity: 0;
transition: scale .26s cubic-bezier(.34,1.6,.5,1),opacity .2s;
}
.cl-10__check:hover .cl-10__box::after {
scale: .7;
opacity: .3;
}
.cl-10__in:checked+.cl-10__check {
background: color-mix(in oklch,var(--cl-10-accent) 26%,white);
}
.cl-10__in:checked+.cl-10__check .cl-10__box {
background: var(--cl-10-accent);
box-shadow: 0 8px 14px -8px var(--cl-10-shade),inset 0 -6px 10px -8px var(--cl-10-shade),inset 0 8px 10px -6px var(--cl-10-light);
}
.cl-10__in:checked+.cl-10__check .cl-10__box::after {
scale: 1;
opacity: 1;
}
.cl-10__seg {
position: relative;
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 4px;
padding: 5px;
border-radius: 26px;
background: color-mix(in oklch,var(--cl-10-bg) 92%,oklch(0.66 0.05 280));
box-shadow: inset 0 9px 16px -7px var(--cl-10-shade),inset 0 -6px 12px -9px var(--cl-10-light);
}
.cl-10__thumb {
position: absolute;
top: 5px;
left: 5px;
width: calc((100% - 18px) / 3);
height: calc(100% - 10px);
border-radius: 22px;
background: var(--cl-10-accent);
box-shadow: 0 10px 18px -8px var(--cl-10-shade),inset 0 -7px 12px -8px var(--cl-10-shade),inset 0 9px 12px -6px var(--cl-10-light);
transition: translate .34s cubic-bezier(.34,1.4,.5,1);
}
.cl-10__seg:has(#cl-10-d2:checked) .cl-10__thumb {
translate: calc(100% + 4px) 0;
}
.cl-10__seg:has(#cl-10-d3:checked) .cl-10__thumb {
translate: calc(200% + 8px) 0;
}
.cl-10__segOpt {
position: relative;
display: grid;
place-items: center;
min-height: 46px;
border-radius: 22px;
font-size: 14px;
font-weight: 640;
color: var(--cl-10-mut);
cursor: pointer;
transition: color .3s;
}
.cl-10__in:checked+.cl-10__segOpt {
color: oklch(0.99 0.01 290);
}
@media (prefers-reduced-motion: reduce) {
.cl-10 * {
transition-duration: .01ms !important;
}
}
```How this works
The material logic of a switch is the whole lesson: the track is a hole, the knob is an object. So they get opposite shadow recipes.
.track{ /* a well: insets only, no drop */
box-shadow: inset 0 8px 16px -6px var(--shade),
inset 0 -6px 12px -8px var(--light);
}
.knob{ /* an object: drop + both insets */
box-shadow: 0 8px 14px -6px var(--shade),
inset 0 -6px 10px -7px var(--shade),
inset 0 8px 10px -6px var(--light);
}
input:checked + label .knob{ translate: 26px 0; scale: 1.04; }The knob also squashes as it travels — scale:1.04 at the end of the throw plus a springy curve makes it feel like it was flicked, not slid.
The checkbox tick is a single rotated pseudo-element with two borders — no SVG, no icon font — centred on the box and sprung in from scale:0, so it lands rather than slides:
.box::after{ position:absolute; left:50%; top:50%; width:8px; height:14px;
border-right:3px solid; border-bottom:3px solid; /* an L shape */
translate:-50% -62%; rotate:45deg; /* becomes a tick */
scale:0; transition:scale .26s cubic-bezier(.34,1.6,.5,1); }
input:checked + label .box::after{ scale:1; }Centring is the fiddly part: the individual transform properties always apply in the order translate → rotate → scale, so the offset is computed in unrotated space (-50% -62% compensates for the tick's optical centre sitting below its box centre). Animating scale rather than height keeps the stroke geometry fixed, so the tick can never land off-centre mid-transition.
Every control is a real <input> clipped with clip-path:inset(50%) rather than display:none, so it keeps its place in the tab order and reports its own state. The segmented group's thumb slides by translating a single absolutely-positioned element, selected via :has() on the group — one moving element, not three cross-fading backgrounds.
Make it yours
- Icon-in-track: place a tiny sun and moon inside the track at each end and fade them with the checked state for a theme switch (see demo 19).
- Bigger hit area without bigger visuals: give the label
padding:8pxand negative margins so the touch target clears 44px while the switch stays 52x30. - Loading state: add a
::beforespinner on the knob and set--knob-scale:.9while an async save is in flight. - Group semantics: wrap the checkbox set in a
<fieldset>with a<legend>so assistive tech announces the group name — done here.
Gotchas — read before shipping
- display:none or visibility:hidden on the input removes it from the tab order and breaks keyboard use. Clip it (1px + clip-path) instead.
- The switch needs a label the user can read, not just an aria-label on the input — pair every control with a real <label for>.
- Colour alone must not convey state (WCAG 1.4.1). The knob's position and the tick shape carry it here; colour is reinforcement only.
- Inset tracks under ~24px tall cannot show a well convincingly — increase the track height or drop to a single inset layer.
- Do not animate the track's background-color and the knob's translate on different durations; the eye reads the mismatch as lag.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.2+ | 121+ | 111+ |
Floor set by :has(), oklch(), color-mix() as this demo is written. The core technique itself goes back further — Chrome 105+.
:has() (segmented thumb) needs Chrome 105 / Safari 15.4 / Firefox 121; everything else is universal. Without :has() the segmented group still works — the thumb simply stays under the first option, so add a per-input sibling fallback if you must support older Safari.