---
name: claymorphism
description: Use when you want "Playful, casual, friendly" - Uses rounded, inflated, clay-like shapes with colorful soft shadows.
---

# Claymorphism

> **Category:** Glass / Depth  -  **Personality:** Playful, casual, friendly
>
> **Best use:** Kids brands, landing pages, illustrations
>
> **Ratings:** Professional 2/5 - Casual 5/5 - Exotic 4/5 - Visual impact 4/5 - Difficulty 2/5 - Performance cost 2/5

## What it is

Claymorphism makes UI elements look like soft, inflated lumps of modelling clay — fat rounded corners, a chunky drop shadow that lifts them off the page, and (the part that does the real work) **two `inset` shadows**: a light one in the top-left and a darker, colour-tinted one in the bottom-right. Those opposing inner shadows fake a rounded, bulging surface lit from above, so a flat `<div>` reads as a squishy 3D blob. It is warm, toy-like and friendly, which is why kids' brands, casual landing pages and illustrative interfaces lean on it. Press states are part of the charm: invert the inset direction and the element looks pushed *into* the clay.

## Dependencies / CDN

None — pure CSS for the effect, vanilla JS only for the press/select micro-interactions. The demo loads two rounded display/body fonts (optional):

```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Baloo+2:wght@500;600;700;800&family=Nunito:wght@400;500;600;700;800&display=swap" rel="stylesheet">
```

## HTML

Every clay surface is just an element with the `.cl-clay` class; an accent class (`.cl-mint`, `.cl-coral`…) only swaps two custom properties. Buttons add `.cl-btn` for the press behaviour.

```html
<div class="cl-app cl-clay">
  <p class="cl-greet">Hi, Mia!</p>

  <!-- debossed track + raised fill -->
  <div class="cl-progress"><span class="cl-progress-fill"></span></div>

  <div class="cl-tiles">
    <button class="cl-tile cl-clay is-active" aria-pressed="true">
      <span class="cl-tile-ic cl-clay cl-coral">123</span>Counting
      <span class="cl-tile-check">&#10003;</span>
    </button>
    <button class="cl-tile cl-clay" aria-pressed="false">
      <span class="cl-tile-ic cl-clay cl-mint">Aa</span>Letters
      <span class="cl-tile-check">&#10003;</span>
    </button>
  </div>

  <button class="cl-btn cl-clay cl-mint">Play next game &rarr;</button>
</div>
```

## CSS

```css
/* 1) THE CLAY RECIPE — the only rule that matters.
      --c = surface colour, --sh = a DARKER shade of it (drop + bottom-right shade),
      --hl = the top-left highlight (white). */
.cl-clay{
  --c:#ffffff; --sh:182,162,216; --hl:255,255,255;
  background:var(--c);
  border-radius:28px;                                  /* fat, friendly corners */
  box-shadow:
    0 18px 30px -10px rgba(var(--sh),.5),              /* soft tinted lift off the page */
    inset 6px 7px 14px  rgba(var(--hl),.9),            /* lit top-left edge   */
    inset -8px -10px 18px rgba(var(--sh),.5);          /* shaded bottom-right */
}

/* 2) Accents = just re-point the two variables */
.cl-coral {--c:#ff8e93; --sh:224,92,104}
.cl-mint  {--c:#62d6b0; --sh:38,162,124}
.cl-butter{--c:#ffd166; --sh:226,168,48}
.cl-violet{--c:#b69bff; --sh:132,98,224}
.cl-sky   {--c:#7cc1ff; --sh:64,140,214}

/* 3) Buttons: lift on hover, squish IN on press (insets swap sides) */
.cl-btn{font:600 16px/1 'Baloo 2',sans-serif;color:#2f2150;border:0;border-radius:24px;
  padding:13px 24px;cursor:pointer;transition:transform .18s ease,box-shadow .18s ease}
.cl-btn.cl-clay:hover{transform:translateY(-3px);
  box-shadow:0 26px 40px -12px rgba(var(--sh),.6),
             inset 6px 7px 14px rgba(var(--hl),.9),
             inset -8px -10px 18px rgba(var(--sh),.5)}
.cl-btn.cl-clay:active{transform:translateY(1px);
  box-shadow:0 6px 12px -8px rgba(var(--sh),.5),
             inset 5px 6px 12px rgba(var(--sh),.55),   /* dark moves to top-left… */
             inset -4px -5px 10px rgba(var(--hl),.65)}  /* …so it reads pushed-in */

/* 4) Debossed variants: pressed selection + an inset "trench" track */
.cl-tile.is-active{transform:translateY(1px);
  box-shadow:inset 6px 7px 14px rgba(var(--sh),.5),inset -5px -6px 11px rgba(var(--hl),.7)}
.cl-progress{height:18px;border-radius:999px;overflow:hidden;background:#ece3f6;
  box-shadow:inset 5px 6px 12px rgba(178,160,214,.6),inset -4px -5px 10px rgba(255,255,255,.85)}
.cl-progress-fill{display:block;height:100%;width:62%;border-radius:999px;background:#62d6b0;
  box-shadow:inset 3px 3px 7px rgba(255,255,255,.55),inset -3px -3px 7px rgba(38,162,124,.55)}
```

