16 CSS Image Gallery Designs 02 / 16

CSS Lightbox Gallery Overlay

A six-thumbnail grid where clicking any image opens a full-size overlay driven entirely by CSS :target pseudo-class — no JavaScript.

Pure CSS MIT licensed
Live Demo Open in tab
Open in playground

The code

<div class="ig-02__grid">
  <a class="ig-02__thumb" href="#ig-02-1">
    <svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
      <defs><radialGradient id="vg1" cx="35%" cy="40%" r="65%"><stop offset="0%" stop-color="#ff6b35"/><stop offset="50%" stop-color="#c0392b"/><stop offset="100%" stop-color="#2c0a0a"/></radialGradient><filter id="vf1"><feGaussianBlur stdDeviation="4"/></filter></defs>
      <rect width="300" height="300" fill="url(#vg1)"/>
      <ellipse cx="105" cy="120" rx="80" ry="60" fill="#ff9060" opacity=".3" filter="url(#vf1)"/>
      <!-- Volcano silhouette -->
      <polygon points="0,300 80,150 120,200 150,130 180,200 220,150 300,300" fill="#1a0505"/>
      <polygon points="120,200 150,130 180,200" fill="#1a0505"/>
      <!-- Lava glow at crater -->
      <ellipse cx="150" cy="132" rx="18" ry="8" fill="#ff4400" opacity=".9" filter="url(#vf1)"/>
      <ellipse cx="150" cy="132" rx="8" ry="4" fill="#ffaa00"/>
      <!-- Lava streams -->
      <path d="M150,135 Q145,160 138,180 Q130,200 125,230" stroke="#ff5500" stroke-width="3" fill="none" opacity=".7"/>
      <path d="M150,135 Q155,158 162,175 Q170,195 172,225" stroke="#ff6600" stroke-width="2.5" fill="none" opacity=".6"/>
      <!-- Stars -->
      <g fill="#fff" opacity=".7"><circle cx="30" cy="20" r="1"/><circle cx="80" cy="10" r="1.2"/><circle cx="130" cy="25" r=".9"/><circle cx="200" cy="15" r="1.1"/><circle cx="255" cy="8" r="1"/><circle cx="280" cy="30" r=".8"/></g>
      <!-- Smoke plume -->
      <g filter="url(#vf1)" opacity=".4"><circle cx="150" cy="105" r="20" fill="#888"/><circle cx="145" cy="85" r="16" fill="#777"/><circle cx="152" cy="68" r="14" fill="#888"/><circle cx="148" cy="52" r="12" fill="#888"/></g>
    </svg>
    <span class="ig-02__badge">Eruption</span>
  </a>
  <a class="ig-02__thumb" href="#ig-02-2">
    <svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
      <defs><linearGradient id="tg2" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#001a33"/><stop offset="50%" stop-color="#003366"/><stop offset="100%" stop-color="#001a33"/></linearGradient><filter id="tf2"><feGaussianBlur stdDeviation="3"/></filter></defs>
      <rect width="300" height="300" fill="url(#tg2)"/>
      <!-- Underwater light rays -->
      <g opacity=".15" fill="#40aaff"><polygon points="100,0 130,0 200,300 170,300"/><polygon points="160,0 180,0 240,300 220,300"/><polygon points="60,0 75,0 120,300 105,300"/></g>
      <!-- Whale body -->
      <g transform="translate(150,155)">
        <ellipse cx="0" cy="0" rx="85" ry="30" fill="#1a3a5c"/>
        <ellipse cx="0" cy="0" rx="75" ry="24" fill="#234d7a"/>
        <!-- Belly -->
        <ellipse cx="10" cy="8" rx="50" ry="16" fill="#2d6a9f" opacity=".6"/>
        <!-- Tail fluke -->
        <path d="M85,0 Q105,-20 115,-15 Q120,0 105,5 Q118,8 118,20 Q108,25 90,5 Z" fill="#1a3a5c"/>
        <!-- Flippers -->
        <ellipse cx="-20" cy="20" rx="25" ry="8" fill="#1a3a5c" transform="rotate(25,-20,20)"/>
        <ellipse cx="-20" cy="-18" rx="22" ry="6" fill="#1a3a5c" transform="rotate(-20,-20,-18)"/>
        <!-- Eye -->
        <circle cx="-58" cy="-5" r="5" fill="#0d2040"/>
        <circle cx="-58" cy="-5" r="3" fill="#1a4060"/>
        <circle cx="-57" cy="-6" r="1.2" fill="#fff"/>
        <!-- Mouth line -->
        <path d="M-82,-2 Q-70,4 -55,2" stroke="#1a3a5c" stroke-width="1.5" fill="none"/>
        <!-- Barnacles -->
        <circle cx="-30" cy="-8" r="2" fill="#1a3a5c" opacity=".6"/>
        <circle cx="-45" cy="12" r="1.5" fill="#1a3a5c" opacity=".5"/>
      </g>
      <!-- Bubble trail -->
      <g fill="#80c8ff" opacity=".5"><circle cx="250" cy="120" r="4"/><circle cx="258" cy="100" r="3"/><circle cx="265" cy="82" r="5"/><circle cx="256" cy="65" r="2.5"/><circle cx="270" cy="48" r="4"/></g>
      <!-- Small fish school -->
      <g fill="#60aaee" opacity=".7">
        <ellipse cx="60" cy="80" rx="6" ry="3"/><ellipse cx="75" cy="75" rx="5" ry="2.5"/><ellipse cx="68" cy="68" rx="6" ry="3"/>
        <ellipse cx="82" cy="88" rx="5" ry="2.5"/><ellipse cx="55" cy="92" rx="6" ry="3"/>
      </g>
    </svg>
    <span class="ig-02__badge">Deep Blue</span>
  </a>
  <a class="ig-02__thumb" href="#ig-02-3">
    <svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
      <defs><linearGradient id="ag3" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#0a1520"/><stop offset="60%" stop-color="#0d1f2d"/><stop offset="100%" stop-color="#1a3a20"/></linearGradient><filter id="af3"><feGaussianBlur stdDeviation="5"/></filter><filter id="af3b"><feGaussianBlur stdDeviation="2"/></filter></defs>
      <rect width="300" height="300" fill="url(#ag3)"/>
      <!-- Aurora ribbons -->
      <g opacity=".7" filter="url(#af3)">
        <path d="M0,80 Q75,40 150,80 Q225,120 300,60" stroke="#00e8a0" stroke-width="30" fill="none"/>
        <path d="M0,110 Q80,65 160,100 Q240,135 300,85" stroke="#6040ff" stroke-width="20" fill="none"/>
        <path d="M0,65 Q60,35 120,70 Q190,105 300,52" stroke="#00c8e0" stroke-width="15" fill="none"/>
        <path d="M0,95 Q70,58 140,90 Q215,122 300,75" stroke="#40ff90" stroke-width="10" fill="none"/>
      </g>
      <g opacity=".4" filter="url(#af3b)">
        <path d="M0,80 Q75,40 150,80 Q225,120 300,60" stroke="#80ffcc" stroke-width="8" fill="none"/>
        <path d="M0,110 Q80,65 160,100 Q240,135 300,85" stroke="#a090ff" stroke-width="6" fill="none"/>
      </g>
      <!-- Stars -->
      <g fill="#fff" opacity=".8"><circle cx="20" cy="15" r="1.1"/><circle cx="55" cy="8" r=".9"/><circle cx="95" cy="20" r="1.2"/><circle cx="140" cy="5" r="1"/><circle cx="180" cy="18" r=".8"/><circle cx="225" cy="10" r="1.1"/><circle cx="265" cy="22" r="1"/><circle cx="290" cy="8" r=".9"/><circle cx="15" cy="45" r=".8"/><circle cx="75" cy="38" r="1"/><circle cx="200" cy="42" r="1.2"/></g>
      <!-- Pine forest silhouette -->
      <g fill="#0a1a0a">
        <polygon points="0,300 0,210 20,180 40,210 40,300"/><polygon points="30,300 30,215 50,182 70,215 70,300"/>
        <polygon points="60,300 60,205 82,170 104,205 104,300"/><polygon points="95,300 95,220 115,185 135,220 135,300"/>
        <polygon points="125,300 125,208 148,172 170,208 170,300"/><polygon points="160,300 160,215 180,180 200,215 200,300"/>
        <polygon points="190,300 190,210 212,175 234,210 234,300"/><polygon points="225,300 225,205 248,170 270,205 270,300"/>
        <polygon points="258,300 258,215 278,183 298,215 298,300"/><polygon points="288,300 288,220 308,185 328,220 328,300"/>
      </g>
      <!-- Snow ground -->
      <rect x="0" y="285" width="300" height="15" fill="#c8d8e8" opacity=".5"/>
      <!-- Log cabin -->
      <g fill="#1a0d05">
        <rect x="125" y="248" width="50" height="30"/>
        <polygon points="118,248 150,228 182,248"/>
        <rect x="140" y="258" width="10" height="20"/>
      </g>
      <!-- Cabin window glow -->
      <rect x="128" y="252" width="12" height="10" fill="#ff9040" opacity=".8"/>
      <ellipse cx="134" cy="257" rx="8" ry="6" fill="#ff9040" opacity=".3" filter="url(#af3b)"/>
    </svg>
    <span class="ig-02__badge">Aurora</span>
  </a>
  <a class="ig-02__thumb" href="#ig-02-4">
    <svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
      <defs><linearGradient id="dg4" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#e8d0a0"/><stop offset="40%" stop-color="#d4a840"/><stop offset="70%" stop-color="#c08020"/><stop offset="100%" stop-color="#8a5010"/></linearGradient><filter id="df4"><feGaussianBlur stdDeviation="4"/></filter></defs>
      <rect width="300" height="300" fill="url(#dg4)"/>
      <!-- Sun near horizon -->
      <circle cx="150" cy="190" r="40" fill="#fff5a0" opacity=".9"/>
      <circle cx="150" cy="190" r="32" fill="#fff0a0"/>
      <ellipse cx="150" cy="220" rx="160" ry="30" fill="#ffaa40" opacity=".4" filter="url(#df4)"/>
      <!-- Heat haze ripples -->
      <g stroke="#e8c060" stroke-width=".8" fill="none" opacity=".3">
        <path d="M0,170 Q75,160 150,170 Q225,180 300,170"/>
        <path d="M0,180 Q80,172 150,180 Q220,188 300,180"/>
        <path d="M0,190 Q70,183 150,190 Q230,197 300,190"/>
      </g>
      <!-- Dunes with shadows -->
      <path d="M0,240 Q50,200 100,220 Q150,240 200,205 Q250,175 300,210 L300,300 L0,300 Z" fill="#c89040"/>
      <path d="M0,260 Q60,235 120,250 Q180,265 240,238 Q270,228 300,240 L300,300 L0,300 Z" fill="#b07828"/>
      <path d="M0,278 Q80,262 160,272 Q230,282 300,268 L300,300 L0,300 Z" fill="#9a6018"/>
      <!-- Dune shadow sides -->
      <path d="M100,220 Q115,240 130,265 Q140,280 135,300 L100,300 Z" fill="#7a4808" opacity=".5"/>
      <path d="M200,205 Q215,225 225,255 Q230,272 225,300 L200,300 Z" fill="#7a4808" opacity=".45"/>
      <!-- Camel caravan silhouette -->
      <g fill="#3d1a05" transform="translate(30,230)">
        <!-- Camel 1 -->
        <ellipse cx="0" cy="10" rx="18" ry="10"/>
        <ellipse cx="5" cy="3" rx="10" ry="7"/> <!-- hump -->
        <rect x="-12" y="16" width="4" height="14" rx="2"/>
        <rect x="-4" y="16" width="4" height="14" rx="2"/>
        <rect x="6" y="16" width="4" height="14" rx="2"/>
        <rect x="14" y="16" width="4" height="12" rx="2"/>
        <ellipse cx="-14" cy="7" rx="7" ry="5"/> <!-- neck+head -->
        <ellipse cx="-20" cy="4" rx="5" ry="4"/> <!-- head -->
        <!-- Rider -->
        <ellipse cx="3" cy="-3" rx="5" ry="6" fill="#5a2a0a"/>
        <circle cx="3" cy="-11" r="4" fill="#5a2a0a"/>
        <!-- Camel 2 -->
        <ellipse cx="60" cy="12" rx="16" ry="9"/>
        <ellipse cx="64" cy="5" rx="9" ry="6"/>
        <rect x="48" y="18" width="3.5" height="12" rx="2"/>
        <rect x="55" y="18" width="3.5" height="12" rx="2"/>
        <rect x="64" y="18" width="3.5" height="12" rx="2"/>
        <rect x="72" y="18" width="3.5" height="11" rx="2"/>
        <ellipse cx="46" cy="9" rx="6" ry="4.5"/>
        <ellipse cx="41" cy="6" rx="4.5" ry="3.5"/>
        <ellipse cx="62" cy="-1" rx="4.5" ry="5.5" fill="#5a2a0a"/>
        <circle cx="62" cy="-8" r="3.5" fill="#5a2a0a"/>
      </g>
    </svg>
    <span class="ig-02__badge">Sahara</span>
  </a>
  <a class="ig-02__thumb" href="#ig-02-5">
    <svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
      <defs><radialGradient id="mg5" cx="50%" cy="50%" r="60%"><stop offset="0%" stop-color="#1a3a1a"/><stop offset="60%" stop-color="#0d200d"/><stop offset="100%" stop-color="#050d05"/></radialGradient><filter id="mf5"><feGaussianBlur stdDeviation="3"/></filter></defs>
      <rect width="300" height="300" fill="url(#mg5)"/>
      <!-- Fireflies -->
      <g filter="url(#mf5)">
        <circle cx="45" cy="120" r="5" fill="#e0ff40" opacity=".85"/>
        <circle cx="95" cy="85" r="4" fill="#c8ff20" opacity=".8"/>
        <circle cx="155" cy="105" r="6" fill="#e0ff40" opacity=".9"/>
        <circle cx="205" cy="75" r="4.5" fill="#d0ff30" opacity=".82"/>
        <circle cx="255" cy="115" r="5" fill="#e0ff40" opacity=".85"/>
        <circle cx="72" cy="160" r="4" fill="#c8ff20" opacity=".75"/>
        <circle cx="130" cy="145" r="5.5" fill="#e0ff40" opacity=".88"/>
        <circle cx="190" cy="135" r="4" fill="#d0ff30" opacity=".78"/>
        <circle cx="238" cy="155" r="6" fill="#e0ff40" opacity=".9"/>
        <circle cx="30" cy="200" r="4.5" fill="#c8ff20" opacity=".8"/>
        <circle cx="110" cy="190" r="5" fill="#e0ff40" opacity=".85"/>
        <circle cx="175" cy="185" r="4" fill="#d0ff30" opacity=".78"/>
        <circle cx="225" cy="205" r="5.5" fill="#e0ff40" opacity=".88"/>
        <circle cx="270" cy="190" r="4" fill="#c8ff20" opacity=".75"/>
        <circle cx="60" cy="240" r="5" fill="#e0ff40" opacity=".82"/>
        <circle cx="145" cy="230" r="4.5" fill="#d0ff30" opacity=".8"/>
        <circle cx="210" cy="245" r="5" fill="#c8ff20" opacity=".85"/>
      </g>
      <!-- Tree trunks in dark -->
      <g fill="#050d05">
        <rect x="0" y="150" width="10" height="150" rx="3"/>
        <rect x="30" y="100" width="12" height="200" rx="4"/>
        <rect x="75" y="120" width="10" height="180" rx="3"/>
        <rect x="120" y="90" width="13" height="210" rx="4"/>
        <rect x="170" y="110" width="11" height="190" rx="3"/>
        <rect x="215" y="95" width="12" height="205" rx="4"/>
        <rect x="258" y="130" width="10" height="170" rx="3"/>
        <rect x="285" y="105" width="12" height="195" rx="4"/>
      </g>
      <!-- Canopy silhouette top -->
      <path d="M0,0 Q35,50 70,30 Q105,60 140,40 Q175,65 210,38 Q245,60 300,35 L300,0 Z" fill="#050d05"/>
      <!-- Leaf fringe -->
      <path d="M0,50 Q25,30 50,45 Q80,25 110,40 Q140,22 165,38 Q195,20 225,35 Q255,18 285,32 Q300,28 300,50" fill="#0a1a0a" opacity=".9"/>
      <!-- Ground mist -->
      <rect x="0" y="260" width="300" height="40" fill="#1a2a1a" opacity=".7" filter="url(#mf5)"/>
      <!-- Moon -->
      <circle cx="230" cy="45" r="22" fill="#fff8d0" opacity=".9"/>
      <circle cx="238" cy="40" r="18" fill="#0d200d"/>
      <circle cx="232" cy="38" r="15" fill="#fff8d0" opacity=".9"/>
    </svg>
    <span class="ig-02__badge">Fireflies</span>
  </a>
  <a class="ig-02__thumb" href="#ig-02-6">
    <svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
      <defs><linearGradient id="gg6" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#002244"/><stop offset="50%" stop-color="#003366"/><stop offset="100%" stop-color="#112200"/></linearGradient><filter id="gf6"><feGaussianBlur stdDeviation="4"/></filter></defs>
      <rect width="300" height="300" fill="url(#gg6)"/>
      <!-- Glacier face -->
      <polygon points="0,80 60,50 120,70 180,45 240,65 300,50 300,220 0,220" fill="#c8ddf0"/>
      <polygon points="0,80 60,50 120,70 180,45 240,65 300,50 300,160 0,160" fill="#a8c8e8"/>
      <!-- Crevasse cracks -->
      <g stroke="#5588aa" stroke-width="1.5" fill="none" opacity=".7">
        <path d="M40,80 Q50,110 45,140 Q42,165 48,190"/>
        <path d="M90,70 Q98,105 92,140 Q88,160 95,190"/>
        <path d="M145,65 Q152,100 148,135 Q145,155 150,190"/>
        <path d="M200,60 Q208,95 203,130 Q200,152 205,185"/>
        <path d="M255,68 Q260,100 256,135 Q253,158 258,188"/>
      </g>
      <!-- Ice shading layers -->
      <polygon points="0,100 60,75 120,92 180,68 240,88 300,72 300,130 0,130" fill="#9ab8d8" opacity=".4"/>
      <!-- Meltwater lake at base -->
      <ellipse cx="150" cy="225" rx="180" ry="25" fill="#1a4a6a"/>
      <ellipse cx="150" cy="228" rx="160" ry="18" fill="#2a6080" opacity=".7"/>
      <!-- Glacier reflection in lake -->
      <polygon points="0,220 60,235 120,225 180,238 240,226 300,235 300,250 0,250" fill="#4a80a0" opacity=".3"/>
      <!-- Ice cave opening -->
      <path d="M110,145 Q150,118 190,145 Q195,165 150,168 Q105,165 110,145 Z" fill="#1a3a5c"/>
      <ellipse cx="150" cy="155" rx="30" ry="15" fill="#0a2040" opacity=".9"/>
      <ellipse cx="150" cy="158" rx="20" ry="10" fill="#1a4060" filter="url(#gf6)"/>
      <!-- Kayaker on lake -->
      <g transform="translate(80,232)">
        <ellipse cx="0" cy="0" rx="22" ry="5" fill="#e04020"/>
        <ellipse cx="0" cy="-3" rx="6" ry="6" fill="#1a1a1a"/>
        <rect x="-2" y="-3" width="4" height="16" fill="#8a6a40" rx="1"/>
      </g>
      <!-- Mountains far back -->
      <polygon points="0,80 0,50 40,20 80,55 80,80" fill="#8ab0c8" opacity=".4"/>
      <polygon points="220,50 260,18 300,48 300,50" fill="#8ab0c8" opacity=".4"/>
    </svg>
    <span class="ig-02__badge">Glacier</span>
  </a>
