Jhey CSS Techniques

A running collection of production CSS recipes from Jhey Tompkins (@jh3yy), a design engineer at Shopify's brand design studio and author of the craftofui.dev playbook. Each leans on modern, progressively enhanced CSS (scroll-driven timelines, masks, registered custom properties) with no JavaScript.

Jhey's signature is the "extra little details" pass: effects that degrade gracefully and run on the compositor. These pair with the timeline primitives in Scroll-Driven Animations (CSS) and the discrete patterns in X Bookmarks: CSS & Frontend Techniques.

Animated scrollbar-color

scrollbar-color: var(--thumb, canvasText) var(--track, #0000) styles thumb and track in two values and drops the vanilla track. Animate a registered custom property on a timeline to sync the thumb hue with the active item:

html {
  scrollbar-color: oklch(65% 0.3 var(--p)) #0000;
  animation: sync;
  animation-timeline: --ul;
  animation-range: entry 50% exit 50%;
}
@keyframes sync { to { --p: 320; } }

Source: X/@jh3yy, 2026-05-30 (794 likes, 635 bookmarks). The OKLCH hue ramp ties into OKLCH in Production.

Local video review shows a dark CodePen demo where the active word and scrollbar thumb hue change together. The config panel exposes hue start/end, a scrollbar toggle, and a theme selector, making the recipe concrete: a transparent track plus a dynamic thumb is enough to make the scrollbar read as part of the page's state. MDN now marks scrollbar-color Baseline 2025 and documents the exact two-color syntax, with the accessibility caveat that thumb and track colors still need sufficient contrast and forced-colors mode resets the value to auto. Source: local contact sheet /tmp/xreview-next15-videos/2060729282402423141-sheet.jpg, reviewed 2026-07-02; Source: MDN, 2026-07-02

Scroll masking (progressive enhancement)

Fade content at a scroller's edges by animating mask-size on a scroll timeline, then excluding the overlap with mask-composite:

.scroller {
  animation: mask-up;
  animation-timeline: scroll(self);
  animation-range: 0 1rem;
  mask-composite: exclude;
}
@keyframes mask-up { to { mask-size: 100% 120px, 100% 100%; } }

The mask only grows once the user scrolls, so unsupported browsers see no fade and lose nothing. The reviewed local video shows a card titled "Scroll Masking" inside a scrollable container, a red scrollbar, and a config panel where mask size/range changes affect the fade edge live. This is a concrete application of Scroll-Driven Animations (CSS) because the visual polish is attached to scroll state without requiring a JavaScript scroll listener. Source: X/@jh3yy, 2024-05-11 (3,460 likes, 3,733 bookmarks); Source: local video artifact review, 2026-07-01

Image-mask keypad

Build an interactive keypad from three image assets (a base plus keycaps) without slicing. Use a keycap PNG as a mask on each key container, translate the contained <img> on :active, then clip-path the hit area and filter the keys:

.key { mask: url(keycap.png); }
.key:active img { translate: 0 20%; }

No need to cut sprites: place keycap images on top of the base inside containers, then clip and mask those containers using the image they contain. The reviewed video shows the interaction layer, not just the static trick: hover/press key travel, live controls for theme, hue, travel, saturation, brightness, and a key-recording flow that updates labels and active state. MDN's current mask reference confirms the shorthand owns mask image source, size, repeat, clip/origin, and compositing; clip-path remains Baseline widely available and defines the visible hit/display region. Source: X/@jh3yy thread, 2025-07-10 (876 likes, 551 bookmarks); Source: local video contact sheet, 2026-07-02; Source: MDN mask, 2026-07-02; Source: MDN clip-path, 2026-07-02

A fourth jh3yy recipe — CSS anchor positioning for magnetic nav highlights — now has a dedicated feature page at CSS Anchor Positioning (also listed in X Bookmarks: CSS & Frontend Techniques).


Timeline