Skip to content
← writing

Progressive blur: ramping a marquee's edges into a haze

css
backdrop-filter
mask
marquee

The usual way to fade a marquee's edges is an opacity gradient mask: the content just gets transparent. A nicer version fades it into blur, so the logos seem to dissolve into a haze as they scroll off. Here it is on both ends:

Orbit
Prism
Vertex
Loop
Quanta
Flux
Cobalt
Ember

One blur won't ramp

backdrop-filter: blur() is uniform. Everything behind the element gets the same blur, and it stops dead at the element's edge. There's no built-in way to say "blur a little here, a lot over there." So you fake the gradient by stacking layers.

Stack and mask

Render a handful of overlapping layers. Each one blurs a bit more than the last, and each is masked to a band that fades in and out:

const step = 1 / (layers + 1);
const blurBase = blurRange ** (1 / (layers - 1));
 
layers.map((layer) => (
  <div style={{
    backdropFilter: `blur(${blurBase ** layer}px)`,
    maskImage: `linear-gradient(to left,
      transparent ${layer * step * 100}%,
      black       ${(layer + 1) * step * 100}%,
      black       ${(layer + 2) * step * 100}%,
      transparent ${(layer + 3) * step * 100}%)`,
  }} />
));

Two details make it read as smooth. The blur grows geometrically (1, 1.7, 2.8, 4.8, 8…), which matches how blur actually looks as it deepens. And each band overlaps its neighbours by a step, so where one layer fades out the next is already fading in. The eye blends them into a single continuous ramp instead of five visible steps.

direction just swaps which way the gradient points, so you can deepen the blur toward any edge. Drop one over the left and one over the right of an overflow-hidden marquee and the ends melt away.

Worth knowing

backdrop-filter isn't free; a handful of stacked layers is fine, but it's not something to scatter across a whole page. And like all backdrop blur it needs content behind it to blur, so it lives over scrolling or busy areas, not flat ones.

Recreated from frostin-ui's ProgressiveBlur. Grab the component on the Progressive Blur page.

Ask your agent to implement this

Read the full writeup at https://seangeng.com/writing/progressive-blur-marquee.md and implement it in my project.

It covers: Progressive blur: ramping a marquee's edges into a haze — A single backdrop-filter blurs uniformly with a hard edge. Stack a few blur layers, mask each to an overlapping gradient band, and the blur ramps smoothly — perfect for fading the ends of a marquee.

Requirements:
- Follow the technique/approach exactly as described in the writeup.
- Adapt names, colors, and styling to my project's existing conventions.
- If it's a component, make it reusable with sensible props and TypeScript types.
- Keep it accessible: semantic HTML, keyboard support, and respect prefers-reduced-motion.
- When done, tell me which files you created or changed and how to use it.

Paste into Claude Code, Codex, Cursor, or any agent. view raw .md download source .zip