</div>

<!-- Overlays -->
<div class="ig-02__overlay" id="ig-02-1">
  <a class="ig-02__close" href="#ig-02-close">&times;</a>
  <div class="ig-02__full" style="position:relative">
    <svg viewBox="0 0 700 525" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:100%">
      <defs><radialGradient id="lvg1" cx="35%" cy="40%" r="65%"><stop offset="0%" stop-color="#ff6b35"/><stop offset="50%" stop-color="#c0392b"/><stop offset="100%" stop-color="#2c0a0a"/></radialGradient><filter id="lvf1"><feGaussianBlur stdDeviation="8"/></filter></defs>
      <rect width="700" height="525" fill="url(#lvg1)"/>
      <ellipse cx="245" cy="200" rx="180" ry="130" fill="#ff9060" opacity=".3" filter="url(#lvf1)"/>
      <polygon points="0,525 180,260 280,350 350,220 420,350 520,260 700,525" fill="#1a0505"/>
      <ellipse cx="350" cy="225" rx="45" ry="20" fill="#ff4400" opacity=".9" filter="url(#lvf1)"/>
      <ellipse cx="350" cy="225" rx="20" ry="10" fill="#ffaa00"/>
      <path d="M350,235 Q340,290 320,340 Q305,385 298,430" stroke="#ff5500" stroke-width="6" fill="none" opacity=".7"/>
      <path d="M350,235 Q362,285 375,325 Q388,365 390,420" stroke="#ff6600" stroke-width="5" fill="none" opacity=".6"/>
      <g fill="#fff" opacity=".7"><circle cx="70" cy="35" r="2"/><circle cx="190" cy="20" r="2.5"/><circle cx="310" cy="42" r="1.8"/><circle cx="470" cy="28" r="2.2"/><circle cx="600" cy="18" r="2"/><circle cx="660" cy="40" r="1.8"/></g>
      <g filter="url(#lvf1)" opacity=".4"><circle cx="350" cy="180" r="45" fill="#888"/><circle cx="338" cy="148" r="38" fill="#777"/><circle cx="348" cy="115" r="32" fill="#888"/></g>
    </svg>
    <div class="ig-02__caption-lg" style="position:absolute"><h3>Kilauea Eruption</h3><p>Volcanic landscapes · Big Island, Hawaii</p></div>
  </div>
