AnimationDirectiveCSSAdded in v15.7

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.

import { Component } from '@angular/core';
import { WrBlurReveal } from 'ngwr/animations/blur-reveal';

@Component({ imports: [WrBlurReveal] })
export class MyComponent {}

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>

Signal Forms, with nothing in between.

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>

Built on the new Angular.

From above

from="above" settles each piece down into its place instead of up.

<h2 wrBlurReveal from="above">The checks behind ngwr.</h2>

The checks behind ngwr.

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;
}

Each word waits for the one before it.

Accessibility

PartBehaviour
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

NameDescriptionTypeDefault
byWhat 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'
fromThe side a piece settles in from.WrBlurRevealFrom'below'
staggerGap 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 | nullnull
delayPause between the host entering the viewport and the first piece, in ms.number0

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.

VariableDefaultDeclared on
--wr-blur-reveal-blur0.2em.wr-blur-reveal
--wr-blur-reveal-delay0ms.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-direction1.wr-blur-reveal +1 variant override
--wr-blur-reveal-duration0.6s.wr-blur-reveal
--wr-blur-reveal-easevar(--wr-ease-out).wr-blur-reveal
--wr-blur-reveal-offset0.35em.wr-blur-reveal
--wr-blur-reveal-stagger70ms.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