16 CSS Image Gallery Designs 09 / 16

CSS Magazine Layout Gallery

A real editorial-magazine page in CSS — italic serif masthead, issue number, four ranked stories (hero spread + two column cards + side-by-side feature), drop-cap excerpts, byline rules, monospace section numbers, and a paper-stock footer rule.

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

The code

<div class="ig-09">

  <!-- Masthead -->
  <header class="ig-09__masthead">
    <div class="ig-09__brand">
      <span class="ig-09__logo">Voyageur</span>
      <span class="ig-09__issue">Issue 09 · Markets of the World</span>
    </div>
    <div class="ig-09__date">Summer 2026</div>
  </header>
  <hr class="ig-09__rule"/>

  <!-- Hero: Bangkok night market -->
  <div class="ig-09__card">
    <div class="ig-09__img ig-09__img--hero">
      <svg viewBox="0 0 500 325" xmlns="http://www.w3.org/2000/svg">
        <defs><linearGradient id="bmg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#1a0a05"/><stop offset="50%" stop-color="#2a1008"/><stop offset="100%" stop-color="#150808"/></linearGradient><filter id="bmf"><feGaussianBlur stdDeviation="4"/></filter></defs>
        <rect width="500" height="325" fill="url(#bmg)"/>
        <!-- String lights overhead -->
        <g>
          <path d="M0,40 Q125,55 250,42 Q375,55 500,40" stroke="#c8a030" stroke-width="1.5" fill="none"/>
          <path d="M0,70 Q125,82 250,68 Q375,82 500,70" stroke="#c8a030" stroke-width="1.5" fill="none"/>
          <!-- Bulbs -->
          <g fill="#ffdd60" opacity=".9">
            <circle cx="25" cy="42" r="4" filter="url(#bmf)"/><circle cx="25" cy="42" r="2.5"/>
            <circle cx="75" cy="47" r="4" filter="url(#bmf)"/><circle cx="75" cy="47" r="2.5"/>
            <circle cx="125" cy="55" r="4" filter="url(#bmf)"/><circle cx="125" cy="55" r="2.5"/>
            <circle cx="175" cy="50" r="4" filter="url(#bmf)"/><circle cx="175" cy="50" r="2.5"/>
            <circle cx="225" cy="44" r="4" filter="url(#bmf)"/><circle cx="225" cy="44" r="2.5"/>
            <circle cx="275" cy="42" r="4" filter="url(#bmf)"/><circle cx="275" cy="42" r="2.5"/>
            <circle cx="325" cy="48" r="4" filter="url(#bmf)"/><circle cx="325" cy="48" r="2.5"/>
            <circle cx="375" cy="55" r="4" filter="url(#bmf)"/><circle cx="375" cy="55" r="2.5"/>
            <circle cx="425" cy="48" r="4" filter="url(#bmf)"/><circle cx="425" cy="48" r="2.5"/>
            <circle cx="475" cy="42" r="4" filter="url(#bmf)"/><circle cx="475" cy="42" r="2.5"/>
            <circle cx="25" cy="73" r="4" filter="url(#bmf)"/><circle cx="25" cy="73" r="2.5"/>
            <circle cx="85" cy="80" r="4" filter="url(#bmf)"/><circle cx="85" cy="80" r="2.5"/>
            <circle cx="175" cy="82" r="4" filter="url(#bmf)"/><circle cx="175" cy="82" r="2.5"/>
            <circle cx="265" cy="78" r="4" filter="url(#bmf)"/><circle cx="265" cy="78" r="2.5"/>
            <circle cx="355" cy="82" r="4" filter="url(#bmf)"/><circle cx="355" cy="82" r="2.5"/>
            <circle cx="445" cy="76" r="4" filter="url(#bmf)"/><circle cx="445" cy="76" r="2.5"/>
          </g>
        </g>
        <!-- Market stalls -->
        <g>
          <!-- Stall 1 canopy -->
          <polygon points="10,90 110,90 110,105 10,105" fill="#c82020"/>
          <g fill="#e03030"><polygon points="10,105 30,90 50,105"/><polygon points="50,105 70,90 90,105"/><polygon points="90,105 110,90 130,105"/></g>
          <!-- Stall 2 -->
          <polygon points="115,92 215,92 215,107 115,107" fill="#2268cc"/>
          <g fill="#3378dd"><polygon points="115,107 135,92 155,107"/><polygon points="155,107 175,92 195,107"/></g>
          <!-- Stall 3 -->
          <polygon points="220,90 320,90 320,105 220,105" fill="#22aa44"/>
          <g fill="#33bb55"><polygon points="220,105 240,90 260,105"/><polygon points="260,105 280,90 300,105"/></g>
          <!-- Stall 4 -->
          <polygon points="325,92 425,92 425,107 325,107" fill="#cc8820"/>
          <!-- Stall 5 -->
          <polygon points="430,90 500,90 500,105 430,105" fill="#cc2266"/>
        </g>
        <!-- Food on tables: Pad Thai -->
        <g>
          <!-- Table surfaces -->
          <rect x="15" y="180" width="90" height="55" rx="3" fill="#8a5a28" opacity=".9"/>
          <rect x="120" y="183" width="88" height="52" rx="3" fill="#7a4a1a" opacity=".9"/>
          <rect x="225" y="178" width="92" height="58" rx="3" fill="#8a5a28" opacity=".9"/>
          <rect x="330" y="180" width="85" height="55" rx="3" fill="#7a4a1a" opacity=".9"/>
          <rect x="428" y="182" width="68" height="52" rx="3" fill="#8a5a28" opacity=".9"/>
          <!-- Food items -->
          <!-- Wok with flames -->
          <ellipse cx="60" cy="190" rx="28" ry="12" fill="#1a1a0a"/>
          <ellipse cx="60" cy="188" rx="22" ry="9" fill="#ff6600" opacity=".8"/>
          <ellipse cx="60" cy="186" rx="16" ry="6" fill="#ff9900" opacity=".7"/>
          <g fill="#ff4400" opacity=".5" filter="url(#bmf)"><circle cx="52" cy="180" r="5"/><circle cx="60" cy="177" r="6"/><circle cx="68" cy="180" r="5"/></g>
          <!-- Bowls of noodles -->
          <ellipse cx="160" cy="196" rx="20" ry="10" fill="#e8c060"/>
          <ellipse cx="160" cy="194" rx="16" ry="7" fill="#f0d080"/>
          <!-- Mango sticky rice -->
          <ellipse cx="270" cy="192" rx="22" ry="10" fill="#d4a020"/>
          <ellipse cx="280" cy="190" rx="10" ry="6" fill="#ffdd00" opacity=".8"/>
          <!-- Skewers -->
          <g stroke="#c87020" stroke-width="2" fill="none">
            <line x1="365" y1="175" x2="368" y2="220"/><line x1="375" y1="175" x2="378" y2="220"/>
            <line x1="385" y1="175" x2="388" y2="220"/><line x1="395" y1="175" x2="398" y2="220"/>
          </g>
          <g fill="#ff6020" opacity=".8"><ellipse cx="366" cy="180" rx="5" ry="4"/><ellipse cx="376" cy="178" rx="5" ry="4"/><ellipse cx="386" cy="181" rx="5" ry="4"/><ellipse cx="396" cy="179" rx="5" ry="4"/></g>
          <!-- Fruit display -->
          <g fill="#ff4466" opacity=".8"><circle cx="448" cy="193" r="6"/><circle cx="460" cy="190" r="6"/><circle cx="454" cy="202" r="6"/></g>
          <g fill="#88cc22" opacity=".8"><circle cx="472" cy="194" r="5"/><circle cx="480" cy="188" r="5"/></g>
        </g>
        <!-- Crowd silhouettes -->
        <g fill="#100a05">
          <ellipse cx="50" cy="270" rx="12" ry="16"/><circle cx="50" cy="252" r="10"/>
          <ellipse cx="100" cy="268" rx="11" ry="15"/><circle cx="100" cy="251" r="9"/>
          <ellipse cx="155" cy="272" rx="12" ry="16"/><circle cx="155" cy="254" r="10"/>
          <ellipse cx="210" cy="268" rx="11" ry="14"/><circle cx="210" cy="252" r="9"/>
          <ellipse cx="265" cy="270" rx="12" ry="16"/><circle cx="265" cy="252" r="10"/>
          <ellipse cx="320" cy="267" rx="10" ry="14"/><circle cx="320" cy="251" r="9"/>
          <ellipse cx="375" cy="270" rx="12" ry="15"/><circle cx="375" cy="253" r="10"/>
          <ellipse cx="430" cy="268" rx="11" ry="14"/><circle cx="430" cy="252" r="9"/>
          <ellipse cx="478" cy="272" rx="10" ry="16"/><circle cx="478" cy="254" r="10"/>
        </g>
        <!-- Thai lanterns rising -->
        <g>
          <ellipse cx="80" cy="130" rx="12" ry="18" fill="#ff8820" opacity=".7" filter="url(#bmf)"/>
          <ellipse cx="80" cy="130" rx="8" ry="13" fill="#ffaa40" opacity=".5"/>
          <ellipse cx="200" cy="115" rx="10" ry="15" fill="#ff4444" opacity=".65" filter="url(#bmf)"/>
          <ellipse cx="350" cy="125" rx="11" ry="17" fill="#ff8820" opacity=".7" filter="url(#bmf)"/>
          <ellipse cx="460" cy="110" rx="9" ry="14" fill="#ffcc44" opacity=".65" filter="url(#bmf)"/>
        </g>
        <!-- Buddhist temple spire bg -->
        <g fill="#150808" opacity=".4">
          <polygon points="240,0 248,60 232,60"/><rect x="234" y="60" width="12" height="40"/>
          <polygon points="270,10 278,55 262,55"/><rect x="264" y="55" width="12" height="35"/>
        </g>
      </svg>
    </div>
    <div class="ig-09__body">
      <span class="ig-09__num">01</span>
      <p class="ig-09__tag">Street Food · Bangkok</p>
      <h2 class="ig-09__title">Night Market<br/>Yaowarat</h2>
      <p class="ig-09__byline">By Mei Tanaka · Photographs by R. Singh · 6 min read</p>
      <p class="ig-09__desc">A sensory labyrinth of woks and lanterns, where centuries-old recipes become street theatre under a canopy of lights — and every alley is its own kitchen.</p>
      <a class="ig-09__more">Read the story →</a>
    </div>
  </div>

  <!-- Card 2: Istanbul bazaar -->
  <div class="ig-09__card">
    <div class="ig-09__img ig-09__img--sq">
      <svg viewBox="0 0 250 250" xmlns="http://www.w3.org/2000/svg">
        <rect width="250" height="250" fill="#1a0a02"/>
        <!-- Vaulted arched ceiling -->
        <g fill="#3a2010">
          <path d="M0,0 Q62,40 62,80 L62,250 L0,250 Z"/>
          <path d="M62,0 Q124,40 124,80 L124,250 L62,250 Z"/>
          <path d="M124,0 Q186,40 186,80 L186,250 L124,250 Z"/>
          <path d="M186,0 Q248,40 248,80 L248,250 L186,250 Z"/>
        </g>
        <g fill="#2a1808">
          <path d="M0,0 Q62,35 62,75 L62,250 L0,250 Z"/>
          <path d="M62,0 Q124,35 124,75 L124,250 L62,250 Z"/>
          <path d="M124,0 Q186,35 186,75 L186,250 L124,250 Z"/>
          <path d="M186,0 Q248,35 248,75 L248,250 L186,250 Z"/>
        </g>
        <!-- Skylights -->
        <g fill="#c8a830" opacity=".7"><circle cx="31" cy="25" r="15"/><circle cx="93" cy="22" r="13"/><circle cx="155" cy="25" r="15"/><circle cx="218" cy="22" r="12"/></g>
        <g fill="#ffe88a" opacity=".5"><circle cx="31" cy="25" r="9"/><circle cx="93" cy="22" r="8"/><circle cx="155" cy="25" r="9"/><circle cx="218" cy="22" r="7"/></g>
        <!-- Hanging carpets/textiles -->
        <g>
          <rect x="5" y="70" width="30" height="55" rx="2" fill="#c82020" opacity=".9"/>
          <g stroke="#e83030" stroke-width="1.5" fill="none" opacity=".6"><line x1="5" y1="84" x2="35" y2="84"/><line x1="5" y1="99" x2="35" y2="99"/><line x1="5" y1="114" x2="35" y2="114"/></g>
          <rect x="40" y="65" width="28" height="62" rx="2" fill="#c87a20" opacity=".9"/>
          <rect x="72" y="68" width="25" height="58" rx="2" fill="#2268cc" opacity=".9"/>
          <rect x="100" y="72" width="28" height="54" rx="2" fill="#22aa44" opacity=".9"/>
          <rect x="132" y="65" width="30" height="62" rx="2" fill="#8822cc" opacity=".9"/>
          <rect x="166" y="70" width="26" height="55" rx="2" fill="#cc2266" opacity=".9"/>
          <rect x="196" y="67" width="30" height="60" rx="2" fill="#c87a20" opacity=".9"/>
        </g>
        <!-- Spice urns/ceramics on shelves -->
        <g>
          <rect x="0" y="155" width="250" height="8" fill="#5a3010"/>
          <!-- Ceramics -->
          <g fill="#2268cc"><path d="M12,140 Q18,120 24,140 Q22,155 14,155 Z"/><path d="M28,142 Q32,125 36,142 Q34,154 30,154 Z"/></g>
          <g fill="#cc2266"><path d="M42,138 Q48,116 55,138 Q53,156 44,156 Z"/></g>
          <g fill="#22aa44"><path d="M62,140 Q67,122 72,140 Q70,155 64,155 Z"/></g>
          <g fill="#c87a20"><path d="M78,136 Q85,112 92,136 Q90,157 80,157 Z"/></g>
          <!-- Lanterns hanging -->
          <g fill="#cc6820" opacity=".8">
            <ellipse cx="124" cy="142" rx="10" ry="14"/><ellipse cx="124" cy="142" rx="7" ry="10" fill="#ffaa40" opacity=".6"/>
            <ellipse cx="185" cy="138" rx="9" ry="12"/><ellipse cx="185" cy="138" rx="6" ry="8" fill="#ffaa40" opacity=".6"/>
          </g>
          <g fill="#8822cc" opacity=".8"><ellipse cx="218" cy="144" rx="8" ry="11"/></g>
        </g>
        <!-- Merchant silhouette -->
        <g fill="#0a0502" transform="translate(140,190)">
          <ellipse cx="0" cy="-5" rx="14" ry="18"/>
          <circle cx="0" cy="-25" r="12"/>
          <!-- Turban -->
          <ellipse cx="0" cy="-30" rx="14" ry="8" fill="#c82020"/>
        </g>
        <!-- Floor pattern -->
        <g fill="none" stroke="#3a2010" stroke-width=".8" opacity=".5">
          <line x1="0" y1="220" x2="250" y2="220"/><line x1="0" y1="235" x2="250" y2="235"/>
          <line x1="40" y1="200" x2="40" y2="250"/><line x1="80" y1="200" x2="80" y2="250"/>
          <line x1="120" y1="200" x2="120" y2="250"/><line x1="160" y1="200" x2="160" y2="250"/>
          <line x1="200" y1="200" x2="200" y2="250"/>
        </g>
      </svg>
    </div>
    <div class="ig-09__body">
      <span class="ig-09__num">02</span>
      <p class="ig-09__tag">Bazaar · Istanbul</p>
      <h2 class="ig-09__title">Grand Bazaar</h2>
      <p class="ig-09__byline">Y. Ozkan · 4 min</p>
      <p class="ig-09__desc">4,000 shops beneath Ottoman vaults — a living museum of craft and commerce.</p>
    </div>
  </div>

  <!-- Card 3: Mexican mercado -->
  <div class="ig-09__card">
    <div class="ig-09__img ig-09__img--sq">
      <svg viewBox="0 0 250 250" xmlns="http://www.w3.org/2000/svg">
        <rect width="250" height="250" fill="#c8a030"/>
        <rect width="250" height="250" fill="#f5e0a0" opacity=".2"/>
        <!-- Colonial arch facade -->
        <g fill="#e8c870">
          <rect x="0" y="0" width="250" height="80"/>
          <path d="M60,80 Q80,50 100,80 Z" fill="#d4a840"/>
          <path d="M130,80 Q150,50 170,80 Z" fill="#d4a840"/>
        </g>
        <!-- Arched windows -->
        <g>
          <path d="M15,20 Q30,5 45,20 L45,60 L15,60 Z" fill="#88aacc" opacity=".7"/>
          <path d="M65,18 Q80,3 95,18 L95,58 L65,58 Z" fill="#88aacc" opacity=".7"/>
          <path d="M115,20 Q130,5 145,20 L145,60 L115,60 Z" fill="#88aacc" opacity=".7"/>
          <path d="M165,18 Q180,3 195,18 L195,58 L165,58 Z" fill="#88aacc" opacity=".7"/>
          <path d="M205,20 Q220,5 235,20 L235,60 L205,60 Z" fill="#88aacc" opacity=".7"/>
        </g>
        <!-- Papel picado banners -->
        <path d="M0,85 Q62,92 125,85 Q187,92 250,85" stroke="#4a2808" stroke-width="1.2" fill="none"/>
        <g fill="#e82020" opacity=".8"><polygon points="12,88 20,82 28,88 24,96 16,96"/><polygon points="52,90 60,84 68,90 64,98 56,98"/><polygon points="95,87 103,81 111,87 107,95 99,95"/></g>
        <g fill="#2288ee" opacity=".8"><polygon points="32,90 40,84 48,90 44,98 36,98"/><polygon points="72,88 80,82 88,88 84,96 76,96"/></g>
        <g fill="#22aa44" opacity=".8"><polygon points="138,88 146,82 154,88 150,96 142,96"/></g>
        <g fill="#ee9922" opacity=".8"><polygon points="162,90 170,84 178,90 174,98 166,98"/><polygon points="200,87 208,81 216,87 212,95 204,95"/></g>
        <!-- Fruit/veg stalls -->
        <!-- Avocados -->
        <g fill="#2a6a10"><ellipse cx="30" cy="150" rx="10" ry="14"/><ellipse cx="48" cy="148" rx="10" ry="14"/><ellipse cx="38" cy="162" rx="10" ry="13"/></g>
        <g fill="#1a4a08" opacity=".7"><ellipse cx="34" cy="152" rx="5" ry="7"/><ellipse cx="52" cy="150" rx="5" ry="7"/></g>
        <!-- Chilli peppers -->
        <g fill="#cc2020"><path d="M65,138 Q72,128 76,140 Q74,148 68,148 Q64,144 65,138 Z"/><path d="M75,135 Q82,124 86,137 Q84,145 78,145 Q74,141 75,135 Z"/><path d="M85,138 Q92,128 96,140 Q94,148 88,148 Z"/></g>
        <!-- Corn / maiz -->
        <g><rect x="108" y="130" width="12" height="30" rx="4" fill="#f0c020"/><g fill="#e0a810" opacity=".7"><rect x="110" y="132" width="3" height="26"/><rect x="115" y="132" width="3" height="26"/></g><rect x="108" y="125" width="12" height="8" fill="#2a6a10" rx="2"/><rect x="123" y="128" width="12" height="30" rx="4" fill="#f0c020"/><rect x="123" y="123" width="12" height="8" fill="#2a6a10" rx="2"/></g>
        <!-- Mangoes -->
        <g fill="#ff8820"><ellipse cx="158" cy="148" rx="14" ry="10"/><ellipse cx="180" cy="145" rx="13" ry="10"/><ellipse cx="170" cy="158" rx="12" ry="9"/></g>
        <g fill="#cc5010" opacity=".5"><ellipse cx="162" cy="145" rx="6" ry="4"/><ellipse cx="184" cy="142" rx="5" ry="4"/></g>
        <!-- Pottery blue talavera -->
        <g fill="#2268cc"><ellipse cx="220" cy="148" rx="12" ry="15"/><ellipse cx="220" cy="145" rx="9" ry="10" fill="#3388ee" opacity=".6"/></g>
        <g fill="#4488ee" opacity=".7">
          <line x1="214" y1="138" x2="226" y2="138" stroke="#4488ee" stroke-width="1.5"/><line x1="213" y1="143" x2="227" y2="143" stroke="#4488ee" stroke-width="1.5"/>
        </g>
        <!-- Tables -->
        <rect x="5" y="168" width="240" height="6" rx="2" fill="#8a5020"/>
        <!-- Person browsing -->
        <g fill="#3a1a08" transform="translate(195,195)">
          <ellipse cx="0" cy="0" rx="10" ry="14"/><circle cx="0" cy="-16" r="9"/>
          <!-- Hat -->
          <ellipse cx="0" cy="-24" rx="12" ry="4" fill="#5a2a08"/><rect x="-6" y="-30" width="12" height="8" rx="2" fill="#6a3a10"/>
        </g>
        <!-- Ground tiles -->
        <g fill="none" stroke="#c8a030" stroke-width=".8" opacity=".4">
          <line x1="0" y1="215" x2="250" y2="215"/><line x1="50" y1="185" x2="50" y2="250"/><line x1="100" y1="185" x2="100" y2="250"/><line x1="150" y1="185" x2="150" y2="250"/><line x1="200" y1="185" x2="200" y2="250"/>
        </g>
      </svg>
    </div>
    <div class="ig-09__body">
      <span class="ig-09__num">03</span>
      <p class="ig-09__tag">Mercado · Oaxaca</p>
      <h2 class="ig-09__title">Mercado Benito Juárez</h2>
      <p class="ig-09__byline">L. Velázquez · 5 min</p>
      <p class="ig-09__desc">Beneath colonial arches and papel picado, the colours of Mexico spill into the street.</p>
    </div>
  </div>

  <!-- Wide strip: Moroccan tannery -->
  <div class="ig-09__card">
    <div class="ig-09__img ig-09__img--wide">
      <svg viewBox="0 0 780 285" xmlns="http://www.w3.org/2000/svg">
        <rect width="780" height="285" fill="#c8a030"/>
        <!-- Rooftop view of dye pits -->
        <g>
          <!-- Vat circles in rows -->
          <!-- Row 1 -->
          <ellipse cx="55" cy="70" rx="38" ry="28" fill="#c82020"/><ellipse cx="55" cy="68" rx="30" ry="22" fill="#e83030"/>
          <ellipse cx="150" cy="72" rx="38" ry="28" fill="#2268cc"/><ellipse cx="150" cy="70" rx="30" ry="22" fill="#4488ee"/>
          <ellipse cx="248" cy="68" rx="38" ry="28" fill="#22aa44"/><ellipse cx="248" cy="66" rx="30" ry="22" fill="#44cc66"/>
          <ellipse cx="345" cy="72" rx="38" ry="28" fill="#ffee20"/><ellipse cx="345" cy="70" rx="30" ry="22" fill="#fff060"/>
          <ellipse cx="442" cy="68" rx="38" ry="28" fill="#cc2266"/><ellipse cx="442" cy="66" rx="30" ry="22" fill="#ee4488"/>
          <ellipse cx="540" cy="72" rx="38" ry="28" fill="#8822cc"/><ellipse cx="540" cy="70" rx="30" ry="22" fill="#aa44ee"/>
          <ellipse cx="635" cy="68" rx="38" ry="28" fill="#c87a20"/><ellipse cx="635" cy="66" rx="30" ry="22" fill="#ee9940"/>
          <ellipse cx="725" cy="72" rx="38" ry="28" fill="#22aaaa"/><ellipse cx="725" cy="70" rx="30" ry="22" fill="#44cccc"/>
          <!-- Row 2 -->
          <ellipse cx="100" cy="155" rx="38" ry="28" fill="#2268cc"/><ellipse cx="100" cy="153" rx="30" ry="22" fill="#4488ee"/>
          <ellipse cx="198" cy="152" rx="38" ry="28" fill="#c82020"/><ellipse cx="198" cy="150" rx="30" ry="22" fill="#e83030"/>
          <ellipse cx="295" cy="155" rx="38" ry="28" fill="#c87a20"/><ellipse cx="295" cy="153" rx="30" ry="22" fill="#ee9940"/>
          <ellipse cx="392" cy="152" rx="38" ry="28" fill="#22aa44"/><ellipse cx="392" cy="150" rx="30" ry="22" fill="#44cc66"/>
          <ellipse cx="490" cy="155" rx="38" ry="28" fill="#ffee20"/><ellipse cx="490" cy="153" rx="30" ry="22" fill="#fff060"/>
          <ellipse cx="587" cy="152" rx="38" ry="28" fill="#8822cc"/><ellipse cx="587" cy="150" rx="30" ry="22" fill="#aa44ee"/>
          <ellipse cx="683" cy="155" rx="38" ry="28" fill="#cc2266"/><ellipse cx="683" cy="153" rx="30" ry="22" fill="#ee4488"/>
        </g>
        <!-- Workers on ledges -->
        <g fill="#3a1a08">
          <ellipse cx="90" cy="100" rx="7" ry="10"/><circle cx="90" cy="88" r="6"/>
          <ellipse cx="245" cy="96" rx="7" ry="10"/><circle cx="245" cy="84" r="6"/>
          <ellipse cx="440" cy="98" rx="7" ry="10"/><circle cx="440" cy="86" r="6"/>
          <ellipse cx="635" cy="100" rx="7" ry="10"/><circle cx="635" cy="88" r="6"/>
          <ellipse cx="195" cy="185" rx="7" ry="10"/><circle cx="195" cy="173" r="6"/>
          <ellipse cx="490" cy="188" rx="7" ry="10"/><circle cx="490" cy="176" r="6"/>
        </g>
        <!-- Stone dividers between vats -->
        <g fill="#a87838" opacity=".7"><rect x="0" y="110" width="780" height="14"/></g>
        <!-- Hides on racks above -->
        <g>
          <rect x="10" y="230" width="30" height="40" fill="#8a5028" rx="2"/>
          <rect x="48" y="225" width="25" height="45" fill="#6a3810" rx="2"/>
          <rect x="80" y="232" width="28" height="38" fill="#8a5028" rx="2" transform="rotate(5,80,232)"/>
          <rect x="620" y="228" width="30" height="42" fill="#8a5028" rx="2"/>
          <rect x="658" y="225" width="26" height="45" fill="#6a3810" rx="2"/>
          <rect x="692" y="230" width="28" height="40" fill="#8a5028" rx="2" transform="rotate(-4,692,230)"/>
          <rect x="730" y="226" width="28" height="44" fill="#8a5028" rx="2"/>
        </g>
        <!-- Bamboo poles -->
        <g stroke="#4a2808" stroke-width="3" fill="none" opacity=".6">
          <line x1="25" y1="200" x2="25" y2="285"/><line x1="63" y1="200" x2="63" y2="285"/>
          <line x1="635" y1="200" x2="635" y2="285"/><line x1="673" y1="200" x2="673" y2="285"/>
          <line x1="706" y1="200" x2="706" y2="285"/><line x1="744" y1="200" x2="744" y2="285"/>
        </g>
        <!-- Background wall - medina -->
        <g fill="#c89840" opacity=".3">
          <rect x="0" y="0" width="780" height="25"/>
          <g fill="#e8b060" opacity=".5"><rect x="0" y="0" width="30" height="25"/><rect x="35" y="0" width="30" height="25"/><rect x="70" y="0" width="30" height="25"/><rect x="105" y="0" width="30" height="25"/></g>
        </g>
      </svg>
    </div>
    <div class="ig-09__body">
      <span class="ig-09__num">04</span>
      <p class="ig-09__tag">Craft · Fes</p>
      <h2 class="ig-09__title">Chouara Tannery — The Living Palette of Fes</h2>
      <p class="ig-09__byline">By A. El Idrissi · Photographs by H. Karim · 7 min read</p>
      <p class="ig-09__desc">Morocco's oldest tannery has been dyeing leather in these stone vats since the 11th century — a spectacle unchanged by time, where artisans still mix indigo, saffron, and pomegranate by hand.</p>
      <a class="ig-09__more">Read the story →</a>
    </div>
  </div>

  <!-- Footer rule -->
  <hr class="ig-09__rule ig-09__rule--bottom"/>
  <footer class="ig-09__footer">
    <span>VOYAGEUR MAGAZINE · ESTABLISHED 1998</span>
    <span>Page 09 — 14</span>
  </footer>