</div>
<div class="ig-02__overlay" id="ig-02-2">
  <a class="ig-02__close" href="#ig-02-close">&times;</a>
  <div class="ig-02__full" style="position:relative">
    <svg viewBox="0 0 700 525" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:100%">
      <defs><linearGradient id="ltg2" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#001a33"/><stop offset="50%" stop-color="#003366"/><stop offset="100%" stop-color="#001a33"/></linearGradient></defs>
      <rect width="700" height="525" fill="url(#ltg2)"/>
      <g opacity=".12" fill="#40aaff"><polygon points="220,0 290,0 460,525 390,525"/><polygon points="360,0 410,0 550,525 500,525"/><polygon points="130,0 160,0 270,525 240,525"/></g>
      <g transform="translate(350,280)">
        <ellipse cx="0" cy="0" rx="200" ry="70" fill="#1a3a5c"/>
        <ellipse cx="0" cy="0" rx="175" ry="55" fill="#234d7a"/>
        <ellipse cx="25" cy="18" rx="118" ry="38" fill="#2d6a9f" opacity=".6"/>
        <path d="M200,0 Q245,-46 268,-35 Q280,0 245,12 Q276,20 276,46 Q252,58 210,12 Z" fill="#1a3a5c"/>
        <ellipse cx="-45" cy="46" rx="58" ry="18" fill="#1a3a5c" transform="rotate(25,-45,46)"/>
        <ellipse cx="-45" cy="-42" rx="52" ry="14" fill="#1a3a5c" transform="rotate(-20,-45,-42)"/>
        <circle cx="-135" cy="-12" r="12" fill="#0d2040"/>
        <circle cx="-135" cy="-12" r="7" fill="#1a4060"/>
        <circle cx="-132" cy="-15" r="3" fill="#fff"/>
        <path d="M-192,-5 Q-164,10 -128,5" stroke="#1a3a5c" stroke-width="3" fill="none"/>
      </g>
      <g fill="#80c8ff" opacity=".5"><circle cx="590" cy="210" r="9"/><circle cx="608" cy="175" r="7"/><circle cx="620" cy="143" r="11"/><circle cx="610" cy="112" r="6"/></g>
      <g fill="#60aaee" opacity=".7">
        <ellipse cx="140" cy="150" rx="14" ry="7"/><ellipse cx="172" cy="140" rx="12" ry="6"/><ellipse cx="158" cy="128" rx="14" ry="7"/>
        <ellipse cx="190" cy="165" rx="12" ry="6"/><ellipse cx="128" cy="175" rx="14" ry="7"/>
      </g>
    </svg>
    <div class="ig-02__caption-lg" style="position:absolute"><h3>Humpback Whale</h3><p>Marine photography · Tonga, South Pacific</p></div>
  </div>
