← Effects

Sunburst rays

Decorative backgrounds · Pure CSS

A sunburst of alternating rays radiates from a point near the top centre of the page, like a retro poster or a stage light. The rays turn very slowly and fade out before the edges of the page, with a soft glow at their origin. Bold, but it stays behind the content.

✓ (2×) · claude-haiku-5-5 → claude-opus-5-5
# Build the "Sunburst rays" background effect (`conic-rays`)

Family: Decorative backgrounds · pure CSS. Alternating rays radiate from above the hero and turn very slowly.

## Look
A sunburst of alternating rays radiates from a point near the top centre of the page, like a retro poster or a stage light. The rays turn very slowly and fade out before the edges of the page, with a soft glow at their origin. Bold, but it stays behind the content.

## Parameters (current values)
- Speed `--fx-speed`: 0.3 (range 0.1–2)
- Rays `--fx-rays`: 18 (range 8–36) — number of ray pairs
- Strength `--fx-opacity`: 0.25 (range 0.05–0.6)
- Origin height `--fx-origin`: 0.12 (range 0–0.6) — share of the height from the top
- Rays `--fx-color-ray`: the `primary` colour token, `var(--c-primary)`
- Background `--fx-color-bg`: the `bg` colour token, `var(--c-bg)`

## Recipe
- The element: `background-color: var(--fx-color-bg)`.
- Rays on `::before`: `content: ''; position: absolute; left: 50%; top: calc(var(--fx-origin) * 100%); width: 400%; aspect-ratio: 1; translate: -50% -50%` (sized from the element, so it works in a small tile and a full page), with `background: repeating-conic-gradient(from 0deg, R 0deg, R calc(180deg / var(--fx-rays) - 0.4deg), transparent calc(180deg / var(--fx-rays)), transparent calc(360deg / var(--fx-rays) - 0.4deg), R calc(360deg / var(--fx-rays)))` where R is `color-mix(in srgb, var(--fx-color-ray) calc(var(--fx-opacity) * 100%), transparent)` — the 0.4deg ramps soften the ray edges.
- Fade the rays on `::before` with `mask-image` and `-webkit-mask-image`: `radial-gradient(closest-side, #000 0%, #000 6%, transparent 50%)` — the layer is four times the element's width, so the rays fade out about one element-width from the origin.
- Glow on `::after` (`content: ''; position: absolute; inset: 0`): `radial-gradient(circle at 50% calc(var(--fx-origin) * 100%), color-mix(in srgb, var(--fx-color-ray) calc(var(--fx-opacity) * 120%), transparent), transparent 35%)`.
- Inside `@media (prefers-reduced-motion: no-preference)`: `::before` runs keyframes `fx-rays-turn` (`rotate: 0deg` to `rotate: 360deg`, using the `rotate` property so the `translate` stays) for `calc(120s / var(--fx-speed))`, linear, infinite.

## CSS fallback
It is pure CSS: the still state, before the rays turn, is the whole effect.

## Runtime rules
- Mount it in one element that fills a fixed, `pointer-events: none`, `aria-hidden` layer behind the page content; every parameter above is a CSS custom property on that element.
- Colours come only from the colour-token variables above (mix them with `color-mix()` or alpha), never hard-coded hex, so the effect follows any palette and light or dark mode.
- CSS only: gradients, `mask`, pseudo-elements and inline `data:image/svg+xml` (no `<script>` or `<image>` inside it). No images, remote URLs, `@import` or JavaScript. Keep it under ~8 KB.
- Animate only inside `@media (prefers-reduced-motion: no-preference)`, with durations divided by `--fx-speed` (for example `calc(24s / var(--fx-speed))`). The still state, before any animation runs, must look complete: it is what reduced motion and screenshots (a `?shot` URL flag) show.

## Avoid
- Strength above 0.5 behind body text
- Fast spinning: under 60 seconds per turn at speed 1
- Hard, aliased ray edges
- A second ray colour or rainbow rays
Copied!

↑ ↓ to move · Enter to open · Esc to close