The library

Techniques, not templates

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

001 / 161

3D Carousel: Rotate, Then Push

One rule places every card. rotateY() turns the card to its seat, which re-aims the card's own z axis outwards, and translateZ() then walks it along that new axis to the rim, so only --i changes. Swap the two and every card is pushed at the camera before it turns: the rotation swings one stack around the parent and you get a fan, not a ring. The radius is derived, not guessed. The cards are the sides of a regular polygon, each side one card plus one gap long, so r = (card + gap) / 2tan(180deg / n): pick the gap and the radius follows, which is why the count buttons set --n and nothing else. The spin is one keyframe on a registered --angle, so a drag can take the wheel and hand it straight back.

animationcssuicarouseljavascript3dinteractiontransformperspective
002 / 161

Squircles in CSS: corner-shape Cuts the Corner

Chromium 139 and up only. Safari and Firefox drop the declaration and keep the border-radius, which is the rounded box you already ship, so the fallback costs nothing. A round corner is a quarter circle: it meets the straight edge at an angle. corner-shape says which curve cuts the corner instead, and squircle keeps curving into the edge, the shape phone home screens have used for a decade. It needs a border-radius to work on, since that is what says how far the corner is cut. Every named value is one point on a single curve: bevel is superellipse(0), round is superellipse(1), squircle is superellipse(2), and negatives scoop the corner inwards. notch and square sit at the two infinities.

cssborder-radiusuino-jscornersshapesiconscorner-shape
003 / 161

Inverting Headline: White Minus the Backdrop

One line, and the headline stops needing a colour. mix-blend-mode: difference subtracts the two layers channel by channel, so white text hands back the exact inverse of whatever is under it: black on a bright sheet, white on a dark hero, cyan over magenta, all of it per pixel and without a second copy of the text. Three things bound it. Mid grey is the blind spot, since 128 against 255 comes back as 127, the grey it was meant to beat. Only white is a true invert, because any other colour has channels it cannot fully subtract. And a blended element reads everything painted beneath it in its stacking context, so isolation: isolate on the scene is what stops the headline from subtracting the whole page.

csscontrasttypographytextcolorblend-modeno-jshero
004 / 161

Refractive Glass: Noise Bends the Backdrop

Chrome is the only engine that bends a real backdrop. Safari and Firefox run an SVG filter on an element and never on a backdrop, so there it is a copy of the scene's own gradient that bends, and over arbitrary content they get the frost and nothing else. Frosted glass blurs what is behind it; real glass moves it. 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 because a fragment reference cannot be resolved from a sandboxed frame.

cssjavascriptnoiseglassmorphismblurbackdrop-filterfiltersvg
005 / 161

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
006 / 161

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
007 / 161

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, because animation-delay is a length of time and this timeline has none. 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
008 / 161

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
009 / 161

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
010 / 161

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
011 / 161

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
012 / 161

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