</div>
<div class="ig-02__overlay" id="ig-02-3">
  <a class="ig-02__close" href="#ig-02-close">&times;</a>
  <div class="ig-02__full" style="position:relative">
    <svg viewBox="0 0 700 525" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:100%">
      <defs><linearGradient id="lag3" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#0a1520"/><stop offset="60%" stop-color="#0d1f2d"/><stop offset="100%" stop-color="#1a3a20"/></linearGradient><filter id="laf3"><feGaussianBlur stdDeviation="10"/></filter><filter id="laf3b"><feGaussianBlur stdDeviation="3"/></filter></defs>
      <rect width="700" height="525" fill="url(#lag3)"/>
      <g opacity=".75" filter="url(#laf3)">
        <path d="M0,140 Q175,70 350,140 Q525,210 700,105" stroke="#00e8a0" stroke-width="55" fill="none"/>
        <path d="M0,195 Q185,120 370,175 Q555,230 700,150" stroke="#6040ff" stroke-width="38" fill="none"/>
        <path d="M0,115 Q140,65 280,125 Q445,185 700,92" stroke="#00c8e0" stroke-width="28" fill="none"/>
        <path d="M0,170 Q165,108 325,158 Q500,213 700,135" stroke="#40ff90" stroke-width="18" fill="none"/>
      </g>
      <g fill="#fff" opacity=".8"><circle cx="45" cy="28" r="2.2"/><circle cx="130" cy="14" r="1.8"/><circle cx="220" cy="38" r="2.4"/><circle cx="325" cy="10" r="2"/><circle cx="420" cy="32" r="1.6"/><circle cx="525" cy="18" r="2.2"/><circle cx="615" cy="40" r="2"/><circle cx="678" cy="16" r="1.8"/></g>
      <g fill="#0a1a0a">
        <polygon points="0,525 0,370 46,315 92,370 92,525"/><polygon points="70,525 70,378 117,320 164,378 164,525"/>
        <polygon points="140,525 140,360 192,300 244,360 244,525"/><polygon points="220,525 220,375 268,318 316,375 316,525"/>
        <polygon points="295,525 295,365 348,302 400,365 400,525"/><polygon points="375,525 375,372 422,315 470,372 470,525"/>
        <polygon points="448,525 448,360 498,298 548,360 548,525"/><polygon points="525,525 525,372 574,315 622,372 622,525"/>
        <polygon points="600,525 600,365 648,308 696,365 696,525"/>
      </g>
      <rect x="0" y="500" width="700" height="25" fill="#b8c8d8" opacity=".6"/>
      <rect x="290" y="432" width="120" height="68" fill="#1a0d05"/>
      <polygon points="278,432 350,398 422,432" fill="#120b04"/>
      <rect x="325" y="452" width="26" height="48" fill="#120b04"/>
      <rect x="295" y="438" width="30" height="24" fill="#ff8020" opacity=".8"/>
      <ellipse cx="310" cy="445" rx="20" ry="15" fill="#ff8020" opacity=".3" filter="url(#laf3b)"/>
    </svg>
    <div class="ig-02__caption-lg" style="position:absolute"><h3>Aurora Borealis</h3><p>Astrophotography · Tromsø, Norway</p></div>
  </div>
