# Reveal

> A 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.

Source: https://ngwr.dev/animations/reveal  
Kind: Animation, Component, CSS  
Added in v15.7

## Installation

Import the class, and `@use` the entry point in your global styles. Nothing warns you when the `@use` is missing.

```typescript
import { Component } from '@angular/core';
import { WrReveal } from 'ngwr/animations/reveal';

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

```scss
@use 'ngwr/animations/reveal';
```

## Basic

`<wr-reveal>` is inline, so it sits inside your heading and takes its font. Pass the text as `text`: it is split into graphemes in the template, each piece carries its index, and the stylesheet turns that into a delay. When the last piece lands the pieces are swapped for the plain text, so the headline at rest is exactly the text it would have been.

```angular-html
<h1><wr-reveal text="Components that bind straight to Signal Forms." /></h1>
```

## Words

`by="words"` rises one word at a time, 70 ms apart instead of 28.

```angular-html
<h1><wr-reveal text="One word at a time." by="words" /></h1>
```

## Masked

`masked` clips each word at a padded line box, so a letter comes up from under the line instead of fading in where it stands. Descenders and accents at rest sit inside the padding.

```angular-html
<h1><wr-reveal text="Up from under the line." masked /></h1>
```

## One sequence from several runs

A headline with markup inside it is several runs. Give each run the count of pieces before it as `start`, and they play as one sequence. An inline element that is not text, a logo chip, joins the sequence as class `wr-reveal__item` with `--wr-reveal-i` set inline. A sequence longer than 1.2 s shrinks its gap; set the same `stagger` on every run so the gap is one gap.

```angular-html
<h1>
  <span class="wr-reveal__item" style="--wr-reveal-i: 0"><wr-tag>Angular</wr-tag></span>
  <wr-reveal text="components for" start="1" />
  <em><wr-reveal text="Signal Forms" start="15" /></em>
</h1>
```

## On scroll

`trigger="view"` keeps the pieces visible and plays them the first time most of the host is in the viewport, for a heading further down the page. `load`, the default, plays from first paint. The offset, the duration and the easing are CSS variables.

```angular-html
<h2><wr-reveal text="Plays when it scrolls into view." trigger="view" /></h2>
```

```scss
h1 .wr-reveal {
  --wr-reveal-offset: 0.5em;
  --wr-reveal-duration: 0.8s;
}
```

## 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 headline is announced once. At rest the host holds the plain text. |
| Reduced motion | Under `prefers-reduced-motion: reduce` the stylesheet plays nothing and the host swaps to the plain text at once. The demos on this page follow the same setting. |
| Server and no script | The pieces are in the server HTML and the animation is CSS, so it starts at first paint and runs on through hydration. Without script the pieces simply end fully visible. |
| Wrapping | The letters of one word sit in a no-wrap wrapper and the spaces between words stay real text, so the lines break where plain text would. |

## API

| Name | Description | Type | Default |
| --- | --- | --- | --- |
| `text`required | The text of this run. Breaking spaces stay real spaces, so it wraps as plain text would. | `string` | — |
| `by` | What enters one at a time: a grapheme, or a word. In letter mode the letters of one word sit in a no-wrap wrapper, so a word never breaks across lines mid-word. | `WrStaggerBy` | `'letters'` |
| `masked` | Each word clips its pieces at a padded line box, so a letter comes up from under the line instead of fading in where it stands. Descenders and accents at rest sit inside the padding. | `boolean` | `false` |
| `start` | The index of this run's first piece. A headline made of several runs passes each one the count the runs before it used, so they play as one sequence. | `number` | `0` |
| `stagger` | Gap between the start of one piece and the next, in ms. Unset, the mode decides: 28 for letters, 70 for words. Either way the sequence up to this run's last piece spreads over 1.2 s at most; a long sequence of several runs sets the same `stagger` on each, so the gap is one gap. | `number \| null` | `null` |
| `delay` | Pause before the first piece of the sequence, in ms. | `number` | `0` |
| `trigger` | `load` plays from first paint, with no script. `view` keeps the pieces visible and arms them the first time most of the host is in the viewport; an `__item` outside the host does not follow it. | `WrRevealTrigger` | `'load'` |

## 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/reveal` declares each default on its own element.

| Variable | Default | Declared on |
| --- | --- | --- |
| `--wr-reveal-delay` | `0ms` | `.wr-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-reveal-duration` | `0.6s` | `.wr-reveal` |
| `--wr-reveal-ease` | `var(--wr-ease-out)` | `.wr-reveal` |
| `--wr-reveal-gap` | `28ms` | `.wr-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-reveal-offset` | `0.35em` | `.wr-reveal` +1 variant override |

## See also

- [Blur Reveal](https://ngwr.dev/animations/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.
- [Server-side rendering](https://ngwr.dev/guides/ssr) — Prerender and hydrate an ngwr app without mismatches.
- [Motion](https://ngwr.dev/guides/tokens/motion) — Easing and duration tokens for your transitions and animations.
- [Badge](https://ngwr.dev/reference/components/badge) — A small label for a count or a status.
