16 CSS Image Gallery Designs 16 / 16

CSS Accordion Image Gallery

Six desert landscape panels in a horizontal accordion — clicking any panel expands it to 5× width while the others compress, driven by CSS flex transitions.

CSS + JS MIT licensed
Live Demo Open in tab
Open in playground

The code

<div class="ig-16" id="ig-16">

  <!-- Panel 1: Delicate Arch, Utah -->
  <div class="ig-16__panel ig-16--open" data-idx="0">
    <svg viewBox="0 0 180 420" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <linearGradient id="utg" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stop-color="#1a0830"/>
          <stop offset="35%" stop-color="#6a1a28"/>
          <stop offset="65%" stop-color="#c04828"/>
          <stop offset="100%" stop-color="#e07840"/>
        </linearGradient>
        <filter id="utf"><feGaussianBlur stdDeviation="5"/></filter>
      </defs>
      <rect width="180" height="420" fill="url(#utg)"/>
      <!-- Stars -->
      <g fill="#fff" opacity=".7"><circle cx="20" cy="22" r="1"/><circle cx="55" cy="10" r="1.2"/><circle cx="90" cy="28" r=".9"/><circle cx="130" cy="8" r="1.1"/><circle cx="165" cy="20" r="1"/><circle cx="40" cy="50" r=".8"/><circle cx="115" cy="42" r="1"/><circle cx="155" cy="55" r=".9"/></g>
      <!-- Milky Way hint -->
      <ellipse cx="90" cy="120" rx="100" ry="60" fill="#8060c0" opacity=".08" filter="url(#utf)" transform="rotate(-30,90,120)"/>
      <!-- Distant canyon walls -->
      <g fill="#5a2a08" opacity=".7">
        <polygon points="0,250 0,200 30,175 55,210 55,250"/>
        <polygon points="125,250 125,195 150,168 175,200 180,250"/>
      </g>
      <!-- The Arch (Delicate Arch) -->
      <g fill="#d06028">
        <!-- Left leg -->
        <path d="M45,420 Q42,380 40,340 Q38,310 45,285 Q52,268 60,262 Q68,258 72,265 Q76,275 74,295 Q72,320 72,355 L72,420 Z"/>
        <!-- Right leg -->
        <path d="M110,420 L110,355 Q108,325 106,298 Q104,278 108,268 Q112,258 118,258 Q126,260 132,272 Q138,288 136,315 Q134,345 132,380 Q130,400 130,420 Z"/>
        <!-- Arch span -->
        <path d="M72,265 Q91,228 110,268 Q100,238 91,230 Q82,238 72,265 Z" fill="#d06028"/>
        <path d="M76,278 Q90,240 106,275 Q98,248 90,242 Q82,248 76,278 Z" fill="#e07840" opacity=".7"/>
      </g>
      <!-- Rocky slickrock platform -->
      <path d="M15,380 Q90,362 165,378 L165,420 L15,420 Z" fill="#8a4010"/>
      <!-- Smaller rock hoodoos -->
      <g fill="#7a3808" opacity=".7">
        <polygon points="10,380 16,345 22,380"/>
        <polygon points="155,380 162,350 168,380"/>
      </g>
      <!-- Venus / bright star near arch -->
      <circle cx="91" cy="218" r="4" fill="#fff8d0" opacity=".9"/>
      <circle cx="91" cy="218" r="7" fill="#fff8d0" opacity=".2" filter="url(#utf)"/>
      <!-- Moon slim crescent -->
      <g transform="translate(148,45)">
        <circle cx="0" cy="0" r="11" fill="#fff8d0" opacity=".9"/>
        <circle cx="5" cy="-2" r="9" fill="#6a1a28"/>
        <circle cx="4" cy="-3" r="8" fill="#fff8d0" opacity=".9"/>
      </g>
    </svg>
    <div class="ig-16__label"><h3>Delicate Arch</h3><p>Arches National Park · Utah, USA</p></div>
    <span class="ig-16__tab">Delicate Arch</span>
  </div>

  <!-- Panel 2: Namib Desert dunes (orange/red) -->
  <div class="ig-16__panel" data-idx="1">
    <svg viewBox="0 0 180 420" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <linearGradient id="nmg" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stop-color="#c87820"/>
          <stop offset="40%" stop-color="#d88828"/>
          <stop offset="70%" stop-color="#e09838"/>
          <stop offset="100%" stop-color="#b06018"/>
        </linearGradient>
      </defs>
      <rect width="180" height="420" fill="url(#nmg)"/>
      <!-- Sky gradient top -->
      <rect width="180" height="130" fill="#8ab8d8" opacity=".5"/>
      <rect width="180" height="80" fill="#a8cce0" opacity=".4"/>
      <!-- Sun intense white -->
      <circle cx="145" cy="35" r="20" fill="#fff9e0" opacity=".92"/>
      <circle cx="145" cy="35" r="14" fill="#fffce0"/>
      <!-- Dune 1: massive star dune Sossusvlei -->
      <path d="M0,220 Q45,165 90,185 Q135,165 180,210 L180,420 L0,420 Z" fill="#c87020"/>
      <path d="M0,240 Q50,195 90,212 Q130,195 180,232 L180,420 L0,420 Z" fill="#b86018"/>
      <path d="M0,270 Q60,240 90,252 Q120,240 180,262 L180,420 L0,420 Z" fill="#a85010"/>
      <path d="M0,305 Q70,280 90,290 Q110,280 180,298 L180,420 L0,420 Z" fill="#985008"/>
      <!-- Dune crest line (bright) -->
      <path d="M0,240 Q45,196 90,212 Q135,196 180,232" stroke="#e0a040" stroke-width="2.5" fill="none" opacity=".6"/>
      <!-- Shadow side of dune (dark) -->
      <path d="M90,185 Q100,220 112,265 Q118,295 115,340 L90,340 Z" fill="#5a2008" opacity=".5"/>
      <!-- Far dune silhouettes -->
      <g fill="#b06018" opacity=".6"><path d="M0,220 Q-10,180 20,170 Q40,165 60,185 Q75,172 90,185"/><path d="M90,185 Q105,172 120,182 Q140,165 160,178 Q175,168 190,190"/></g>
      <!-- Dead tree (Deadvlei) -->
      <g fill="#2a1208" transform="translate(35,280)">
        <rect x="-2" y="-80" width="4" height="80" rx="2"/>
        <g stroke="#2a1208" stroke-width="2.5" fill="none" stroke-linecap="round">
          <path d="M0,-65 Q-15,-55 -22,-42"/><path d="M0,-55 Q12,-45 18,-32"/>
          <path d="M0,-45 Q-10,-38 -14,-28"/><path d="M0,-38 Q8,-32 11,-22"/>
          <path d="M0,-70 Q-8,-62 -12,-52"/><path d="M0,-72 Q10,-65 15,-55"/>
        </g>
      </g>
      <!-- Second dead tree far -->
      <g fill="#2a1208" opacity=".6" transform="translate(145,300)">
        <rect x="-1.5" y="-55" width="3" height="55" rx="1.5"/>
        <g stroke="#2a1208" stroke-width="1.8" fill="none" stroke-linecap="round">
          <path d="M0,-45 Q-10,-38 -14,-28"/><path d="M0,-38 Q9,-32 12,-22"/>
        </g>
      </g>
      <!-- Oryx silhouette on ridge -->
      <g fill="#1a0808" transform="translate(95,202)">
        <ellipse cx="0" cy="0" rx="12" ry="7"/>
        <ellipse cx="-8" cy="-6" rx="6" ry="7.5"/>
        <ellipse cx="-10" cy="-13" rx="2.5" ry="3.5"/>
        <!-- Horns straight up -->
        <line x1="-12" y1="-16" x2="-14" y2="-32" stroke="#1a0808" stroke-width="1.5"/>
        <line x1="-8" y1="-16" x2="-6" y2="-32" stroke="#1a0808" stroke-width="1.5"/>
        <rect x="-4" y="6" width="3" height="10" rx="1.5"/>
        <rect x="2" y="6" width="3" height="10" rx="1.5"/>
        <rect x="-11" y="6" width="3" height="12" rx="1.5"/>
        <rect x="-16" y="6" width="3" height="10" rx="1.5"/>
      </g>
    </svg>
    <div class="ig-16__label"><h3>Sossusvlei Dunes</h3><p>Namib-Naukluft Park · Namibia</p></div>
    <span class="ig-16__tab">Namib Desert</span>
  </div>

  <!-- Panel 3: Atacama salt flat -->
  <div class="ig-16__panel" data-idx="2">
    <svg viewBox="0 0 180 420" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <linearGradient id="atcg" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stop-color="#1a3a6a"/>
          <stop offset="40%" stop-color="#3a6aaa"/>
          <stop offset="60%" stop-color="#5a8ac8"/>
          <stop offset="100%" stop-color="#88aad0"/>
        </linearGradient>
        <filter id="atcf"><feGaussianBlur stdDeviation="4"/></filter>
      </defs>
      <rect width="180" height="420" fill="url(#atcg)"/>
      <!-- Vast white salt flat with perfect mirror reflection -->
      <!-- Sky and reflection symmetric -->
      <!-- Real sky -->
      <rect width="180" height="210" fill="#4a88c8" opacity=".2"/>
      <!-- Wispy clouds -->
      <g fill="#fff" opacity=".4" filter="url(#atcf)">
        <ellipse cx="35" cy="55" rx="50" ry="16"/><ellipse cx="145" cy="40" rx="40" ry="13"/>
        <ellipse cx="88" cy="72" rx="35" ry="11"/>
      </g>
      <!-- Andes volcano silhouette (distant) -->
      <polygon points="0,210 0,165 32,130 65,170 65,210" fill="#2a1a2a" opacity=".6"/>
      <polygon points="65,210 65,158 95,120 125,162 125,210" fill="#1a0a1a" opacity=".7"/>
      <polygon points="115,210 115,168 142,138 165,172 180,165 180,210" fill="#2a1a2a" opacity=".6"/>
      <!-- Eternal snow on volcano tops -->
      <polygon points="32,130 40,122 48,130 44,133 36,133" fill="#e8eef8" opacity=".7"/>
      <polygon points="95,120 103,112 111,120 107,124 99,124" fill="#e8eef8" opacity=".7"/>
      <!-- Salt flat (mirror surface) -->
      <rect x="0" y="210" width="180" height="210" fill="#c8d8e8" opacity=".85"/>
      <!-- Hexagonal salt crust patterns -->
      <g fill="none" stroke="#a8b8c8" stroke-width=".8" opacity=".5">
        <polygon points="45,240 62,231 79,240 79,258 62,267 45,258"/>
        <polygon points="79,240 96,231 113,240 113,258 96,267 79,258"/>
        <polygon points="113,240 130,231 147,240 147,258 130,267 113,258"/>
        <polygon points="62,267 79,258 96,267 96,285 79,294 62,285"/>
        <polygon points="96,267 113,258 130,267 130,285 113,294 96,285"/>
        <polygon points="45,294 62,285 79,294 79,312 62,321 45,312"/>
        <polygon points="79,294 96,285 113,294 113,312 96,321 79,312"/>
        <polygon points="113,294 130,285 147,294 147,312 130,321 113,312"/>
        <polygon points="28,321 45,312 62,321 62,339 45,348 28,339"/>
        <polygon points="62,321 79,312 96,321 96,339 79,348 62,339"/>
        <polygon points="96,321 113,312 130,321 130,339 113,348 96,339"/>
        <polygon points="130,321 147,312 164,321 164,339 147,348 130,339"/>
        <polygon points="45,348 62,339 79,348 79,366 62,375 45,366"/>
        <polygon points="79,348 96,339 113,348 113,366 96,375 79,366"/>
        <polygon points="113,348 130,339 147,348 147,366 130,375 113,366"/>
        <polygon points="62,375 79,366 96,375 96,393 79,402 62,393"/>
        <polygon points="96,375 113,366 130,375 130,393 113,402 96,393"/>
      </g>
      <!-- Perfect reflection of sky in water layer -->
      <rect x="0" y="210" width="180" height="210" fill="#5a8ac8" opacity=".18"/>
      <!-- Reflection of mountains (inverted) -->
      <polygon points="0,210 0,255 32,290 65,250 65,210" fill="#2a1a2a" opacity=".25"/>
      <polygon points="65,210 65,252 95,292 125,248 125,210" fill="#1a0a1a" opacity=".3"/>
      <!-- Flamingos in distance -->
      <g fill="#e06080" opacity=".7">
        <g transform="translate(65,225)">
          <ellipse cx="0" cy="0" rx="5" ry="3.5"/><ellipse cx="-3" cy="-5" rx="2.5" ry="3"/>
          <line x1="0" y1="3" x2="0" y2="12" stroke="#e06080" stroke-width="1.2"/>
          <line x1="0" y1="8" x2="-3" y2="14" stroke="#e06080" stroke-width="1"/>
        </g>
        <g transform="translate(75,222)">
          <ellipse cx="0" cy="0" rx="4.5" ry="3"/><ellipse cx="-2.5" cy="-4.5" rx="2" ry="2.5"/>
          <line x1="0" y1="3" x2="0" y2="11" stroke="#e06080" stroke-width="1.2"/>
        </g>
        <g transform="translate(88,226)">
          <ellipse cx="0" cy="0" rx="5" ry="3.5"/><ellipse cx="-3" cy="-5" rx="2.5" ry="3"/>
          <line x1="0" y1="3" x2="0" y2="12" stroke="#e06080" stroke-width="1.2"/>
          <line x1="0" y1="8" x2="3" y2="14" stroke="#e06080" stroke-width="1"/>
        </g>
      </g>
    </svg>
    <div class="ig-16__label"><h3>Salar de Atacama</h3><p>Atacama Desert · Chile</p></div>
    <span class="ig-16__tab">Atacama</span>
  </div>

  <!-- Panel 4: Wadi Rum canyon at golden hour -->
  <div class="ig-16__panel" data-idx="3">
    <svg viewBox="0 0 180 420" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <linearGradient id="wrg" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stop-color="#c87820"/>
          <stop offset="35%" stop-color="#e09030"/>
          <stop offset="65%" stop-color="#b86818"/>
          <stop offset="100%" stop-color="#7a3808"/>
        </linearGradient>
        <filter id="wrf"><feGaussianBlur stdDeviation="4"/></filter>
      </defs>
      <rect width="180" height="420" fill="url(#wrg)"/>
      <!-- Sky strip warm at top -->
      <rect width="180" height="80" fill="#d08830" opacity=".3"/>
      <circle cx="155" cy="28" r="22" fill="#fff580" opacity=".85"/>
      <circle cx="155" cy="28" r="16" fill="#fff8a0"/>
      <!-- Sunbeam rays -->
      <g stroke="#ffe060" stroke-width="1.5" opacity=".15">
        <line x1="155" y1="28" x2="0" y2="100"/><line x1="155" y1="28" x2="0" y2="180"/>
        <line x1="155" y1="28" x2="0" y2="260"/><line x1="155" y1="28" x2="80" y2="420"/>
        <line x1="155" y1="28" x2="140" y2="420"/>
      </g>
      <!-- Wadi Rum jebels (sandstone monoliths) -->
      <!-- Right jebel (massive) -->
      <path d="M120,0 Q128,40 135,100 Q140,160 138,230 Q136,300 140,380 L180,380 L180,0 Z" fill="#9a4808"/>
      <path d="M130,0 Q138,45 145,110 Q150,170 148,240 L180,240 L180,0 Z" fill="#c05a18"/>
      <!-- Left jebel -->
      <path d="M0,0 L0,380 L38,380 Q36,300 34,230 Q32,160 38,100 Q44,50 42,0 Z" fill="#8a4008"/>
      <path d="M0,0 L22,0 Q28,50 32,105 Q36,165 34,235 L0,235 Z" fill="#b05018"/>
      <!-- Rock strata horizontal lines -->
      <g stroke="#7a3008" stroke-width="1.2" fill="none" opacity=".5">
        <path d="M120,80 Q150,82 180,80"/><path d="M120,160 Q150,162 180,160"/>
        <path d="M120,240 Q150,242 180,240"/>
        <path d="M0,90 Q30,92 42,90"/><path d="M0,175 Q30,177 42,175"/>
        <path d="M0,258 Q30,260 42,258"/>
      </g>
      <!-- Middle distance rock formations -->
      <g fill="#7a3a10" opacity=".8">
        <polygon points="50,300 65,240 80,300"/>
        <polygon points="100,298 118,245 136,298"/>
      </g>
      <!-- Sand floor of Wadi -->
      <path d="M38,400 Q90,385 142,400 L142,420 L38,420 Z" fill="#d09040"/>
      <rect x="38" y="400" width="104" height="20" fill="#c08030"/>
      <!-- Desert sand ripples -->
      <g stroke="#b07020" stroke-width=".8" fill="none" opacity=".4">
        <path d="M42,408 Q90,402 138,408"/><path d="M45,415 Q90,410 135,415"/>
      </g>
      <!-- Jeep silhouette on sand -->
      <g fill="#1a0808" transform="translate(85,396)">
        <rect x="-18" y="-8" width="36" height="12" rx="3"/>
        <rect x="-10" y="-14" width="22" height="8" rx="2"/>
        <circle cx="-12" cy="5" r="5"/><circle cx="12" cy="5" r="5"/>
        <circle cx="-12" cy="5" r="3" fill="#2a1a0a"/><circle cx="12" cy="5" r="3" fill="#2a1a0a"/>
      </g>
      <!-- Bedouin camp -->
      <g fill="#5a3010" transform="translate(60,398)">
        <polygon points="-15,0 0,-12 15,0"/><rect x="-14" y="0" width="28" height="6"/>
        <g stroke="#8a5020" stroke-width="1" fill="none"><line x1="-15" y1="0" x2="-18" y2="-6"/><line x1="15" y1="0" x2="18" y2="-6"/></g>
      </g>
      <!-- Stars (visible in daytime desert sky hint) -->
      <g fill="#fff" opacity=".2"><circle cx="45" cy="18" r=".9"/><circle cx="75" cy="8" r=".8"/><circle cx="108" cy="22" r=".9"/></g>
    </svg>
    <div class="ig-16__label"><h3>Wadi Rum Valley</h3><p>Valley of the Moon · Jordan</p></div>
    <span class="ig-16__tab">Wadi Rum</span>
  </div>

  <!-- Panel 5: White Sands New Mexico at dusk -->
  <div class="ig-16__panel" data-idx="4">
    <svg viewBox="0 0 180 420" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <linearGradient id="wsg" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stop-color="#1a0830"/>
          <stop offset="30%" stop-color="#5a1850"/>
          <stop offset="60%" stop-color="#d05870"/>
          <stop offset="80%" stop-color="#f0a080"/>
          <stop offset="100%" stop-color="#e8e0d8"/>
        </linearGradient>
        <filter id="wsf"><feGaussianBlur stdDeviation="5"/></filter>
      </defs>
      <rect width="180" height="420" fill="url(#wsg)"/>
      <!-- Stars emerging -->
      <g fill="#fff" opacity=".7"><circle cx="18" cy="18" r="1"/><circle cx="50" cy="8" r="1.1"/><circle cx="88" cy="22" r=".9"/><circle cx="130" cy="10" r="1.2"/><circle cx="162" cy="25" r="1"/><circle cx="35" cy="40" r=".8"/><circle cx="110" cy="35" r="1"/><circle cx="155" cy="48" r=".9"/></g>
      <!-- Venus bright -->
      <circle cx="142" cy="62" r="4.5" fill="#fff8c0" opacity=".95"/>
      <circle cx="142" cy="62" r="8" fill="#fff8c0" opacity=".2" filter="url(#wsf)"/>
      <!-- Distant San Andres mountains -->
      <g fill="#3a1a28" opacity=".6"><polygon points="0,230 0,195 28,168 55,195 55,230"/><polygon points="40,230 55,190 80,165 105,192 105,230"/><polygon points="90,230 105,188 128,162 152,190 152,230"/><polygon points="138,230 152,188 168,168 180,182 180,230"/></g>
      <!-- White gypsum dunes (luminous) -->
      <path d="M0,290 Q45,255 90,272 Q135,255 180,285 L180,420 L0,420 Z" fill="#f0eee8"/>
      <path d="M0,310 Q50,280 90,292 Q130,280 180,302 L180,420 L0,420 Z" fill="#f5f4f0"/>
      <path d="M0,335 Q55,312 90,320 Q125,312 180,325 L180,420 L0,420 Z" fill="#fafaf8"/>
      <path d="M0,365 Q65,348 90,355 Q115,348 180,358 L180,420 L0,420 Z" fill="#fff"/>
      <!-- Dune shadows (subtle lavender) -->
      <path d="M90,272 Q100,300 108,340 Q112,368 108,400 L90,400 Z" fill="#c8b8d8" opacity=".25"/>
      <!-- Crest highlight -->
      <path d="M0,310 Q50,281 90,292 Q130,281 180,302" stroke="#fff" stroke-width="1.5" fill="none" opacity=".6"/>
      <!-- Yucca plant silhouette -->
      <g fill="#2a1a08" transform="translate(40,322)">
        <rect x="-2" y="-28" width="4" height="28" rx="2"/>
        <!-- Yucca spiky fronds -->
        <g stroke="#2a1a08" stroke-width="1.5" fill="none" stroke-linecap="round">
          <path d="M0,-24 Q-10,-18 -16,-10"/><path d="M0,-24 Q10,-18 16,-10"/>
          <path d="M0,-18 Q-12,-12 -18,-5"/><path d="M0,-18 Q12,-12 18,-5"/>
          <path d="M0,-12 Q-8,-8 -12,-2"/><path d="M0,-12 Q8,-8 12,-2"/>
          <path d="M0,-28 Q-5,-22 -8,-16"/><path d="M0,-28 Q5,-22 8,-16"/>
        </g>
      </g>
      <!-- Second yucca far -->
      <g fill="#2a1a08" opacity=".6" transform="translate(145,340)">
        <rect x="-1.5" y="-20" width="3" height="20" rx="1.5"/>
        <g stroke="#2a1a08" stroke-width="1.2" fill="none" stroke-linecap="round">
          <path d="M0,-18 Q-7,-13 -11,-7"/><path d="M0,-18 Q7,-13 11,-7"/>
          <path d="M0,-12 Q-8,-8 -12,-3"/><path d="M0,-12 Q8,-8 12,-3"/>
        </g>
      </g>
      <!-- Person on dune crest (tiny silhouette) -->
      <g fill="#1a0a18" transform="translate(88,280)">
        <ellipse cx="0" cy="0" rx="3.5" ry="5"/>
        <circle cx="0" cy="-7" r="3.5"/>
      </g>
      <!-- Pink glow from horizon -->
      <ellipse cx="90" cy="240" rx="120" ry="35" fill="#d06870" opacity=".2" filter="url(#wsf)"/>
    </svg>
    <div class="ig-16__label"><h3>White Sands at Dusk</h3><p>White Sands NM · New Mexico, USA</p></div>
    <span class="ig-16__tab">White Sands</span>
  </div>

  <!-- Panel 6: Cappadocia hot air balloons sunrise -->
  <div class="ig-16__panel" data-idx="5">
    <svg viewBox="0 0 180 420" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <linearGradient id="cpcg" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stop-color="#ff8040"/>
          <stop offset="30%" stop-color="#ffaa60"/>
          <stop offset="55%" stop-color="#ffd080"/>
          <stop offset="75%" stop-color="#c87040"/>
          <stop offset="100%" stop-color="#8a4010"/>
        </linearGradient>
        <filter id="cpcf"><feGaussianBlur stdDeviation="4"/></filter>
      </defs>
      <rect width="180" height="420" fill="url(#cpcg)"/>
      <!-- Rising sun -->
      <circle cx="90" cy="160" r="35" fill="#fff5a0" opacity=".85"/>
      <circle cx="90" cy="160" r="28" fill="#ffee80"/>
      <!-- Sun rays -->
      <g stroke="#ffe050" stroke-width="1.5" opacity=".2">
        <line x1="90" y1="115" x2="90" y2="95"/><line x1="120" y1="128" x2="132" y2="116"/>
        <line x1="130" y1="158" x2="150" y2="158"/><line x1="120" y1="188" x2="132" y2="200"/>
        <line x1="60" y1="128" x2="48" y2="116"/><line x1="50" y1="158" x2="30" y2="158"/>
        <line x1="60" y1="188" x2="48" y2="200"/>
      </g>
      <!-- Fairy chimney hoodoos -->
      <g fill="#9a5a28">
        <g transform="translate(15,300)">
          <polygon points="-10,120 0,0 10,120"/><ellipse cx="0" cy="-2" rx="14" ry="10"/>
        </g>
        <g transform="translate(40,285)">
          <polygon points="-8,135 0,0 8,135"/><ellipse cx="0" cy="-2" rx="12" ry="8"/>
        </g>
        <g transform="translate(62,295)">
          <polygon points="-7,125 0,0 7,125"/><ellipse cx="0" cy="-2" rx="10" ry="7"/>
        </g>
        <g transform="translate(100,280)">
          <polygon points="-9,140 0,0 9,140"/><ellipse cx="0" cy="-2" rx="13" ry="9"/>
        </g>
        <g transform="translate(125,292)">
          <polygon points="-8,128 0,0 8,128"/><ellipse cx="0" cy="-2" rx="11" ry="8"/>
        </g>
        <g transform="translate(150,288)">
          <polygon points="-10,132 0,0 10,132"/><ellipse cx="0" cy="-2" rx="14" ry="10"/>
        </g>
        <g transform="translate(170,298)">
          <polygon points="-6,122 0,0 6,122"/><ellipse cx="0" cy="-2" rx="9" ry="7"/>
        </g>
      </g>
      <!-- Cave dwellings windows -->
      <g fill="#5a2808" opacity=".7">
        <rect x="8" y="335" width="8" height="10" rx="2"/><rect x="20" y="342" width="6" height="8" rx="2"/>
        <rect x="35" y="328" width="7" height="9" rx="2"/><rect x="56" y="335" width="6" height="8" rx="2"/>
        <rect x="95" y="322" width="8" height="10" rx="2"/><rect x="108" y="330" width="6" height="8" rx="2"/>
        <rect x="120" y="338" width="7" height="9" rx="2"/>
      </g>
      <!-- Hot air balloons! (multiple) -->
      <!-- Balloon 1 (large, center) -->
      <g transform="translate(85,52)">
        <ellipse cx="0" cy="0" rx="22" ry="28" fill="#e82020"/>
        <g fill="#ff8020" opacity=".8"><path d="M-22,0 Q-22,-28 0,-28 Q22,-28 22,0 Q11,-12 0,-8 Q-11,-12 -22,0 Z"/></g>
        <g fill="#ffdd20" opacity=".7"><path d="M-22,0 Q-11,-12 0,-8 Q11,-12 22,0 Q11,12 0,8 Q-11,12 -22,0 Z"/></g>
        <g fill="#2288ee" opacity=".7"><path d="M-22,0 Q-11,12 0,8 Q11,12 22,0 Q22,28 0,28 Q-22,28 -22,0 Z"/></g>
        <rect x="-10" y="26" width="20" height="6" rx="2" fill="#8a5020"/>
        <g stroke="#8a5020" stroke-width="1" fill="none"><line x1="-9" y1="26" x2="-6" y2="14"/><line x1="9" y1="26" x2="6" y2="14"/></g>
        <rect x="-8" y="32" width="16" height="7" rx="2" fill="#6a3810"/>
        <ellipse cx="0" cy="35" rx="9" ry="4" fill="#4a2208"/>
      </g>
      <!-- Balloon 2 (smaller, left, higher) -->
      <g transform="translate(32,32)">
        <ellipse cx="0" cy="0" rx="15" ry="20" fill="#22aa44"/>
        <g fill="#88dd44" opacity=".7"><path d="M-15,0 Q-15,-20 0,-20 Q15,-20 15,0 Q7,-8 0,-6 Q-7,-8 -15,0 Z"/></g>
        <g fill="#ffdd20" opacity=".6"><path d="M-15,0 Q-7,-8 0,-6 Q7,-8 15,0 Q7,8 0,6 Q-7,8 -15,0 Z"/></g>
        <g fill="#ee4422" opacity=".6"><path d="M-15,0 Q-7,8 0,6 Q7,8 15,0 Q15,20 0,20 Q-15,20 -15,0 Z"/></g>
        <rect x="-7" y="18" width="14" height="5" rx="2" fill="#8a5020"/>
        <rect x="-5" y="23" width="10" height="5" rx="2" fill="#6a3810"/>
      </g>
      <!-- Balloon 3 (right, higher) -->
      <g transform="translate(148,20)">
        <ellipse cx="0" cy="0" rx="14" ry="18" fill="#8822cc"/>
        <g fill="#cc44ff" opacity=".7"><path d="M-14,0 Q-14,-18 0,-18 Q14,-18 14,0 Q7,-7 0,-5 Q-7,-7 -14,0 Z"/></g>
        <g fill="#ffdd20" opacity=".6"><path d="M-14,0 Q-7,-7 0,-5 Q7,-7 14,0 Q7,7 0,5 Q-7,7 -14,0 Z"/></g>
        <g fill="#2288ee" opacity=".6"><path d="M-14,0 Q-7,7 0,5 Q7,7 14,0 Q14,18 0,18 Q-14,18 -14,0 Z"/></g>
        <rect x="-6" y="16" width="12" height="5" rx="2" fill="#8a5020"/>
        <rect x="-4" y="21" width="8" height="5" rx="2" fill="#6a3810"/>
      </g>
      <!-- Distant balloons (tiny) -->
      <g fill="#cc2020" opacity=".6"><ellipse cx="60" cy="15" rx="8" ry="10"/></g>
      <g fill="#2266cc" opacity=".6"><ellipse cx="162" cy="55" rx="7" ry="9"/></g>
      <g fill="#22aa44" opacity=".5"><ellipse cx="110" cy="8" rx="7" ry="8"/></g>
      <g fill="#cc8820" opacity=".5"><ellipse cx="20" cy="65" rx="6" ry="8"/></g>
    </svg>
    <div class="ig-16__label"><h3>Cappadocia Balloons</h3><p>Göreme Valley · Central Turkey</p></div>
    <span class="ig-16__tab">Cappadocia</span>
  </div>