</div>
<div class="ig-02__overlay" id="ig-02-4">
  <a class="ig-02__close" href="#ig-02-close">&times;</a>
  <div class="ig-02__full" style="position:relative">
    <svg viewBox="0 0 700 525" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:100%">
      <defs><linearGradient id="ldg4" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#e8d0a0"/><stop offset="40%" stop-color="#d4a840"/><stop offset="70%" stop-color="#c08020"/><stop offset="100%" stop-color="#8a5010"/></linearGradient><filter id="ldf4"><feGaussianBlur stdDeviation="8"/></filter></defs>
      <rect width="700" height="525" fill="url(#ldg4)"/>
      <circle cx="350" cy="330" r="92" fill="#fff5a0" opacity=".9"/>
      <circle cx="350" cy="330" r="74" fill="#fff0a0"/>
      <ellipse cx="350" cy="390" rx="380" ry="55" fill="#ffaa40" opacity=".4" filter="url(#ldf4)"/>
      <path d="M0,420 Q115,370 230,388 Q350,420 468,372 Q582,340 700,368 L700,525 L0,525 Z" fill="#c89040"/>
      <path d="M0,455 Q140,420 280,438 Q420,458 560,422 Q630,408 700,425 L700,525 L0,525 Z" fill="#b07828"/>
      <path d="M0,480 Q185,458 370,472 Q535,488 700,468 L700,525 L0,525 Z" fill="#9a6018"/>
      <path d="M230,388 Q268,428 305,468 Q325,495 315,525 L230,525 Z" fill="#7a4808" opacity=".5"/>
      <path d="M468,372 Q502,412 520,455 Q528,480 522,525 L468,525 Z" fill="#7a4808" opacity=".45"/>
      <g fill="#3d1a05" transform="translate(80,405)">
        <ellipse cx="0" cy="18" rx="42" ry="22"/><ellipse cx="12" cy="5" rx="23" ry="16"/>
        <rect x="-28" y="36" width="9" height="30" rx="4"/><rect x="-10" y="36" width="9" height="32" rx="4"/>
        <rect x="14" y="36" width="9" height="30" rx="4"/><rect x="32" y="36" width="9" height="26" rx="4"/>
        <ellipse cx="-32" cy="14" rx="16" ry="11"/><ellipse cx="-48" cy="8" rx="11" ry="9"/>
        <ellipse cx="145" cy="22" rx="38" ry="20"/><ellipse cx="155" cy="10" rx="20" ry="14"/>
        <rect x="120" y="38" width="8" height="26" rx="4"/><rect x="136" y="38" width="8" height="28" rx="4"/>
        <rect x="154" y="38" width="8" height="26" rx="4"/><rect x="170" y="38" width="8" height="24" rx="4"/>
        <ellipse cx="118" cy="16" rx="14" ry="10"/><ellipse cx="105" cy="12" rx="10" ry="8"/>
      </g>
    </svg>
    <div class="ig-02__caption-lg" style="position:absolute"><h3>Sahara Caravan</h3><p>Desert expedition · Erg Chebbi, Morocco</p></div>
  </div>
