The library

Techniques, not templates

Every trick recreated from the source video as a live, self-contained demo. Search, filter, open, steal.

001 / 158

Refractive Glass: Noise Bends the Backdrop

Frosted glass blurs what is behind it; real glass moves it. The difference is one SVG filter: feTurbulence paints a cloud, feDisplacementMap reads red as how far each backdrop pixel travels along x and green as y, and it runs before the blur averages anything. The lens and the frost are siblings, never nested: an element with a backdrop-filter starts its own backdrop root, so a lens inside the frosted box would find nothing left to bend. The filter travels as a data URI: a fragment reference resolves against the document, and this demo runs in a sandboxed frame with an opaque origin, where Chrome refuses it and paints the frame empty. Chrome is also the only engine that bends a real backdrop. Safari and Firefox run an SVG filter on an element but never on a backdrop, so what bends here is a copy of the scene's own gradient, pinned with background-attachment: fixed so it lands on the original to the pixel. That only works because this demo painted what is behind the glass. Over arbitrary content, a page scrolling under a header, those two get the frost and nothing else.

cssjavascriptnoiseglassmorphismblurbackdrop-filterfiltersvg
002 / 158

Seamless Marquee: Two Copies, Half a Slide

A marquee loops with no visible jump when the run is repeated twice and slid by exactly half the track: half the track is one whole copy, so at the end copy two stands where copy one started and the restart has nothing to show. Three details decide it. The travel has to be translateX(-50%), a percentage of the element being transformed, so it tracks the run's width on its own. The track needs width: max-content, or it wraps at the parent's width. And the spacing belongs to the items, not the track: a gap sits between the two copies as well as inside them, so a 34px track gap puts one copy 17px out of step, while padding-inline-end leaves the halves identical.

animationcssno-jsmarqueetransformkeyframesticker
003 / 158

Pulsing Status Dot: The Ring Is a Box Shadow

A pulsing status dot is usually three elements: a wrapper, a ring, and the dot. It needs one. box-shadow paints outside the border box and takes no part in layout, so the halo is a second shape the element already owns: grow the spread from 0 to 14px while the alpha runs out and the ring swells past the dot, moving nothing around it. One span, two keyframes. The shadow reads color-mix(in srgb, var(--dot) 70%, transparent), so green, red, amber and blue all run the same pulse, and it inherits border-radius, so the circle and the rounded square differ by that one property. cubic-bezier(0, 0, .35, 1) throws the spread out at once and then crawls, which is what a ripple looks like; linear reads as a blinking outline.

animationcssbox-shadowno-jskeyframesstatuspulse
004 / 158

Scroll-Driven Animation: The Scroll Is the Clock

A scroll-driven animation is an ordinary @keyframes animation with its clock swapped out: animation-timeline: view() replaces time with the element's own trip through its scroller. Nothing fires, nothing needs teardown, and it runs on the compositor. animation-range picks which slice of that trip the keyframes get: cover, entry, exit, contain. Rings and cards pin with position: sticky and read scroll(), since view() times an element against travel a pinned box no longer has. Rows stagger inside entry, since animation-delay is a length of time and this timeline has none. Stats counts through a registered @property holding an integer. Two traps: animation-timeline goes after the animation shorthand, which resets it, and @supports has to land everything finished where scroll timelines are missing.

animationcssscrollno-jsanimation-timelinescroll-drivenanimation-range
005 / 158

Skeleton Shimmer: Paint Wider Than the Box

A shimmer is one gradient painted wider than the element that shows it, then slid sideways: the box never moves, only the paint inside it. The first tab is the everyday skeleton at the reel's 1.2s. The second is the mechanism, slowed to 6s with the clipped overhang drawn faintly beside the box. Three things decide whether it loops cleanly. The travel has to equal the image width, not the element width, or the gradient jumps at the wrap. The stops sit at 25/50/75 rather than 0/50/100, so the image starts and ends on the same colour and repeat-x shows no seam. And the offset is in pixels, because a background-position percentage resolves against (box - image), negative once the image is the wider of the two.

animationcssgradientloadingskeletonbackground-position
006 / 158

Sprite Sheet Animation with steps()

