Home / Snippets / Animation & Motion /
Blur reveal
Content starts blurred and sharpens on hover using filter: blur() with a smooth transition.
Quick implementation
.blur-reveal {
filter: blur(4px);
transition: filter 0.4s ease;
}
.blur-reveal:hover {
filter: blur(0);
}
@media (prefers-reduced-motion: reduce) {
.blur-reveal {
filter: blur(0);
transition: none;
}
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer building a CSS interaction library.
Goal: A blur reveal hover effect — content starts blurred and sharpens to focus on hover using only CSS.
Technical constraints:
- Apply filter: blur(4px) to the element by default and transition to filter: blur(0) on :hover.
- Use transition: filter 0.4s ease — not transition: all.
- filter: blur() creates a new stacking context; document this as a known side effect.
- Use oklch() for any background or border colors in the demo.
- Include @media (prefers-reduced-motion: reduce): set filter: blur(0) and transition: none so content is always readable without motion.
Framework variant (pick one):
A) Vanilla CSS — utility class, blur amount configurable via --blur-amount custom property.
B) React component — accept blurAmount (default 4) and duration (default 0.4s) as props.
Edge cases to handle:
- Screen readers can still access blurred content — blur is visual only. Add aria-label if the blurred state conveys "hidden" semantics.
- filter: blur() clips content to its painted bounds slightly — add a small overflow: visible or padding buffer if edges are cropped.
- Combine with opacity: 0.5 → 1 for a richer reveal without adding extra transitions — just extend the transition list.
- Works on text, images, and card containers.
Return CSS.
Why this matters in 2026
Blur reveal is used for content teaser effects, hover-to-preview patterns, and focus-state highlighting in dashboards. It communicates "this content is discoverable" without hiding it from screen readers or search engine indexing. A pure CSS implementation avoids JavaScript event listeners and handles both mouse and keyboard focus with the right selector combinations.
The logic
The element starts with filter: blur(4px), which rasterizes the element and applies a Gaussian blur. On hover, the filter transitions to blur(0) — effectively no blur. The transition: filter 0.4s ease declaration animates this change. Because filter creates a new stacking context, positioned children with z-index values may stack differently; account for this if the blurred element contains overlapping layers.
Accessibility & performance
@media (prefers-reduced-motion: reduce) removes both the blur and the transition, ensuring content is always sharp and readable for users who have opted out of motion effects. Unlike opacity: 0, a blurred element remains accessible to screen readers — the text is still in the DOM and read aloud. filter triggers paint and compositing; it is more expensive than transform-only animations, so avoid applying it to large or frequently-repainted elements.