</div>
<div class="ig-02__overlay" id="ig-02-5">
  <a class="ig-02__close" href="#ig-02-close">&times;</a>
  <div class="ig-02__full" style="position:relative">
    <svg viewBox="0 0 700 525" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:100%">
      <defs><radialGradient id="lmg5" cx="50%" cy="50%" r="60%"><stop offset="0%" stop-color="#1a3a1a"/><stop offset="60%" stop-color="#0d200d"/><stop offset="100%" stop-color="#050d05"/></radialGradient><filter id="lmf5"><feGaussianBlur stdDeviation="6"/></filter></defs>
      <rect width="700" height="525" fill="url(#lmg5)"/>
      <g filter="url(#lmf5)">
        <circle cx="105" cy="210" r="11" fill="#e0ff40" opacity=".88"/><circle cx="222" cy="148" r="9" fill="#c8ff20" opacity=".82"/>
        <circle cx="360" cy="185" r="13" fill="#e0ff40" opacity=".92"/><circle cx="478" cy="132" r="10" fill="#d0ff30" opacity=".84"/>
        <circle cx="595" cy="202" r="11" fill="#e0ff40" opacity=".88"/><circle cx="168" cy="285" r="9" fill="#c8ff20" opacity=".78"/>
        <circle cx="305" cy="258" r="12" fill="#e0ff40" opacity=".9"/><circle cx="445" cy="238" r="9" fill="#d0ff30" opacity=".8"/>
        <circle cx="555" cy="272" r="13" fill="#e0ff40" opacity=".92"/><circle cx="70" cy="350" r="10" fill="#c8ff20" opacity=".82"/>
        <circle cx="255" cy="332" r="11" fill="#e0ff40" opacity=".88"/><circle cx="408" cy="345" r="9" fill="#d0ff30" opacity=".8"/>
        <circle cx="490" cy="362" r="12" fill="#e0ff40" opacity=".9"/><circle cx="635" cy="338" r="10" fill="#c8ff20" opacity=".78"/>
      </g>
      <g fill="#050d05">
        <rect x="0" y="262" width="22" height="263" rx="5"/><rect x="70" y="175" width="28" height="350" rx="6"/>
        <rect x="175" y="210" width="23" height="315" rx="5"/><rect x="280" y="158" width="30" height="367" rx="7"/>
        <rect x="397" y="192" width="25" height="333" rx="5"/><rect x="502" y="166" width="28" height="359" rx="6"/>
        <rect x="602" y="228" width="23" height="297" rx="5"/><rect x="665" y="184" width="28" height="341" rx="6"/>
      </g>
      <path d="M0,0 Q80,88 160,55 Q245,105 325,70 Q408,112 490,67 Q572,105 700,61 L700,0 Z" fill="#050d05"/>
      <path d="M0,88 Q58,55 116,79 Q187,44 258,70 Q325,40 385,67 Q455,35 525,61 Q592,32 665,57 Q700,50 700,88" fill="#0a1a0a" opacity=".9"/>
      <circle cx="535" cy="80" r="50" fill="#fff8d0" opacity=".9"/>
      <circle cx="556" cy="70" r="40" fill="#050d05"/>
      <circle cx="542" cy="66" r="34" fill="#fff8d0" opacity=".9"/>
      <rect x="0" y="458" width="700" height="67" fill="#1a2a1a" opacity=".7" filter="url(#lmf5)"/>
    </svg>
    <div class="ig-02__caption-lg" style="position:absolute"><h3>Firefly Forest</h3><p>Night nature · Smoky Mountains, Tennessee</p></div>
  </div>
