All examples

Transitions & animations > View transitions
Books to details

Below we have cards that can transition into larger and more details versions.

Example code

							<button 
  type="button"
  data-make-list-label="Show as list" 
	data-make-grid-label="Show as grid">Show as list</button>
<div class="books">
	<div class="book">
    <div class="book__details">
			<h2>Homeseeking</h2>
			<p>by Karissa Chen</p>
			<ul>
				<li>Average rating: ✯✯✯✯✯</li>
				<li>512 pages</li> 
				<li>Published by Hodder (2025)</li>
			</ul>		</div>
		<img src="../homeseeking.avif" alt="cover of homeseeking" />
	</div>

	<div class="book">	
		<div class="book__details">
			<h2>Dilla Time</h2>
			<p>by Dan Charnas</p>
			<ul>
				<li>Average rating: ✯✯✯✯✯</li>
				<li>480 pages</li> 
				<li>Published by Farrar (2022)</li>
			</ul>
		</div>
		<img src="../dillatime.avif" alt="cover of dilla time" />
	</div>

	<div class="book">	
		<div class="book__details">
			<h2>Liars</h2>
			<p>by Sarah Manguso</p>
			<ul>
				<li>Average rating: ✯✯✯✯</li>
				<li>272 pages</li> 
				<li>Published by Hogarth (2024)</li>
			</ul>
		</div>
		<img src="../liars.avif" alt="cover of liars" />
	</div>

	<div class="book">	
		<div class="book__details">
			<h2>Flesh</h2>
			<p>by David Szalay</p>
			<ul>
			  <li>Average rating: ✯✯✯✯</li>
				<li>368 pages</li> 
				<li>Published by Jonathan Cape (2025)</li>
			</ul>
		</div>
		<img src="../flesh.avif" alt="cover of flesh" />
	</div>
</div>

<style>
.books {
  display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 1em;
	
	&.books--list {
	  display: block;
		margin-bottom: 1em;
	}
}
.book {
  display: flex;
	flex-direction: column;
	
	ul {
	  display: none;
	}

	h2, h2 + p {
		margin: 0;
		font-size: 1em;
	}

	.books--list & /* the list version */{
	  flex-direction: row;
		gap: .5em;
		margin-bottom: .5em;
		padding-bottom: .5em;
		
		&:not(:last-child) {
			border-bottom: 1px solid #ccc;
		}
	
	  ul {
		  display: block;
			margin: 1em 0;
			padding: 0;
			list-style: none;
		} 
		
		img {
		  order: -1;
			max-width: 6em;
		}
	}
}

.book__details {
  margin-bottom: 1em;
}

img {
  max-width: 100%;
}

button {
  margin: 1em 0;
}
</style>

<script>
const button = document.querySelector('button');
const books = document.querySelector('.books');

button.addEventListener('click', function(e) {

  if (document.startViewTransition) {
		document.startViewTransition(() => {
			console.log('view transition started');
			toggleView(e.originalTarget);
		});	
	} else {
		console.log('toggling without view transition');
	  toggleView();
	}
});

/* ignore this */

function toggleView(element) {
	const listLabel = element.getAttribute('data-make-list-label');
	const gridLabel = element.getAttribute('data-make-grid-label');

	books.classList.toggle('books--list');

	if (element.textContent === listLabel) {
		element.textContent = gridLabel;
	} else {
		element.textContent = listLabel;
	}
}
</script>
						

Preview