JSFiddle - React, Tailwind, and code Playground

HTML

<div class="page top" data-page="top">
  <h1>Top page</h1>
  <ul>
    <li>
      <a href="#sub1" data-to="sub1">
        <img class="cat1" src="https://placekitten.com/300/300" width="64" height="64" />
        Sub page 1
      </a>
    </li>
    <li>
      <a href="#sub2" data-to="sub2">
        <img class="cat2" src="https://placekitten.com/400/400" width="64" height="64" />
        Sub page 2
      </a>
    </li>
  </ul>
</div>

<div class="page sub1" data-page="sub1" hidden>
  <h2>Sub page 1</h2>
  <p>
    <img class="cat1" src="https://placekitten.com/300/300" width="300" height="300" />
  </p>
  <p><a href="#top" data-to="top">Back</a></p>
</div>

<div class="page sub2" data-page="sub2" hidden>
  <h2>Sub page 2</h2>
  <p>
    <img class="cat2" src="https://placekitten.com/400/400" width="300" height="300" />
  </p>
  <p><a href="#top" data-to="top">Back</a></p>
</div>

CSS

::view-transition-group(*) {
  animation-duration: 2s;
}

.cat1 {
  view-transition-name: cat1;
  contain: paint;
}

.cat2 {
  view-transition-name: cat2;
  contain: paint;
}

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

.top {
  background: #fff;
}

.sub1 {
  background: #def;
}

.sub2 {
  background: #fed;
}

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