</div>
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
body{background:#0c0a08;font-family:'DM Sans',sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1.5rem}
.ig-16{width:100%;max-width:780px;height:420px;display:flex;gap:5px}
.ig-16__panel{flex:1;position:relative;overflow:hidden;border-radius:10px;cursor:pointer;transition:flex .55s cubic-bezier(.25,.46,.45,.94);min-width:52px}
.ig-16__panel.ig-16--open{flex:5}
.ig-16__panel svg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .55s ease}
.ig-16__panel:hover:not(.ig-16--open) svg{transform:scale(1.05)}
.ig-16__panel.ig-16--open svg{transform:scale(1)}
.ig-16__label{position:absolute;bottom:0;left:0;right:0;padding:1.2rem 1.4rem .9rem;background:linear-gradient(to top,rgba(0,0,0,.85) 0%,transparent);transform:translateY(100%);transition:transform .4s .1s ease;pointer-events:none}
.ig-16__panel.ig-16--open .ig-16__label{transform:translateY(0)}
.ig-16__label h3{color:#fff;font-size:1.05rem;font-weight:600;margin-bottom:.2rem}
.ig-16__label p{color:rgba(255,255,255,.5);font-size:.73rem;font-style:italic;font-family:'Playfair Display',serif}
.ig-16__tab{position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);white-space:nowrap;color:rgba(255,255,255,.7);font-size:.6rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;writing-mode:vertical-lr;transition:opacity .3s}
.ig-16__panel.ig-16--open .ig-16__tab{opacity:0}
@media(prefers-reduced-motion:reduce){.ig-16__panel,.ig-16__panel svg,.ig-16__label{transition:none}}
(function(){
  const root=document.getElementById('ig-16');
  if(!root)return;
  const panels=root.querySelectorAll('.ig-16__panel');
  panels.forEach(p=>{
    p.addEventListener('click',()=>{
      const isOpen=p.classList.contains('ig-16--open');
      panels.forEach(x=>x.classList.remove('ig-16--open'));
      if(!isOpen)p.classList.add('ig-16--open');
    });
  });
}());

