# Hero sequence

> Animate a hero section in sequence: the title, then the lead, then the buttons, with a delay on each Reveal. Try it live, then copy the code for your framework.

The title, the lead and the buttons of a hero enter one after the other. Each part has its own `Reveal`, and each `delay` is larger than the previous one.

* React

  ```jsx
  import { Reveal } from "@awesome-reveal/react";
  import { slide } from "@awesome-reveal/react/keyframes";

  export function Hero({ title, lead }) {
    return (
      <header className="hero">
        <Reveal as="h1" keyframes={slide()}>{title}</Reveal>
        <Reveal as="p" keyframes={slide()} delay={200}>{lead}</Reveal>
        <Reveal className="actions" keyframes={slide()} stagger={80} delay={400}>
          <a href="/start">Get started</a>
          <a href="/docs">Read the docs</a>
        </Reveal>
      </header>
    );
  }
  ```

* Vue

  ```vue
  <script setup>
  import { Reveal } from "@awesome-reveal/vue";
  import { slide } from "@awesome-reveal/vue/keyframes";

  defineProps(["title", "lead"]);
  </script>

  <template>
    <header class="hero">
      <Reveal as="h1" :keyframes="slide()">{{ title }}</Reveal>
      <Reveal as="p" :keyframes="slide()" :delay="200">{{ lead }}</Reveal>
      <Reveal class="actions" :keyframes="slide()" :stagger="80" :delay="400">
        <a href="/start">Get started</a>
        <a href="/docs">Read the docs</a>
      </Reveal>
    </header>
  </template>
  ```

* Astro

  ```astro
  ---
  import { Reveal } from "@awesome-reveal/astro";
  import { slide } from "@awesome-reveal/astro/keyframes";

  const { title, lead } = Astro.props;
  ---

  <header class="hero">
    <Reveal as="h1" keyframes={slide()}>{title}</Reveal>
    <Reveal as="p" keyframes={slide()} delay={200}>{lead}</Reveal>
    <Reveal class="actions" keyframes={slide()} stagger={80} delay={400}>
      <a href="/start">Get started</a>
      <a href="/docs">Read the docs</a>
    </Reveal>
  </header>
  ```

* JavaScript

  ```html
  <header class="hero">
    <h1>Build pages that feel alive</h1>
    <p>Reveal animations for React, Vue, Astro and plain JavaScript.</p>
    <div class="actions">
      <a href="/start">Get started</a>
      <a href="/docs">Read the docs</a>
    </div>
  </header>
  ```

  ```js
  import { reveal } from "@awesome-reveal/core";
  import { slide } from "@awesome-reveal/core/keyframes";

  const [title, lead, actions] = document.querySelectorAll(".hero > *");

  reveal(title, {
    keyframes: slide(),
  });
  reveal(lead, {
    keyframes: slide(),
    delay: 200,
  });
  reveal(actions, {
    keyframes: slide(),
    stagger: 80,
    delay: 400,
  });
  ```

```css
/* Transforms do not apply to inline elements. */
.actions {
  display: flex;
  gap: 0.5rem;
}
```

## Why a `Reveal` for each part

One `Reveal` with `stagger` on the whole hero would animate the buttons as one element. With a `Reveal` for each part, the buttons get their own `stagger`, and each part can have its own keyframes.

## Tips

* The delays work because the parts enter the viewport together. Above the fold, they enter when the page loads. A `Reveal` that enters later starts its delay at that time.
* Keep the sequence short. The last part starts two gaps after the first one, so a long gap makes visitors wait for the buttons.
* The title is often the Largest Contentful Paint (LCP) element. Chrome skips elements at opacity 0 when it measures LCP, so a hidden title can delay LCP. If the title is your LCP element, keep it out of the sequence.

## Next steps

[Text animation](/examples/text-animation/): Reveal a headline word by word or letter by letter.

[Options](/concepts/options/): Duration, delay, stagger and the viewport options.

[Accessibility](/concepts/accessibility/): Reduced motion, screen readers and pages without JavaScript.

[Getting started](/getting-started/): Install the package for your framework.
