A living library of web craft

Imperial Web Tricks

Imperator Design is a curated canvas of modern CSS, JavaScript and layout techniques. Copy the code, watch it run, ship it today.

164Tricks
327Tags
100%Copy-paste
The library

Techniques, not templates

Each entry is a self-contained, production-ready trick recreated from the source video. Click one to watch it run.

001 / 164

Neon Sign: The Letters Are White

The letters are white. Every bit of color is in the shadow behind them, which is why this reads as glass and gas rather than as colored text. Four shadows do it, at 4, 12, 28 and 60 pixels: the first is white and tight so the glyph keeps a hot core, and the other three are the hue, each wider than the last. Stacking them is what makes the falloff, since a single large blur only ever gives a flat halo. The border is the same tube bent into a rectangle, the shadow stack repeated as box-shadow outward and inward so it lights both the wall behind it and the air it encloses. One custom property carries the color, so a swatch sets --neon and nothing else.

002 / 164

Gliding Pill Nav, No Measuring

A pill that follows the pointer without measuring anything. The hovered link takes anchor-name: --pill, and the rail's ::before sets position-anchor: --pill and inset: anchor(top) anchor(right) anchor(bottom) anchor(left), so its four edges are that link's four edges: it becomes the link, wherever the link sits. Transitioning inset turns the jump into a glide. Two elements holding one anchor name is not an error, it is worse: the later one in the DOM quietly wins, so an active link at the end of the rail steals the pill back from anything hovered before it. While the rail has a hovered link, the resting link gives up the name. The rail carries no padding, no gap and square links, because hit testing follows border-radius and any dead pixel hands the pill back mid-glide.

003 / 164

Odometer Price Roll

No digit is ever rewritten. Each column is a strip of 0 to 9 behind a window one line tall, and translate: 0 calc(var(--d) * -1lh) slides the strip until digit --d is the one showing. 1lh is the whole trick: the window and the step are both read off the same line box, so the strip stays in register at any font size without one pixel value anywhere. Changing the price is then changing two numbers, and :has lets the checkbox do it from inside the card, so .card:has(#yearly:checked) rewrites --tens and --ones and the wheels follow. A spring ease overshoots by a hair so each wheel settles instead of stopping dead, and the ones column starts a beat after the tens so the count cascades.

004 / 164

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.

005 / 164

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.

006 / 164

Inverting Headline: White Minus the Backdrop

One line, and the headline stops needing a color. 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 gray is the blind spot, since 128 against 255 comes back as 127, the gray it was meant to beat. Only white is a true invert, because any other color 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.

007 / 164

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.

008 / 164

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.

009 / 164

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.

010 / 164

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.

011 / 164

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 color 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.

012 / 164

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.

Browse by category

Find the move you need

Every trick, filed by the craft it demonstrates. CSS, motion, layout and more. Choose a category to jump straight to what fits.

Your next trick awaits

Steal like a professional

Self-contained HTML, CSS and JS, written to be copied and pasted straight into your own project.