divot.css

v0.2.0

divot.css

A simple skeuomorphic button style for a satisfying button experience.

background

Buttons should be satisfying to press.

Real physical buttons are so satisfying to press, and I wanted to try to bring that feeling to the web. The key feature of this stylesheet is a soft divot around the button that keeps its face flush with the surface.

It’s a simple, no-frills skeuomorphic style that mimics light catching the edges of the cut. The result is a page that feels tangible and makes you want to click things.

light ground lo hi face · flush hi lo 2px

gallery

Every divot button type.

Add one modifier to .divot to change its style. Every variant keeps the same size, so they line up in any layout.

.divot The default, flush with the page.
aria-pressed A toggle held down while on.
.raise The primary action, raised.
.quiet Borderless until hovered.
.ghost A lighter cut, for grouped buttons.
.firm A deeper cut, for busy backgrounds.
.bare No border, for list and menu rows.
.icon A square box for a single icon.
.eased Softly rounded 3px corners.
.pill Fully rounded, for chips and filters.
.danger Inverts on hover, for deletes.
:disabled Faded, but keeps its size.

elevation

+1 / .raise Raised, for the primary action.
0 / .divot Flush, the default resting state.
−1 / pressed Pressed in, where every click lands.

customize

Change your light source.

Every wall on the page takes its light from one value. Drag the lamp around the ring to move it. The button inside is a real .divot: see the cut up close at 2×, or switch to 1× for actual size.

:root { --divot-light-angle: 315deg; }

reference

How to use this stylesheet.

classes
.divot
the button
.raise
one band up, the primary
.quiet .ghost .firm
strength 0 / 25 / 70
.bare
no walls
.icon
square box for a glyph
.eased .pill
3px / full-round corners
.danger
inverts on hover
states
:hover
groove deepens
:active
face sinks, label nudges
[aria-pressed="true"]
stays sunk
.active
same, as a class
:disabled
flat groove, faint ink
:focus-visible
1px outline, keep it
tokens · set on a container
--divot-ground
the surface it's cut into
--divot-strength
0–100
--divot-radius
0 by default
--divot-padding-y / -x
the box; not padding
--divot-raise-strength
how far .raise lifts
--divot-light-angle
315deg by default

install

Add it to your project.

Download
one file
<link rel="stylesheet" href="divot.css">
<button class="divot">Edit</button>
on a surface that isn't the page
<div class="ground-surface">
  <button class="divot">Edit</button>
</div>