## JavaScript

Optional — the look is 100% CSS. JS only adds the toy-like behaviour: single-select tiles that press in, and a star counter that pops.

```js
// Tiles: press one in, pop the rest out (single-select)
var tiles = Array.prototype.slice.call(document.querySelectorAll('.cl-tile'));
tiles.forEach(function(t){
  t.addEventListener('click', function(){
    var on = t.classList.contains('is-active');
    tiles.forEach(function(o){ o.classList.remove('is-active'); o.setAttribute('aria-pressed','false'); });
    if(!on){ t.classList.add('is-active'); t.setAttribute('aria-pressed','true'); }
  });
});

// Reward counter with a squishy pop (skip the pop if the user wants less motion)
var reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
var play = document.getElementById('cl-play'),
    reward = document.getElementById('cl-reward'),
    count = reward && reward.querySelector('b');
if(play && count){
  play.addEventListener('click', function(){
    count.textContent = (parseInt(count.textContent,10) || 0) + 3;
    if(!reduce){ reward.classList.remove('cl-pop'); void reward.offsetWidth; reward.classList.add('cl-pop'); }
  });
}
```

## How it works

- **The two `inset` shadows are the whole illusion.** A light inset in the top-left + a darker inset in the bottom-right simulate a surface bulging toward a top-left light source. Drop the insets and you are left with a plain rounded box.
- **Tint the shade to the surface colour.** Claymorphism uses *coloured* shadows, not grey ones — a coral blob casts a darker-coral shadow (`--sh` is a deeper shade of `--c`). That tint is what separates clay from generic neumorphism.
- **The outer drop shadow** (soft, large, tinted, with a negative spread so it stays under the shape) lifts the lump off the background.
- **Press = invert.** Swapping which corner gets the light vs. dark inset flips the read from "popping out" to "pushed in" — that is the entire press/selected state.
- **Big `border-radius`.** Clay has no sharp edges; corners of 20–34px (or full pills) sell the soft, moulded feel.

## Customization

- **Squish factor:** raise the inset blur/offset (e.g. `inset 8px 9px 18px`) for a puffier, softer lump; lower it for a tighter, harder bead.
- **Recolour in one place:** because every clay element reads `--c` / `--sh`, a new accent is two lines — set the surface and a darker shade of it. Keep `--hl` white.
- **Mood:** pastel surfaces on a light, slightly tinted background = candy/kids. Push saturation up and the same recipe turns into bold "toy plastic."
- **Depth stack:** overlap a small clay chip/badge on a larger clay card (as the floating "stars earned" pill does) to show layering and scale.
- **Corners:** dial `border-radius` from 18px (chunky-square) up to `999px` (full pill) per element.

## Accessibility & performance

- **Cheap to paint** — static `box-shadow`s, no blur sampling of the backdrop (unlike glassmorphism) and no GPU filters. Animate `transform` on hover/press, never the shadow's blur radius, to stay smooth.
- **Contrast:** pastel surfaces are light, so use a **dark** label colour (here `#2f2150`) on every accent rather than white — white-on-pastel fails WCAG. Verify each accent passes 4.5:1.
- **Reduced motion:** the demo gates the floating-puff drift, the pointer parallax and the star "pop" behind `prefers-reduced-motion: reduce` (in CSS and re-checked in JS before any loop/animation).
- **Real buttons:** selectable tiles are `<button aria-pressed>` so the pressed-in clay state is announced, not just shown.

## Gotchas

- **All-grey shadows look like neumorphism, not clay.** The bottom-right inset and the drop shadow must be tinted toward the surface colour, or it reads as flat soft-UI.
- **Highlight vanishes on white surfaces** — a white `inset` highlight on a white blob is invisible; the form then comes only from the darker bottom-right inset (that is fine and intended). On *coloured* clays the white highlight is what creates the glossy bulge.
- **Don't forget `overflow:hidden`** on an inset "trench" (the progress track) or a raised fill with its own rounded corners can poke past the groove.
- **Too much, too big.** Clay is loud; on a dense/professional UI it tips into cartoonish fast. Reserve it for hero moments, playful brands and illustration-led pages (hence the 2/5 "Professional" rating).
- **Press state needs the inset swap**, not just a `translateY`. Without flipping the light/dark inset corners, a "pressed" button still looks like it is popping out.