A sprite sheet is one image and a keyframe that slides it: background-position travels the sheet's full width while steps(10) freezes it on each frame for 140ms, so the browser draws ten discrete poses instead of tweening between them. The strip above is the same image at 3x, running the same duration and step count, so it always sits over the frame being drawn below. Three things decide whether it lines up. The travel is the whole sheet width, not one frame short: steps() defaults to jump-end and never lands on the end value. background-size is in pixels, because a percentage there resolves against the element and the frames would drift. And image-rendering: pixelated, or 18px art smooths into mush.

animationcsskeyframespixel-artspritegame-ui
007 / 158

Staggered Reveals with sibling-index()

Five staggers, one function, and no :nth-child ladder anywhere: sibling-index() reads each element's own position in its parent, so rows added or reordered later re-stagger themselves. The list is the reel's code verbatim, animation-delay: calc(sibling-index() * 100ms). The equalizer drives three properties from one call: delay, height through sin(), and hue. Orbit uses the index as geometry rather than timing, rotate(calc(sibling-index() * 30deg)) translateY(-56px) for twelve dots with no coordinates. Grid turns the flat index into coordinates with mod() and round(down), whose sum sweeps a diagonal ripple. Each declaration sits after a plain fallback. Chrome 149+ and Safari 26.5.

animationcssstaggeredlistcustom-propertiesnth-child
008 / 158

Before/After Slider Driven by a Range Input

A comparison slider where the whole drag is a native <input type="range">, stretched over the image at opacity 0. One line of JavaScript copies its value into --pos; clip-path: inset(0 0 0 var(--pos)) on the top layer and left: var(--pos) on the divider read the same variable, so the seam and the handle can never drift apart. Pointer capture, touch, and arrow-key stepping all come from the input. Two details make it line up. The thumb has to be 1px wide, because a range maps its value across the track minus the thumb, so a default 16px thumb leaves the divider short of the edges at 0 and 100. And step="0.1", because the default step of 1 quantises a 560px sweep into 5.6px jumps.

cssjavascriptinteractionimagesclip-pathslider
009 / 158

Animated Gradient Text Glow

One gradient, clipped to the glyphs and animated by background-position, fills the text; a pseudo-element repeats the same clipped gradient behind it and blurs it into a halo that travels with the colour. Two details make or break it. The glow copy must be set in the same font as the heading — leave the size on the wrapper and an h1 takes its 2em default, so the halo renders at half scale and reads as a smudge beside the word rather than light coming off it. And the wrapper needs isolation: isolate, because z-index: -1 without a stacking context of its own drops the glow behind the page background instead of behind the text. The gradient repeats its first colour last, so the loop has no seam.

animationcssgradientglowtext effectbackground-clip
010 / 158

Rotating Glow Border with @property

A conic gradient can start at any angle, and until that angle is a registered custom property the browser refuses to interpolate it — so the border jumps instead of sweeping. Declare it with @property and one spinning gradient serves a card, an avatar ring and a button, each changing only its palette, speed and direction. The halo is the same gradient again, blurred behind the edge. Worth knowing: inherits is a required descriptor, not an optional one. Leave it out and the whole rule is invalid, --a never registers, and every gradient silently computes to none.

animationcssui/uxgradientconic-gradient@property
011 / 158

Two-Handle Price Filter From Real Inputs

Every shop has a two-handle price filter and no HTML element does it, so people reach for a slider library or fake the whole thing with divs — and throw away keyboard support on the way. Stack two real range inputs on one track instead. pointer-events: none lets a click fall straight through the invisible tracks, pointer-events: auto on the thumbs keeps each one grabbable, and that pair is the entire trick: arrow keys, Home/End, Tab focus and aria all still work. One fill div reads both values, each input clamps against the other so the handles cannot cross, and the higher one sits on top or its thumb goes unreachable at the far end.

cssaccessibilityui/uxformsjavascriptrange
012 / 158

Drag-to-Reorder That Opens a Gap

What sells a sortable list is not the row you are holding — it is what the other rows do. Swap them the instant you cross a boundary and the list flickers; instead, every row past the drop target shifts by exactly one row height, and the gap that opens up is the drop indicator. Two details carry it: transform rather than top or margin, so the shift stays composited at fifty rows, and a short transition, because anything over about 0.2s lags behind your finger and reads worse than no animation at all.

animationcssui/uxjavascriptinteractiondrag and drop