<div class="site-container">
<div class="card card--collapsible">
<h2 class="card__title">Click to toggle</h2>
<p>This example is using View Transitions API to demonstrate how easily the widths, position, and shadow attributes are transitioned dynamically and seamlessly.</p>
</div>
</div>
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
font: 1em/1.6 sans-serif;
background: #ddd;
margin: 0;
}
p {
margin-bottom: 0;
}
p + p {
margin-top: 1.5em;
}
.site-container {
padding: 2rem;
display: grid;
place-items: center;
min-height: 100vh;
}
.card {
max-width: 480px;
background: white;
padding: 1.5rem;
border-radius: 0.5rem;
cursor: pointer;
box-shadow: 0 0.25rem 0.5rem hsl(0 0 0 / 15%);
& + & {
margin-top: 1.5em;
}
}
.card--collapsible {
position: relative;
overflow: hidden;
height: 120px;
view-transition-name: card;
&::before {
content: "+";
position: absolute;
right: 1em;
top: 1em;
line-height: 1;
font-weight: bold;
width: 1em;
text-align: center;
}
&::after {
content: "";
position: absolute;
display: block;
width: 100%;
bottom: 0;
height: 2rem;
background: linear-gradient(to bottom, transparent, white);
}
}
.card__title {
font-size: 1.25em;
margin-top: 0;
}
.card--expanded {
height: auto;
box-shadow: 0 1rem 2rem hsl(0 0 0 / 35%);
&::after {
background: none;
}
&::before {
content: "–";
}
}
::view-transition-group(card) {
animation-duration: 0.75s;
}
const card = document.querySelector(".card--collapsible");
card?.addEventListener("click", () => {
if (!document.startViewTransition) {
card.classList.toggle("card--expanded");
return;
}
document.startViewTransition(() => {
card.classList.toggle("card--expanded");
});
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.