How this works

The accordion uses a CSS flexbox container where each panel has flex: 1 by default, dividing space equally. When JS adds .ig-16--open to a panel, its flex value becomes flex: 5, making it five times wider than each of the other five panels. Because flexbox recalculates proportionally, all other panels compress smoothly. A transition: flex .55s cubic-bezier(.25,.46,.45,.94) animates the resize.

The expanded panel reveals a caption via a transform: translateY(100%) → translateY(0) transition on .ig-16__label, with a 0.1s delay so it enters only after the panel has started opening. The compressed vertical tab label (writing-mode: vertical-lr) fades out on the open panel so it doesn't conflict with the horizontal caption.

Customize

  • Change the open flex ratio from 5 to 7 on .ig-16--open for a more dominant focal panel, or 3 for a more balanced multi-panel view.
  • Add an initial open state on page load by adding .ig-16--open to the first panel in HTML — no JS needed for the initial state.
  • Change the panel minimum compressed width by editing min-width: 52px on .ig-16__panel — reducing this allows more panels before they overflow.
  • Animate panel background color shifts using CSS custom properties: assign each panel a --color and transition it via background-color on open.
  • Add a click-to-close by checking if the clicked panel already has .ig-16--open and toggling it off — the code already handles this with the isOpen check.

Watch out for

  • CSS flex shorthand transitions are supported but flex-grow alone may not interpolate in all browsers — always use the flex shorthand, not flex-grow, for animated accordion panels.
  • The SVG inside each panel must use preserveAspectRatio="xMidYMid slice" to fill its expanding container without distortion as the panel resizes.
  • Setting min-width too small on compressed panels can cause text in the tab labels to overflow — use overflow: hidden and text-overflow: ellipsis on tab labels as a fallback.

Browser support

ChromeSafariFirefoxEdge
29+ 9+ 28+ 29+

CSS flexbox transitions are widely supported; flex shorthand transition interpolation requires Chrome 29+, Safari 9+, Firefox 28+.

Search CodeFronts

Loading…