View Transitions API: Creating Smooth Page Transitions

by Julien Etienne

HTML

<!-- Top page -->
<div class="page top" data-page="top">
  <h1>View Transitions API Example</h1>
  <ul>
    <li>
      <a href="#about" data-to="about">
        <img src="https://opentools.ai/storage/tools/stockimg-ai.png?t=1693872799" width="64" height="64" />
        About Me
      </a>
      <p>Learn more about who I am and what I do.</p>
    </li>
    <li>
      <a href="#portfolio" data-to="portfolio">
        <img src="https://uploads-ssl.webflow.com/63994dae1033718bee6949ce/63ade7c4eaa7ea52e2941ef8_covr.png" width="64" height="64" />
        My Portfolio
      </a>
      <p>Browse through my projects and see what I've worked on.</p>
    </li>
  </ul>
</div>

<!-- About page -->
<div class="page about" data-page="about" hidden>
  <h2>About Me</h2>
  <p>
    <img src="https://opentools.ai/storage/tools/stockimg-ai.png?t=1693872799" width="1000" height="300" />
  </p>
  <p>Hi, my name is Alex. Find me on <a href="https://stackdiary.com/">Stack Diary</a> or <a href="https://twitter.com/stackdiary">Twitter</a>.</p>
  <p><a href="#top" data-to="top">Back</a></p>

</div>
<!-- Portfolio page -->
<div class="page portfolio" data-page="portfolio" hidden>
  <h2>My Portfolio</h2>
  <p>
    <img src="https://uploads-ssl.webflow.com/63994dae1033718bee6949ce/63ade7c4eaa7ea52e2941ef8_covr.png" width="1000" height="300" />
  </p>
  <p>Check out some of the projects I've worked on recently. I'm always looking for new opportunities to collaborate, so feel free to reach out!</p>
  <p><a href="#top" data-to="top">Back</a></p>
</div>

CSS

.page {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  box-sizing: border-box;
  overflow: auto;
  padding: 1rem;
}

.top {
  background: #fff;
}

.about {
  background: #fffff8;
}

.portfolio {
  background: #fffff8;
}

ul {
  list-style: none;
}

JavaScript

document.querySelectorAll('a[data-to]').forEach((a) => {
  a.addEventListener('click', (e) => {
    e.preventDefault();

    const to = e.currentTarget.dataset.to;

    document.startViewTransition(() => {
      document.querySelectorAll('[data-page]').forEach((page) => {
        page.hidden = to !== page.dataset.page
      })
    })
  })
})