vinyl-kit

A vinyl record for the web, built from one grayscale mask and a CSS blend mode — so a single 31 KB asset paints a record in any colour you like. Records, sleeves that slide open, fanned stacks, and colour read straight from cover art.

npm install vinyl-kit

Every record on this page is that same mask over a different colour fill. The markup is hand-written to mirror exactly what the React components render — same class names, same data attributes — so what you see is the CSS contract, with no framework in the way.

The record

Three layers inside a blend-isolated circle: a colour fill, the cover art as a centre label, and the groove mask blended with mix-blend-mode: luminosity — contributing lightness and nothing else, so the grooves take their hue from the fill underneath.

tint="#A15C08"
tint="#7B5E99"
tint="#59658A"
tint="#8E4242"
No cover — just a record

The sleeve

At rest the record peeks past the cover's edge; when the sleeve goes active it rolls out while the cover tilts. The whole move runs on one inheritable custom property, --vinyl-extract, so a parent can drive it from CSS alone — hover needs no JavaScript.

Dawn

Hover or focus this card

.card:hover { --vinyl-extract: 1 }

Bones

Hover or focus this card

Same markup, different tint
Driven by the active prop instead
data-active + reserve

The stack

A crate of records, each showing its own cover. Hovering spreads the fan wider — a transform-only move, so nothing around it shifts.

Spin

Pausing freezes the record where it stopped rather than snapping it back to zero — like lifting the needle. The spin keyframes re-declare the record's translateZ(0), because an animated transform would otherwise replace it and undo the compositing fix the blend mode depends on.

spinning={true}
watch where it stops

Colour from the cover

A plain average of a cover is mud — dark backgrounds and washed highlights win on pixel count. So pixels are weighted toward what the eye latches onto, saturated mid-lightness colour, then snapped onto a designed palette. This runs the package's actual extractAccent and nearestColor, compiled from source into this page.

Tinted by the colour read from the cover
Sample cover 1 Sample cover 2 Sample cover 3 Sample cover 4

Sampling…