Backgrounds
StableDot and grid patterns, masks and vignettes to fade them, a retro floor grid, a spotlight, a lamp and a softly lit card.
The background layers behind the Magic UI and Aceternity style screens, rebuilt in plain CSS. Each one is a class on an empty, aria-hidden layer inside a relative, isolated, overflow-hidden box; masks and vignettes fade a pattern into the page. Anything that moves does it once and then holds.
Updated View source
Patterns and fades
/** * Pattern layers sit behind content (absolute, -z-10, aria-hidden) inside a relative, isolated, * overflow-hidden box. A mask or a vignette fades their edges into the page. */const tiles = [ { name: 'fx-dots + fx-mask-center', layers: <div className="fx-dots fx-mask-center absolute inset-0 -z-10" /> }, { name: 'fx-grid + fx-vignette', layers: ( <> <div className="fx-grid absolute inset-0 -z-10" /> {/* The vignette paints the page colour over the edges: match it to the box behind */} <div className="fx-vignette absolute inset-0 -z-10 [--vig:var(--rc-surface)]" /> </> ), }, { name: 'fx-dots + fx-mask-bottom', layers: <div className="fx-dots fx-mask-bottom absolute inset-0 -z-10" /> }, { name: 'fx-magic-card', layers: <div className="fx-magic-card absolute inset-0 -z-10" /> },]
export default function BackgroundPatterns() { return ( <ul className="grid w-full max-w-2xl grid-cols-2 gap-3 sm:gap-4"> {tiles.map((t) => ( <li key={t.name} className="relative isolate flex h-36 items-start overflow-hidden rounded-xl bg-surface p-3 ring-1 ring-line sm:h-44"> <div aria-hidden="true">{t.layers}</div> <code className="rounded-md bg-surface/80 px-1.5 py-0.5 font-mono text-[11px] text-fg-2">{t.name}</code> </li> ))} </ul> )}Usage
// Once, in your app entry: Tailwind, the brand tokens, the effects and the finishing layerimport '@rchursin/product.css'<section className="relative isolate overflow-hidden"> <div aria-hidden="true" className="fx-dots fx-mask-center absolute inset-0 -z-10" /> …</section>Examples
Retro grid
A floor of lines in perspective that drifts into place once, behind a heading.
/** * Retro grid: a floor of lines in perspective that drifts into place once, then holds. * It needs this exact nesting: fx-retro › fx-retro-plane › fx-retro-lines, plus fx-retro-fade. * The fade is white in light mode and #0a0a0a in dark, so put it on a matching ground. */export default function BackgroundRetro() { return ( <section className="relative isolate flex min-h-80 flex-col items-center justify-center gap-3 overflow-hidden bg-surface px-6 py-16 text-center"> <div aria-hidden="true" className="fx-retro -z-10"> <div className="fx-retro-plane"> <div className="fx-retro-lines" /> </div> <div className="fx-retro-fade" /> </div> <p className="font-mono text-[11px] tracking-[0.14em] text-fg-3 uppercase">Open source</p> <h3 className="max-w-sm text-[28px]/[1.15] font-semibold tracking-[-0.03em] text-balance text-fg">One command, every skill measured</h3> </section> )}Spotlight and lamp
Two lights that switch on once: a beam from the top left, and a cone over a glowing line.
import { Logo } from '@rchursin/brand/Logo'
/** * Two lights that switch on once. fx-spotlight is a soft beam falling across a hero from the * top left. fx-lamp is a cone of light over a glowing line: fx-lamp holds the two halves, and * fx-lamp-glow and fx-lamp-line sit beside it. Both hold still with reduced motion. */export default function BackgroundLight() { return ( <div className="grid w-full gap-px bg-line md:grid-cols-2"> <section className="relative isolate flex min-h-72 flex-col justify-end gap-2 overflow-hidden bg-surface p-6"> <div aria-hidden="true" className="fx-spotlight -z-10" /> <h3 className="text-[22px]/[1.2] font-semibold tracking-[-0.025em] text-balance text-fg">Spotlight on what works</h3> <p className="text-[13.5px]/6 text-fg-2"> <code className="font-mono text-[12.5px]">fx-spotlight</code> </p> </section> <section className="relative isolate flex min-h-72 flex-col items-center overflow-hidden bg-surface px-6 pt-52 pb-6"> <div aria-hidden="true" className="fx-lamp -z-10"> <div className="fx-lamp-left" /> <div className="fx-lamp-right" /> </div> <div aria-hidden="true" className="fx-lamp-glow -z-10" /> <div aria-hidden="true" className="fx-lamp-line" /> <Logo variant="mark" title="" className="absolute top-24 size-10 text-fg" /> <p className="text-[13.5px]/6 text-fg-2"> <code className="font-mono text-[12.5px]">fx-lamp</code> </p> </section> </div> )}API
CSS
| Class or variable | What it does |
|---|---|
fx-dots | 1px dots on a 16px grid (--dot: #d4d4d4, #333 in dark mode). Change the spacing with [background-size:20px_20px]. |
fx-grid | 1px lines on a 40px grid (--grid: #e5e5e5, #262626 in dark mode). |
fx-mask-center | Masks the layer to an ellipse in the middle: solid to 20%, gone by 75%. |
fx-mask-bottom | Masks the layer to an ellipse rising from the bottom centre. |
fx-vignette | A layer of --vig (white, or black in dark mode) masked to the edges by --vig-mask. Set --vig to the colour of the box behind it. |
fx-retro | A perspective floor grid at 55% opacity, absolute over its box. Needs fx-retro-plane with fx-retro-lines inside it, and fx-retro-fade beside the plane. |
fx-retro-plane | Tilts the floor 65° away from the viewer. |
fx-retro-lines | The 60px grid lines (--grid-line). They drift into place over 4s once, then hold. |
fx-retro-fade | Fades the far end into --fade, an "r g b" triplet: 255 255 255, or 10 10 10 in dark mode. |
fx-spotlight | A blurred 980 × 420px beam falling from the top left (8% black, or 20% white in dark mode). It swings and fades in over 2s after 0.4s, once. |
fx-lamp | The cone of light: 180px tall across the top of its box, holding .fx-lamp-left and .fx-lamp-right. Brightens from 40% over 1.6s. |
fx-lamp-left, fx-lamp-right | The two halves of the cone, drawn as conic gradients of --lamp. |
fx-lamp-glow | A blurred pool of light under the cone, 140px from the top. A sibling of fx-lamp. |
fx-lamp-line | The lit 2px line at 179px, widening from 7.5rem to 15rem over 1.6s. A sibling of fx-lamp. |
fx-magic-card | A still glow from the top left (18% across) fading into the card colour (--mc-glow, --mc-bg). |
Accessibility
- Every layer is decoration: keep it empty and mark it aria-hidden.
- Patterns are light greys and the masks fade them where text usually sits; still check text contrast over the strongest part.
- With reduced motion the retro grid, spotlight and lamp start in their final state.
Guidelines
Do
- Make the box relative, isolate and overflow-hidden, and the layer absolute with -z-10.
- Fade every pattern with a mask or a vignette so it never stops at a hard edge.
- Match fx-vignette’s --vig and fx-retro-fade’s --fade to the ground behind them.
Don’t
- Don’t set text over the densest part of a pattern.
- Don’t use more than one background effect per section.
In use
Related
- Light & grainA ceiling halo for heroes, film grain for flat grounds, a fade for product shots and a shadow that follows torn paper.
- Animated accentsShiny and gradient text, a beam round a border, a shine border, ripples, lines that type in and a scanning column.
- Magic UI screensFive screens with Magic UI’s effects: retro grid, border beam, shiny and gradient text, shimmer buttons, ripples and a dock.
- Aceternity screensFive screens in the Aceternity style: a spotlight hero, a borderless sidebar, a signup-style form, a floating navbar and a lamp.
Source
The component’s own files, exactly as they run on this site.
/* Effects behind the Magic UI- and Aceternity-style screens, written in plain CSS (no animation library). Light values are the default; anything inside a `.dark` ancestor switches to the dark values. All motion stops for people who ask for reduced motion. Everything sits in @layer components, so Tailwind utilities on the same element win (e.g. `fx-dots [background-size:20px_20px]`).
Ported from the RChursin_ UI kit (rchursin/styles/effects.css). The word field at the end is a site addition (not in the kit), so `kit.ts diff` reports that block as the only drift.*/
@layer components { @keyframes rc-spin { to { transform: translate(-50%, -50%) rotate(360deg); } } @keyframes rc-shine { from {