Create Expanding Cards with CSS and JavaScript
Interactive UI patterns do not have to be complex. One of the best examples is an expanding cards layout where a single card grows while the others shrink.
In this tutorial, I will show you how to build this effect with plain HTML, CSS and JavaScript.
What will You build
You will create image cards where:
- one card is active by default
- clicking another card makes it expand
- the active card title fades in smoothly
- the other cards shrink and fade out their titles
- visual click icon appears on the inactive cards
This pattern works great for featured destinations, portfolio categories, product highlights or storytelling sections.
Live Demo
HTML
<div class="expanding-cards-container" id="expandingCardsContainer">
<div class="expanding-card card-one is-active">
<h3>Working Lego crew</h3>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free v5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M358.182 179.361c-19.493-24.768-52.679-31.945-79.872-19.098-15.127-15.687-36.182-22.487-56.595-19.629V67c0-36.944-29.736-67-66.286-67S89.143 30.056 89.143 67v161.129c-19.909-7.41-43.272-5.094-62.083 8.872-29.355 21.795-35.793 63.333-14.55 93.152l109.699 154.001C134.632 501.59 154.741 512 176 512h178.286c30.802 0 57.574-21.5 64.557-51.797l27.429-118.999A67.873 67.873 0 0 0 448 326v-84c0-46.844-46.625-79.273-89.818-62.639zM80.985 279.697l27.126 38.079c8.995 12.626 29.031 6.287 29.031-9.283V67c0-25.12 36.571-25.16 36.571 0v175c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16v-35c0-25.12 36.571-25.16 36.571 0v35c0 8.836 7.163 16 16 16H272c8.837 0 16-7.164 16-16v-21c0-25.12 36.571-25.16 36.571 0v21c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16 0-25.121 36.571-25.16 36.571 0v84c0 1.488-.169 2.977-.502 4.423l-27.43 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H176c-5.769 0-11.263-2.878-14.697-7.697l-109.712-154c-14.406-20.223 14.994-42.818 29.394-22.606zM176.143 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.733 0-14-7.163-14-16zm75.428 0v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16zM327 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16z"/></svg>
</div>
<div class="expanding-card card-two">
<h3>Lego figures</h3>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free v5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M358.182 179.361c-19.493-24.768-52.679-31.945-79.872-19.098-15.127-15.687-36.182-22.487-56.595-19.629V67c0-36.944-29.736-67-66.286-67S89.143 30.056 89.143 67v161.129c-19.909-7.41-43.272-5.094-62.083 8.872-29.355 21.795-35.793 63.333-14.55 93.152l109.699 154.001C134.632 501.59 154.741 512 176 512h178.286c30.802 0 57.574-21.5 64.557-51.797l27.429-118.999A67.873 67.873 0 0 0 448 326v-84c0-46.844-46.625-79.273-89.818-62.639zM80.985 279.697l27.126 38.079c8.995 12.626 29.031 6.287 29.031-9.283V67c0-25.12 36.571-25.16 36.571 0v175c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16v-35c0-25.12 36.571-25.16 36.571 0v35c0 8.836 7.163 16 16 16H272c8.837 0 16-7.164 16-16v-21c0-25.12 36.571-25.16 36.571 0v21c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16 0-25.121 36.571-25.16 36.571 0v84c0 1.488-.169 2.977-.502 4.423l-27.43 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H176c-5.769 0-11.263-2.878-14.697-7.697l-109.712-154c-14.406-20.223 14.994-42.818 29.394-22.606zM176.143 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.733 0-14-7.163-14-16zm75.428 0v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16zM327 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16z"/></svg>
</div>
<div class="expanding-card card-three">
<h3>Batman and Superman</h3>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free v5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M358.182 179.361c-19.493-24.768-52.679-31.945-79.872-19.098-15.127-15.687-36.182-22.487-56.595-19.629V67c0-36.944-29.736-67-66.286-67S89.143 30.056 89.143 67v161.129c-19.909-7.41-43.272-5.094-62.083 8.872-29.355 21.795-35.793 63.333-14.55 93.152l109.699 154.001C134.632 501.59 154.741 512 176 512h178.286c30.802 0 57.574-21.5 64.557-51.797l27.429-118.999A67.873 67.873 0 0 0 448 326v-84c0-46.844-46.625-79.273-89.818-62.639zM80.985 279.697l27.126 38.079c8.995 12.626 29.031 6.287 29.031-9.283V67c0-25.12 36.571-25.16 36.571 0v175c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16v-35c0-25.12 36.571-25.16 36.571 0v35c0 8.836 7.163 16 16 16H272c8.837 0 16-7.164 16-16v-21c0-25.12 36.571-25.16 36.571 0v21c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16 0-25.121 36.571-25.16 36.571 0v84c0 1.488-.169 2.977-.502 4.423l-27.43 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H176c-5.769 0-11.263-2.878-14.697-7.697l-109.712-154c-14.406-20.223 14.994-42.818 29.394-22.606zM176.143 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.733 0-14-7.163-14-16zm75.428 0v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16zM327 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16z"/></svg>
</div>
</div>
CSS
.expanding-cards-container {
display: flex;
flex-direction: column;
margin: 20px 0;
gap: 12px;
min-height: 550px;
@media (min-width: 992px) {
flex-direction: row;
}
.expanding-card {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
border-radius: 10px;
cursor: pointer;
color: #ffffff;
flex: 0.6;
margin: 0;
position: relative;
transition: flex 700ms ease-in;
box-shadow: inset 0 -90px 100px -60px rgba(0, 0, 0, 0.8);
&.card-one {
background-image: url('/assets/images/posts/2026/2026-07-16/Four-Lego-figures.avif');
}
&.card-two {
background-image: url('/assets/images/posts/2026/2026-07-16/Three-Lego-figures.avif');
}
&.card-three {
background-image: url('/assets/images/posts/2026/2026-07-16/Lego-Batman-and-Superman.avif');
}
&.is-active {
flex: 3;
h3 {
opacity: 1;
}
svg {
opacity: 0;
}
}
h3 {
font-size: 22px;
font-weight: 500;
line-height: 1.2;
position: absolute;
left: 20px;
bottom: 20px;
margin: 0;
opacity: 0;
transition: opacity 240ms ease-in 320ms;
@media (max-width: 992px) {
font-size: 18px;
}
}
svg {
width: 30px;
height: 30px;
background: #fff;
display: flex;
border-radius: 50%;
align-items: center;
justify-content: center;
position: absolute;
bottom: 2px;
border: 5px solid #fff;
right: 2px;
opacity: 1;
transition: opacity 700ms ease-in;
}
}
}
JavaScript
document.addEventListener("DOMContentLoaded", () => {
const expandingCardsContainer = document.getElementById("expandingCardsContainer");
if (!expandingCardsContainer) {
return;
}
const cards = expandingCardsContainer.querySelectorAll(".expanding-card");
if (!cards.length) {
return;
}
const setActiveCard = (targetCard) => {
cards.forEach((card) => card.classList.remove("is-active"));
targetCard.classList.add("is-active");
};
cards.forEach((card) => {
card.addEventListener("click", () => {
setActiveCard(card);
});
});
});
Why This Works Well
- The layout relies on
display: flex;, which makes width transitions simple - The active card uses a larger
flexvalue, so it naturally expands - JavaScript only toggles one class (
is-active) and lets CSS handle animation - The title animation is delayed slightly for a smoother reveal
Final Thoughts
Expanding cards are a great way to add interaction and visual hierarchy to a section without overcomplicating your code.
You can easily adapt this pattern for testimonials, product categories, travel highlights or portfolio previews.
Got a specific project in mind? Feel free to contact me. I am always happy to chat about how I can help you with your next web project.