Below we have cards that can transition into larger and more details versions.
<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>