51 CSS Buttons
18 / 51

All 51 in 51 CSS Buttons

  1. 01CSS Submit Button (Form Primary)
  2. 02CSS Primary and Secondary Button Pair
  3. 03CSS Ghost / Outline Button
  4. 04CSS Icon-Only Button with Accessible Tooltip
  5. 05CSS Gradient CTA Button
  6. 06CSS Loading Spinner Button (State Transition)
  7. 07CSS Disabled Button State (Full State Reference)
  8. 08CSS Button Group Component (Segmented Radio-Like)
  9. 09CSS Add to Cart Button
  10. 10CSS Download Progress Button
  11. 11CSS Like Heart Button
  12. 12CSS Confirm Delete Button
  13. 13CSS Play Pause Button
  14. 14CSS Subscribe Confetti Button
  15. 15CSS Magnetic Mercury Ripple Button
  16. 16CSS Brutalist Glitch Button
  17. 17CSS Neon Plasma Burst Button
  18. 18CSS Clay Press Button
  19. 19CSS Editorial Ink Spread Button
  20. 20CSS Particle Shard Burst Button
  21. 21CSS Brushed Brass Plate Button
  22. 22CSS Washi Paper Crane Button
  23. 23CSS Frosted Ice Cube Button
  24. 24CSS Vintage Typewriter Key Button
  25. 25CSS Lacquered Walnut Wood Button
  26. 26CSS Pharma Gel Capsule Button
  27. 27CSS Aged Copper Coin Button
  28. 28CSS Origami Fortune Cookie Button
  29. 29CSS Holographic Foil Sticker Button
  30. 30CSS Brutalist Concrete Slab Button
  31. 31CSS Mercury Bead Morph Button
  32. 32CSS Soft Pill Modern SaaS Button
  33. 33CSS Masking Tape Label Button
  34. 34CSS Obsidian Glass Shard Button
  35. 35CSS Wine Velvet Ribbon Button
  36. 36CSS LED Segment Display Button
  37. 37CSS Cassette Mixtape Label Button
  38. 38CSS Chalkboard Menu Button
  39. 39CSS Vinyl Record Sleeve Ripple Button
  40. 40CSS Polaroid Snapshot Button
  41. 41CSS Airline Boarding Pass Button
  42. 42CSS Aged Brass Subway Token Button
  43. 43CSS Vintage Rx Pharmacy Label Button
  44. 44CSS Bakelite Radio Dial Toggle Button
  45. 45CSS Regal Postage Stamp Button
  46. 46CSS Victorian Cigar Band Foil Button
  47. 47CSS Vintage Calculator Key Button
  48. 48CSS Toolbox Latch Spotlight Button
  49. 49CSS Receipt Paper Total Count-Up Button
  50. 50CSS IBM Punch Card Magnetic Follow Button
  51. 51CSS Brass Periscope Lens Button
Pure CSSMIT licensed

CSS Clay Press Button

Fat, matte, extruded clay: two inner shadows carve the highlight and the shade, an outer shadow grounds it, and pressing squashes the shape on both axes so it deforms like real material instead of just moving down.

Live Demo
Plain CSSTailwind v4
Try it

Build UI like this from scratch: Flexbox, Grid, animations & responsive CSS

ZTM · The CSS Bootcamp · 30‑day money-back guarantee · Affiliate link

10% off at checkout with code
Check ZTM Course

The code

<div class="cb-18">
  <div class="cb-18__stage">
    <button class="cb-18__btn" type="button">
      <span class="cb-18__ico" aria-hidden="true">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M5 12h14"/></svg>
      </span>
      <span>Make something</span>
    </button>
  </div>
</div>
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@600;700;800&display=swap');

