Skip to content

Core

@awesome-reveal/core is the framework-independent part of awesome-reveal. The framework adapters use it. If your app uses React, Vue or Astro, install the package for your framework instead. See Getting started.

Use this package with plain DOM code, or to write an adapter for another framework.

Terminal window
pnpm add @awesome-reveal/core
import { reveal } from "@awesome-reveal/core";
import { slide } from "@awesome-reveal/core/keyframes";
const controller = reveal(document.querySelector<HTMLElement>(".hero")!, {
keyframes: slide({ direction: "left" }),
duration: 800,
});
// Later, for example when the element leaves the page:
controller.destroy();

The options are the same as in the adapters. See Options.

The package is ESM-only. Load it with a bundler, such as Vite, or in a <script type="module">. To use the bare @awesome-reveal/core specifiers there, add an import map.

reveal hides the element only when the script runs. Until then, the browser shows the HTML, so an element can show, disappear and then animate in. To hide it from the first paint, put the hidden state in the HTML. The reveal removes the opacity: 0 and the data-reveal attribute:

<section class="card" style="opacity: 0" data-reveal="hidden">…</section>
  • Put the hidden state only on elements that your script reveals. An element that no reveal call finds stays hidden.
  • Do not hide the content at the top of the page. It then waits for the script, which can delay the Largest Contentful Paint.
  • If JavaScript does not run, the content stays hidden. To show it, add the <noscript> style.

Under a strict Content Security Policy, the inline opacity: 0 style needs style-src-attr 'unsafe-inline', and the <noscript> style needs a nonce or a hash. To avoid both, put only data-reveal="hidden" in the HTML, and add this rule to your stylesheet:

@media (scripting: enabled) {
[data-reveal="hidden"] {
opacity: 0;
}
}
  • The rule applies only when JavaScript runs, so the page needs no <noscript> style.
  • reveal sets its own styles through element.style, which the policy does not block.
  • The scripting media feature needs Chrome 120, Firefox 113 or Safari 17. In older browsers, the element shows until the script hides it.
Import path Contents
@awesome-reveal/core reveal, observe, play, hiddenStyle and createReveal.
@awesome-reveal/core/keyframes The built-in keyframes, defineKeyframes, and their types.

Hides the element, and plays the keyframes when the element enters the viewport. While the element is hidden, it has an inline opacity: 0 and data-reveal="hidden". The reveal removes data-reveal and restores the inline opacity that the element had. It removes an opacity: 0 that comes from data-reveal="hidden" markup.

reveal returns a controller:

  • revealed: true while the element is revealed. With once: false, it goes back to false when the element leaves the viewport.
  • setOptions(options): replaces the options. A change of when applies at once. A change of threshold, rootMargin or once restarts the observer. The other options apply at the next reveal.
  • destroy(): stops the observation, cancels the animation and restores the element, so it shows. After destroy(), setOptions() does nothing.

Calls onChange(true) when the element enters the viewport. When once is false, it also calls onChange(false) when the element leaves the viewport. It uses threshold, rootMargin and once, and returns a function that stops the observation.

If the browser rejects an option, such as an invalid rootMargin, observe calls onChange(true), so the element shows. Without IntersectionObserver, it does the same at once. The error is reported once for each message, from a microtask: it reaches window.onerror and does not throw in your code. reveal then stays shown. With the default once, a corrected option does not hide it again.

Plays the keyframes on the element, or on its children with stagger. It uses keyframes, duration, delay, stagger and reducedMotion, and returns a function that cancels the animation.

Call play in the same frame that removes the hidden style. If you do not, the element shows at its resting style for one frame.

The style that hides an element until the reveal: { opacity: "0" }. A server renderer applies it to the markup, so that the element does not show before the client code runs.

@awesome-reveal/core exports the types of its API:

  • RevealOptions and RevealController for reveal.
  • RevealState for createReveal.
  • ObserveOptions for observe, and PlayOptions for play.

@awesome-reveal/core/keyframes exports RevealKeyframe, KeyframesFactory, KeyframesDefinition, SpringOptions, and the options type of each factory, such as SlideOptions.

Use reveal when your code owns the element. When your framework renders the style of the element, use createReveal. It decides when the element is revealed and plays the animation, but it does not change the DOM.

  1. Call createReveal(options) once for each element.
  2. Render the element with hiddenStyle and data-reveal="hidden". Read revealed for the first render: it is true before the first attach only when when is true.
  3. Call subscribe(listener). The listener hides or shows the element before the next frame. There is one listener, and a new call replaces it.
  4. Call attach(element) when the element mounts. The state observes the element and plays the keyframes. A new element keeps the state and does not play again. attach(null) stops the observation.
  5. Call setOptions(options) when the options change.

observe and play are the lower-level pieces of createReveal. Use them when you need only one of them.

The React adapter follows these steps: useReveal.ts builds on createReveal, and its getProps sets data-reveal.