import { Component } from '@angular/core';
import { WrBlurReveal } from 'ngwr/animations/blur-reveal';
@Component({ imports: [WrBlurReveal] })
export class MyComponent {}Blur Reveal
A text comes in piece by piece the first time it scrolls into view: each word, or each letter, from blurred and a little below its place to sharp and in place.
Installation
Import the class, and @use the entry point in your global styles. Nothing warns you when the @use is missing.
Basic
Put wrBlurReveal on the element that holds the text. It plays once, when most of the element is in view, and leaves the element exactly as it was: the same nodes, bindings included, go back when the last piece lands.
<h2 wrBlurReveal>Signal Forms, with nothing in between.</h2>Letters
by="letters" enters one grapheme at a time. The letters of a word sit in a no-wrap wrapper, so a word never breaks across lines mid-word, and an emoji or an accented letter is one piece.
<h2 wrBlurReveal by="letters">Built on the new Angular.</h2>From above
from="above" settles each piece down into its place instead of up.
<h2 wrBlurReveal from="above">The checks behind ngwr.</h2>Timing
delay is the pause between the element entering the viewport and the first piece. stagger is the gap from one piece to the next; unset, it is 70 ms for words and 28 ms for letters. Whatever the gap, the whole reveal spreads over 1.2 s at most, so a long paragraph does not keep the reader waiting. The blur, the offset, the duration and the easing are CSS variables.
<p wrBlurReveal delay="300" stagger="120">Each word waits for the one before it.</p>.hero h2 {
--wr-blur-reveal-blur: 0.4em;
--wr-blur-reveal-duration: 1s;
}Accessibility
| Part | Behaviour |
|---|---|
| Screen readers | While the pieces play they are aria-hidden, and a visually hidden copy of the text stands beside them, so the sentence is announced once and never letter by letter. At rest the element holds its original text nodes. |
| Reduced motion | Under prefers-reduced-motion: reduce nothing is split and nothing moves: the text is shown as authored. The demos on this page follow the same setting. |
| Server | The server renders the plain text. The split happens in the browser, after the first render, and only where IntersectionObserver exists. |
| Selection and search | Spaces between pieces stay real text, so the words wrap where they did, and find-in-page and copy work once the reveal has ended. |
API
| Name | Description | Type | Default |
|---|---|---|---|
by | What enters one at a time: a word, or a grapheme. In letter mode the letters of one word sit in a no-wrap wrapper, so a word never breaks across lines mid-word. | WrBlurRevealBy | 'words' |
from | The side a piece settles in from. | WrBlurRevealFrom | 'below' |
stagger | Gap between the start of one piece and the next, in ms. Unset, the mode decides: 70 for words, 28 for letters. Either way the whole reveal spreads over 1.2 s at most, so for a long text the gap shrinks until the last piece starts by then. | number | null | null |
delay | Pause between the host entering the viewport and the first piece, in ms. | number | 0 |
CSS variables
Set these on the element itself, with a rule more specific than its Declared on selector. In a global stylesheet, put a class of yours on an ancestor it really has: <body> for an overlay panel, which renders outside your markup. In a component stylesheet the selector alone works, but only for an element in that component's own template. A value on a wrapper or :root is shadowed, because ngwr/animations/blur-reveal declares each default on its own element.
| Variable | Default | Declared on |
|---|---|---|
--wr-blur-reveal-blur | 0.2em | .wr-blur-reveal |
--wr-blur-reveal-delay | 0ms | .wr-blur-reveal and inline on the element, written by the component from its inputs or its state — a rule holds only until the component writes |
--wr-blur-reveal-direction | 1 | .wr-blur-reveal +1 variant override |
--wr-blur-reveal-duration | 0.6s | .wr-blur-reveal |
--wr-blur-reveal-ease | var(--wr-ease-out) | .wr-blur-reveal |
--wr-blur-reveal-offset | 0.35em | .wr-blur-reveal |
--wr-blur-reveal-stagger | 70ms | .wr-blur-reveal and inline on the element, written by the component from its inputs or its state — a rule holds only until the component writes |
See also
Animation RevealA headline whose letters rise into place one after another from first paint, with no script: built for above the fold, where the server HTML already holds the pieces and the motion starts before the bundle arrives.Animation DecodeA readout locking on: every character shows random glyphs that change quickly, then settles on the real one, left to right.Guide MotionEasing and duration tokens for your transitions and animations.