</div>
<div class="ig-02__overlay" id="ig-02-6">
  <a class="ig-02__close" href="#ig-02-close">&times;</a>
  <div class="ig-02__full" style="position:relative">
    <svg viewBox="0 0 700 525" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:100%">
      <defs><linearGradient id="lgg6" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#002244"/><stop offset="50%" stop-color="#003366"/><stop offset="100%" stop-color="#112200"/></linearGradient><filter id="lgf6"><feGaussianBlur stdDeviation="7"/></filter></defs>
      <rect width="700" height="525" fill="url(#lgg6)"/>
      <polygon points="0,140 140,88 280,123 420,79 560,114 700,88 700,385 0,385" fill="#c8ddf0"/>
      <polygon points="0,140 140,88 280,123 420,79 560,114 700,88 700,280 0,280" fill="#a8c8e8"/>
      <g stroke="#5588aa" stroke-width="3" fill="none" opacity=".7">
        <path d="M92,140 Q116,193 105,245 Q98,290 112,332"/><path d="M210,123 Q228,183 215,245 Q206,280 220,332"/>
        <path d="M337,114 Q354,175 344,237 Q338,272 348,332"/><path d="M468,105 Q482,168 472,228 Q466,265 476,325"/>
        <path d="M595,120 Q606,178 597,237 Q592,273 600,328"/>
      </g>
      <polygon points="0,175 140,133 280,160 420,120 560,154 700,127 700,228 0,228" fill="#9ab8d8" opacity=".4"/>
      <ellipse cx="350" cy="400" rx="420" ry="44" fill="#1a4a6a"/>
      <ellipse cx="350" cy="408" rx="374" ry="32" fill="#2a6080" opacity=".7"/>
      <path d="M258,270 Q350,208 442,270 Q455,298 350,302 Q246,298 258,270 Z" fill="#1a3a5c"/>
      <ellipse cx="350" cy="285" rx="70" ry="26" fill="#0a2040" opacity=".9"/>
      <ellipse cx="350" cy="292" rx="48" ry="18" fill="#1a4060" filter="url(#lgf6)"/>
      <g transform="translate(185,408)">
        <ellipse cx="0" cy="0" rx="50" ry="11" fill="#e04020"/>
        <ellipse cx="0" cy="-6" rx="14" ry="14" fill="#1a1a1a"/>
        <rect x="-5" y="-6" width="10" height="36" fill="#8a6a40" rx="2"/>
      </g>
    </svg>
    <div class="ig-02__caption-lg" style="position:absolute"><h3>Perito Moreno</h3><p>Glacier expedition · Patagonia, Argentina</p></div>
  </div>