.cb-18 {
  --bg: #e8ecf7;
  --clay: #7c8cf8;
  --deep: #2a3480;
  --ink: #ffffff;
  --chip: #fbbf24;
  --radius: 1.5rem;
  --spring: linear(0,.38 7%,.82 15%,1.08 23%,1.12 28%,1.05 37%,1 52%,1);
  --sans: "Nunito",ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  display: block;
  background: radial-gradient(30rem 20rem at 50% 40%, #ffffff, transparent 70%), var(--bg);
  font-family: var(--sans);
}

@supports (color: oklch(50% 0 0)) {
  .cb-18 {
    --bg: oklch(93.5% .02 265);
    --clay: oklch(68% .16 275);
    --deep: oklch(35% .14 275);
    --chip: oklch(84% .16 82);
  }
}

@media (prefers-color-scheme: dark) {
  .cb-18:not([data-theme="light"]) {
    --bg: #181b28;
    --clay: #5b68d8;
    --deep: #080a16;
  }
}

.cb-18[data-theme="dark"] {
  --bg: #181b28;
  --clay: #5b68d8;
  --deep: #080a16;
}

.cb-18,
.cb-18 *,
.cb-18 *::before,
.cb-18 *::after {
  box-sizing: border-box;
}

.cb-18__stage {
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: clamp(1.5rem,6vw,4rem);
}

.cb-18__btn {
  cursor: pointer;
  display: grid;
  grid-auto-flow: column;
  align-items: center;
  gap: .7rem;
  min-height: 4rem;
  padding: 0 2rem 0 1.4rem;
  border: 0;
  border-radius: var(--radius);
  font: inherit;
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -.01em;
  color: var(--ink);
  background: var(--clay);
  box-shadow: inset 8px 8px 16px color-mix(in oklab,white 45%,transparent), inset -10px -10px 20px color-mix(in oklab,var(--deep) 42%,transparent), 0 18px 32px -16px color-mix(in oklab,var(--deep) 65%,transparent);
  transition: translate .35s cubic-bezier(.16,1,.3,1), scale .35s cubic-bezier(.16,1,.3,1), box-shadow .3s ease;
  -webkit-tap-highlight-color: transparent;
}

@supports (transition-timing-function: linear(0,1)) {
  .cb-18__btn {
    transition: translate .5s var(--spring), scale .5s var(--spring), box-shadow .3s ease;
  }
}

.cb-18__ico {
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  color: var(--deep);
  background: var(--chip);
  box-shadow: inset 3px 3px 6px color-mix(in oklab,white 55%,transparent), inset -3px -3px 6px color-mix(in oklab,var(--deep) 30%,transparent);
  transition: rotate .5s cubic-bezier(.16,1,.3,1);
}

.cb-18__ico svg {
  width: 1.05rem;
  height: 1.05rem;
}

.cb-18__btn:hover {
  translate: 0 -3px;
}

.cb-18__btn:hover .cb-18__ico {
  rotate: 90deg;
}

.cb-18__btn:active {
  scale: .96 .9;
  translate: 0 2px;
  box-shadow: inset 7px 7px 15px color-mix(in oklab,var(--deep) 38%,transparent), inset -7px -7px 14px color-mix(in oklab,white 32%,transparent), 0 6px 12px -10px color-mix(in oklab,var(--deep) 60%,transparent);
}

.cb-18__btn:focus-visible {
  outline: 3px solid color-mix(in oklab,var(--deep) 60%,var(--clay));
  outline-offset: 5px;
}

.cb-18__btn:disabled {
  cursor: not-allowed;
  filter: grayscale(.6);
  opacity: .6;
}

@media (prefers-reduced-motion: reduce) {
  .cb-18__btn,
    .cb-18__ico {
    transition: none;
  }
}

@media (forced-colors: active) {
  .cb-18__btn {
    background: ButtonFace;
    color: ButtonText;
    border: 1px solid ButtonText;
    box-shadow: none;
  }

  .cb-18__ico {
    box-shadow: none;
    border: 1px solid ButtonText;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Button 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: CSS Clay Press Button
Source: https://codefronts.com/components/css-buttons/css-clay-press-button/

Fat, matte, extruded clay: two inner shadows carve the highlight and the shade, an outer shadow grounds it, and pressing squashes the shape on both axes so it deforms like real material instead of just moving down.
## HTML
```html
<div class="cb-18">
  <div class="cb-18__stage">
    <button class="cb-18__btn" type="button">
      <span class="cb-18__ico" aria-hidden="true">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M5 12h14"/></svg>
      </span>
      <span>Make something</span>
    </button>
  </div>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@600;700;800&display=swap');

.cb-18 {
  --bg: #e8ecf7;
  --clay: #7c8cf8;
  --deep: #2a3480;
  --ink: #ffffff;
  --chip: #fbbf24;
  --radius: 1.5rem;
  --spring: linear(0,.38 7%,.82 15%,1.08 23%,1.12 28%,1.05 37%,1 52%,1);
  --sans: "Nunito",ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  display: block;
  background: radial-gradient(30rem 20rem at 50% 40%, #ffffff, transparent 70%), var(--bg);
  font-family: var(--sans);
}

@supports (color: oklch(50% 0 0)) {
  .cb-18 {
    --bg: oklch(93.5% .02 265);
    --clay: oklch(68% .16 275);
    --deep: oklch(35% .14 275);
    --chip: oklch(84% .16 82);
  }
}

@media (prefers-color-scheme: dark) {
  .cb-18:not([data-theme="light"]) {
    --bg: #181b28;
    --clay: #5b68d8;
    --deep: #080a16;
  }
}

.cb-18[data-theme="dark"] {
  --bg: #181b28;
  --clay: #5b68d8;
  --deep: #080a16;
}

.cb-18,
.cb-18 *,
.cb-18 *::before,
.cb-18 *::after {
  box-sizing: border-box;
}

.cb-18__stage {
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: clamp(1.5rem,6vw,4rem);
}

.cb-18__btn {
  cursor: pointer;
  display: grid;
  grid-auto-flow: column;
  align-items: center;
  gap: .7rem;
  min-height: 4rem;
  padding: 0 2rem 0 1.4rem;
  border: 0;
  border-radius: var(--radius);
  font: inherit;
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -.01em;
  color: var(--ink);
  background: var(--clay);
  box-shadow: inset 8px 8px 16px color-mix(in oklab,white 45%,transparent), inset -10px -10px 20px color-mix(in oklab,var(--deep) 42%,transparent), 0 18px 32px -16px color-mix(in oklab,var(--deep) 65%,transparent);
  transition: translate .35s cubic-bezier(.16,1,.3,1), scale .35s cubic-bezier(.16,1,.3,1), box-shadow .3s ease;
  -webkit-tap-highlight-color: transparent;
}

@supports (transition-timing-function: linear(0,1)) {
  .cb-18__btn {
    transition: translate .5s var(--spring), scale .5s var(--spring), box-shadow .3s ease;
  }
}

.cb-18__ico {
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  color: var(--deep);
  background: var(--chip);
  box-shadow: inset 3px 3px 6px color-mix(in oklab,white 55%,transparent), inset -3px -3px 6px color-mix(in oklab,var(--deep) 30%,transparent);
  transition: rotate .5s cubic-bezier(.16,1,.3,1);
}

.cb-18__ico svg {
  width: 1.05rem;
  height: 1.05rem;
}

.cb-18__btn:hover {
  translate: 0 -3px;
}

.cb-18__btn:hover .cb-18__ico {
  rotate: 90deg;
}

.cb-18__btn:active {
  scale: .96 .9;
  translate: 0 2px;
  box-shadow: inset 7px 7px 15px color-mix(in oklab,var(--deep) 38%,transparent), inset -7px -7px 14px color-mix(in oklab,white 32%,transparent), 0 6px 12px -10px color-mix(in oklab,var(--deep) 60%,transparent);
}

.cb-18__btn:focus-visible {
  outline: 3px solid color-mix(in oklab,var(--deep) 60%,var(--clay));
  outline-offset: 5px;
}

.cb-18__btn:disabled {
  cursor: not-allowed;
  filter: grayscale(.6);
  opacity: .6;
}

@media (prefers-reduced-motion: reduce) {
  .cb-18__btn,
    .cb-18__ico {
    transition: none;
  }
}

@media (forced-colors: active) {
  .cb-18__btn {
    background: ButtonFace;
    color: ButtonText;
    border: 1px solid ButtonText;
    box-shadow: none;
  }

  .cb-18__ico {
    box-shadow: none;
    border: 1px solid ButtonText;
  }
}
```

How this works

Clay is entirely about the inset shadow pair — one light from the top-left, one dark from the bottom-right, both large and soft, plus a tight outer shadow for contact:

.cb-18__btn{
  background:var(--clay);
  box-shadow:
    inset 8px 8px 16px color-mix(in oklab,white 55%,transparent),
    inset -10px -10px 20px color-mix(in oklab,var(--deep) 45%,transparent),
    0 16px 30px -14px color-mix(in oklab,var(--deep) 60%,transparent);
}

The squash uses non-uniform scale — 0.96 across, 0.9 down — which is what sells deformation. Because scale is its own property now, it composes with the hover translate without either overwriting the other:

.cb-18__btn:hover{ translate:0 -3px; }
.cb-18__btn:active{ scale:.96 .9; translate:0 2px;
  box-shadow:inset 6px 6px 14px color-mix(in oklab,var(--deep) 40%,transparent),
             inset -6px -6px 12px color-mix(in oklab,white 35%,transparent); }

Note the shadows swap direction on press: the light source now hits the far edge, which is exactly what happens when a soft surface dents. A springy linear() easing on release gives the material its rebound.

Make it yours

  • --clay is the only colour you need to change; the highlight and shade are mixed from it and --deep.
  • Radius is the personality: 2rem is bubblegum, 1rem is app-like, 50% makes a clay ball for icon buttons.
  • Increase both inset blurs together to inflate the button; unequal values make it look wet rather than matte.
  • Add a second clay chip behind the label for a badge — the same shadow recipe scales down to 1rem elements.
  • For dark clay, keep the highlight low (25-30% white) or it turns plastic.

Gotchas — read before shipping

  • Clay is a low-contrast style by nature: the label must be a real ink colour, not a tint of the clay, or it fails contrast at every size.
  • Large inset blurs are expensive at scale — do not put forty of these in a scrolling list with transitions on the shadows.
  • Don't animate border-radius to fake the squash; scale is compositor-friendly and radius is not.
  • The classic mistake is one inset shadow. Two, in opposing directions, is the minimum for a rounded surface to read as volume.
  • In forced-colors mode all of this disappears by design; make sure the button still has a border, or it vanishes entirely.

Browser support

ChromeSafariFirefoxEdge
113+17.2+112+113+

linear() spring easing needs Chrome 113 / Safari 17.2 / Firefox 112, with a cubic-bezier fallback declared first. Individual scale/translate need Chrome 104 / Safari 14.1 / Firefox 72.

Techniques used in this demo

Search CodeFronts

Loading…