Create Expanding Cards with CSS and JavaScript

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

Working Lego crew

Lego figures

Batman and Superman

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 flex value, 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.

Domains and Web Hosting

Maxer domain and web hosting

Virtual server

Get server with Digital ocean