</div>
<div id="ig-02-close"></div>
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
body{background:#0a0a0f;font-family:'DM Sans',sans-serif;padding:2rem}
.ig-02__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.6rem}
.ig-02__thumb{border-radius:10px;overflow:hidden;cursor:pointer;display:block;text-decoration:none;position:relative;transition:transform .25s ease,box-shadow .25s ease;box-shadow:0 4px 20px rgba(0,0,0,.5)}
.ig-02__thumb:hover{transform:scale(1.04) translateY(-2px);box-shadow:0 16px 40px rgba(0,0,0,.6)}
.ig-02__thumb svg{display:block;width:100%;aspect-ratio:1}
.ig-02__badge{position:absolute;bottom:.7rem;left:.7rem;color:rgba(255,255,255,.9);font-size:.7rem;font-weight:600;background:rgba(0,0,0,.4);backdrop-filter:blur(6px);padding:.2rem .55rem;border-radius:5px;font-family:'Playfair Display',serif;font-style:italic}
.ig-02__overlay{position:fixed;inset:0;z-index:100;display:flex;align-items:center;justify-content:center;background:rgba(5,5,10,.95);opacity:0;pointer-events:none;transition:opacity .35s ease}
.ig-02__overlay:target{opacity:1;pointer-events:all}
.ig-02__overlay:target .ig-02__full{transform:scale(1);opacity:1}
.ig-02__full{width:clamp(300px,85vw,700px);aspect-ratio:4/3;border-radius:18px;transform:scale(.88);opacity:0;transition:transform .4s cubic-bezier(.34,1.56,.64,1),opacity .35s ease;box-shadow:0 40px 100px rgba(0,0,0,.7);overflow:hidden}
.ig-02__full svg{width:100%;height:100%}
.ig-02__close{position:absolute;top:1.5rem;right:1.5rem;color:#fff;font-size:1.8rem;text-decoration:none;width:46px;height:46px;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.12);border-radius:50%;backdrop-filter:blur(8px);transition:background .2s ease;line-height:1}
.ig-02__close:hover{background:rgba(255,255,255,.25)}
.ig-02__caption-lg{position:absolute;bottom:2rem;left:2rem;right:2rem;color:#fff;font-family:'Playfair Display',serif}
.ig-02__caption-lg h3{font-size:1.6rem;font-weight:700;margin-bottom:.3rem}
.ig-02__caption-lg p{font-size:.85rem;color:rgba(255,255,255,.6);font-style:italic;font-family:'DM Sans',sans-serif}
@media(prefers-reduced-motion:reduce){.ig-02__overlay,.ig-02__full,.ig-02__thumb{transition:none}}

How this works

Each thumbnail is an <a href="#ig-02-N"> pointing to a corresponding <div id="ig-02-N"> overlay. The overlay sits in the DOM with opacity: 0; pointer-events: none by default. When its id matches the URL fragment, the :target selector fires — setting opacity: 1; pointer-events: all — making the lightbox appear with a CSS transition.

The close button is an <a href="#ig-02-close"> that targets a harmless empty anchor, returning :target to null and hiding the overlay. The inner image container animates via transform: scale(.88) to scale(1) on :target using cubic-bezier(.34,1.56,.64,1) for a satisfying spring-like pop.

Customize

  • Increase the max lightbox width by editing clamp(300px,85vw,700px) on .ig-02__full — try clamp(400px,92vw,900px) for more immersive viewing.
  • Change the overlay darkness by editing rgba(5,5,10,.95) on .ig-02__overlay background — lower opacity for a frosted-glass feel.
  • Animate the close icon with transition: transform .2s; transform: rotate(90deg) on .ig-02__close:hover.
  • Add a blur behind the overlay by using backdrop-filter: blur(8px) on the overlay (requires the body content to be a sibling, not a parent).
  • Swap the spring cubic-bezier from (.34,1.56,.64,1) to (.25,.46,.45,.94) for a more restrained ease-out open.

Watch out for

  • CSS :target changes the URL hash, which adds an entry to browser history — pressing back will close the lightbox as expected, but may surprise users expecting to navigate away. Consider a JavaScript-enhanced version for SPAs.
  • Multiple :target overlays at once is impossible in pure CSS — only one element can match the fragment at a time, which is actually the desired behaviour here.
  • On iOS Safari, clicking elements that are not interactive by default (divs, spans) does not propagate :target changes; always use <a> tags as the trigger elements.

Browser support

ChromeSafariFirefoxEdge
2+ 1.3+ 1+ 2+

:target is universally supported; backdrop-filter requires Chrome 76+, Safari 9+.

Search CodeFronts

Loading…