<div class="card">
  <div class="image" id="image">
    <img src="https://images.unsplash.com/photo-1729770892329-855ec57a6284?crop=entropy&cs=srgb&fm=jpg&ixid=M3wzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3MzEzMTc3MTJ8&ixlib=rb-4.0.3&q=85" alt="a sheep in a field" />
  </div>
  <button aria-controls="image" aria-expanded="true"><span>A Sheep</span></button>
</div>
<div class="card">
  <div class="image" id="image2">
    <img src="https://images.unsplash.com/photo-1729956893184-14fc8bb82048?crop=entropy&cs=srgb&fm=jpg&ixid=M3wzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3MzEzMTk2NTl8&ixlib=rb-4.0.3&q=85" alt="a mushroom" />
  </div>
  <button aria-controls="image2" aria-expanded="false">A mushroom</button>
</div>
<div class="card">
  <div class="image" id="image3">
    <img src="https://images.unsplash.com/photo-1729686093421-570a3394ab14?crop=entropy&cs=srgb&fm=jpg&ixid=M3wzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3MzEzMTk5NzN8&ixlib=rb-4.0.3&q=85" alt="pumpkins" />
  </div>
  <button aria-controls="image3" aria-expanded="false">A pumpkin</button>
</div>
@import url("https://fonts.googleapis.com/css2?family=REM:ital,wght@0,100..900;1,100..900&display=swap");

:root {
  --card-max-width: clamp(280px, 80vw, 600px);
  @supports (interpolate-size: allow-keywords) {
    interpolate-size: allow-keywords;
  }
}

.image {
  display: flex;
  align-items: stretch;
  width: 0;
  overflow: clip;
  transition: width 1s ease;
}

.card:has(button[aria-expanded="true"]) .image {
  width: auto;
}

/* I chose to do it on click, but you could do something like hover as well :
.card:is(:hover, :focus-within) .image {
   width: auto;
} */

img {
  width: 100%;
  max-width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}

.card {
  display: flex;
  background: #333;
  padding: 0;
  height: 500px;
  border-width: 8px;
  max-width: var(--card-max-width);
  border-color: #666a86;
  border-style: groove;
  &:first-of-type {
    border-radius: 1rem 0 0 1rem;
    img {
      border-radius: 1rem 0 0 1rem;
    }
  }
  &:last-of-type {
    border-radius: 0 1rem 1rem 0;
  }
}

button {
  text-align: start;
  margin: 0;
  padding-inline: 1rem;
  padding-block: 0.4rem;
  border: 0;
  border-block-end: 4px double #95b8d1;
  font-size: 2rem;
  letter-spacing: 0.04em;
  font-family: "REM", sans-serif;
  color: #fff;
  background: none;
  cursor: pointer;
  min-width: 3.375rem;
  width: 3.375rem;
  writing-mode: vertical-rl;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
  min-height: 100vh;
  margin: 0;
  background: #e3d3e4;
  font-family: "REM", sans-serif;
  font-size: 1.1rem;
  line-height: 1.6;
  color: #fff;
}
/* Just making sure the button works as a trigger */
const buttons = document.querySelectorAll("button[aria-expanded]");

buttons.forEach((button) => {
  button.addEventListener("click", () => {
    // Toggle the state of the clicked button
    const isExpanded = button.getAttribute("aria-expanded") === "true";
    button.setAttribute("aria-expanded", !isExpanded);

    // Update the state of other buttons
    buttons.forEach((otherButton) => {
      if (otherButton !== button) {
        otherButton.setAttribute("aria-expanded", "false");
      }
    });
  });
});
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.