</div>
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
body{background:#f5f0e8;font-family:'DM Sans',sans-serif;padding:1.2rem;min-height:100vh;color:#1a1614}
.ig-09{max-width:820px;margin:0 auto;background:#f5f0e8;padding:1.2rem;color:#1a1614}
.ig-09__masthead{display:flex;justify-content:space-between;align-items:baseline;padding:.1rem 0 .4rem;flex-wrap:wrap;gap:.5rem}
.ig-09__brand{display:flex;align-items:baseline;gap:.85rem;flex-wrap:wrap}
.ig-09__logo{font-family:'Playfair Display',serif;font-style:italic;font-weight:700;font-size:1.5rem;color:#1a1614;letter-spacing:-0.01em}
.ig-09__issue{font-size:.66rem;letter-spacing:.18em;text-transform:uppercase;color:#8a7f74;font-weight:600}
.ig-09__date{font-size:.66rem;letter-spacing:.18em;text-transform:uppercase;color:#8a7f74;font-weight:600}
.ig-09__rule{border:none;border-top:2px solid #1a1614;margin:.25rem 0 .9rem}
.ig-09__rule--bottom{border-top-width:1px;border-color:#cdc3b5;margin:.9rem 0 .3rem}
.ig-09__footer{display:flex;justify-content:space-between;font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;color:#8a7f74;font-weight:600}
.ig-09{display:grid;grid-template-columns:1fr 1fr 1fr;gap:.85rem}
.ig-09__masthead,.ig-09__rule,.ig-09__footer{grid-column:span 3}
.ig-09__card{overflow:hidden;border-radius:6px;position:relative;background:#fff;box-shadow:0 2px 12px rgba(0,0,0,.06);border:1px solid #ece4d5;display:flex;flex-direction:column;transition:box-shadow .35s ease,transform .35s ease}
.ig-09__card:hover{box-shadow:0 8px 26px rgba(0,0,0,.12);transform:translateY(-2px)}
.ig-09__card:nth-child(3){grid-column:span 2;grid-row:span 2;display:grid;grid-template-rows:auto 1fr}
.ig-09__card:nth-child(6){grid-column:span 3;display:grid;grid-template-columns:1.4fr 1fr;align-items:stretch}
.ig-09__card:nth-child(6) .ig-09__img--wide{aspect-ratio:auto;height:100%;min-height:170px}
.ig-09__img{display:block;width:100%;overflow:hidden;position:relative}
.ig-09__img svg{width:100%;height:100%;display:block;transition:transform .55s cubic-bezier(.25,.46,.45,.94)}
.ig-09__card:hover .ig-09__img svg{transform:scale(1.05)}
.ig-09__img--hero{aspect-ratio:2/1}
.ig-09__img--sq{aspect-ratio:1}
.ig-09__body{padding:.85rem 1rem 1rem;position:relative;flex:1;display:flex;flex-direction:column}
.ig-09__num{position:absolute;top:.85rem;right:1rem;font-family:'Courier New',monospace;font-size:.66rem;font-weight:700;color:#c0472a;letter-spacing:.1em}
.ig-09__tag{font-size:.6rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:#c0472a;margin-bottom:.45rem;padding-bottom:.4rem;border-bottom:1px solid #ece4d5;display:inline-block;padding-right:1rem}
.ig-09__title{font-family:'Playfair Display',serif;font-size:.95rem;font-weight:700;color:#1a1614;line-height:1.2;margin-bottom:.4rem;letter-spacing:-0.005em}
.ig-09__card:nth-child(3) .ig-09__title{font-size:1.4rem;line-height:1.1;margin-bottom:.5rem}
.ig-09__card:nth-child(6) .ig-09__title{font-size:1.4rem;line-height:1.15}
.ig-09__byline{font-size:.62rem;color:#8a7f74;letter-spacing:.04em;margin-bottom:.5rem;font-style:italic}
.ig-09__desc{font-size:.75rem;color:#3a342e;line-height:1.55;flex:1}
.ig-09__card:nth-child(3) .ig-09__desc{font-size:.82rem;line-height:1.6}
.ig-09__card:nth-child(3) .ig-09__desc::first-letter{font-family:'Playfair Display',serif;font-size:2.6em;font-weight:700;float:left;line-height:.85;padding:.1rem .35rem 0 0;color:#c0472a}
.ig-09__card:nth-child(6) .ig-09__desc{font-size:.78rem;line-height:1.6}
.ig-09__card:nth-child(6) .ig-09__desc::first-letter{font-family:'Playfair Display',serif;font-size:2.4em;font-weight:700;float:left;line-height:.85;padding:.1rem .3rem 0 0;color:#c0472a}
.ig-09__more{display:inline-block;margin-top:.7rem;font-size:.7rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#1a1614;border-bottom:1.5px solid #c0472a;padding-bottom:.15rem;align-self:flex-start;cursor:pointer;transition:color .25s ease}
.ig-09__more:hover{color:#c0472a}
@media(prefers-reduced-motion:reduce){.ig-09__img svg,.ig-09__card{transition:none}.ig-09__card:hover{transform:none}}

How this works

The page is a 3-column CSS grid. Masthead + rule span all 3 columns at the top. Card 1 (hero) uses grid-column: span 2; grid-row: span 2 to claim the left two-thirds — its body holds a large Playfair Display headline, a byline rule, a drop-cap excerpt (.ig-09__desc::first-letter with float: left; font-size: 2.6em), and a "Read the story →" link. Cards 2 + 3 stack in the right column as smaller square thumbnails. Card 4 spans all 3 columns at the bottom in a true side-by-side editorial: grid-template-columns: 1.4fr 1fr with the image left and the headline/byline/drop-cap body right.

Editorial details that sell the "magazine" feel: monospace section number anchored top-right of each body (position: absolute), uppercase tracked tag with a fine rule underline, italic byline, drop-cap on long-form excerpts using ::first-letter + float: left, and a 2px black masthead rule + 1px paper-stock footer rule. Card hover lifts the panel translateY(-2px) + scales the SVG image to 1.05, both transform/opacity for free GPU compositing.

Customize

  • Change the editorial accent color by replacing #c0472a (rust red) on .ig-09__tag, .ig-09__num, and the drop-cap ::first-letter — switch to #1c5d99 for navy editorial, #3e6b3e for forest, or #000 for monochrome.
  • Resize the hero headline by editing .ig-09__card:nth-child(3) .ig-09__title — currently 1.8rem; raise to 2.4rem for a more dramatic cover-story title.
  • Disable the drop-cap on the side-by-side feature card by removing the .ig-09__card:nth-child(6) .ig-09__desc::first-letter rule — useful when the excerpt is too short for a drop-cap.
  • Swap the hero image aspect ratio from 16/9 to 4/3 on .ig-09__img--hero for a taller cinematic feel; the body block compresses but stays readable.
  • Control body background warmth by changing background: #f5f0e8 on the body — try #f8f4f0 for lighter cream, #ede7dc for deeper parchment, or #fff for clean white.

Watch out for

  • CSS grid row heights are determined by the tallest cell in that row — if the hero image is taller than the two right-column cards combined, it will force extra row height. Use explicit row heights or align-items: start to control this.
  • The grid-row: span 2 on the hero requires exactly two rows defined in the grid; if the right cards have very different content heights, the grid may not span correctly.
  • Playfair Display italic and bold weights are separate font faces — always load both ital,wght@0,700;1,400 in the Google Fonts URL to avoid faux-bold or faux-italic rendering.

Browser support

ChromeSafariFirefoxEdge
57+ 10.1+ 52+ 57+

CSS Grid spans and aspect-ratio broadly supported; backdrop-filter on Chrome 76+, Safari 9+.

Search CodeFronts

Loading…