16 CSS Image Gallery Designs 13 / 16
CSS 3D Cube Image Viewer
A CSS 3D cube with six faces each showing an iconic world bridge illustration — buttons rotate the cube to any face via JS-applied transforms.
The code
<div class="ig-13">
<div class="ig-13__viewport">
<div class="ig-13__cube" id="ig-13-cube">
<!-- Front: Golden Gate Bridge -->
<div class="ig-13__face ig-13__face--front">
<svg viewBox="0 0 260 260" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="ggg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#4488cc"/><stop offset="50%" stop-color="#88aacc"/><stop offset="100%" stop-color="#2a5a7a"/></linearGradient><filter id="ggf"><feGaussianBlur stdDeviation="4"/></filter></defs>
<rect width="260" height="260" fill="url(#ggg)"/>
<g filter="url(#ggf)" opacity=".4"><ellipse cx="130" cy="90" rx="100" ry="30" fill="#c8d8e8"/></g>
<!-- Bay -->
<path d="M0,185 Q65,172 130,180 Q195,172 260,182 L260,260 L0,260 Z" fill="#1a4a6a"/>
<!-- Bridge towers -->
<g fill="#cc3010">
<rect x="70" y="80" width="14" height="110"/><rect x="176" y="80" width="14" height="110"/>
<!-- Tower details -->
<rect x="66" y="80" width="22" height="10"/><rect x="172" y="80" width="22" height="10"/>
<rect x="66" y="100" width="22" height="8"/><rect x="172" y="100" width="22" height="8"/>
<rect x="66" y="120" width="22" height="8"/><rect x="172" y="120" width="22" height="8"/>
<!-- Tops -->
<rect x="74" y="72" width="6" height="12"/><rect x="180" y="72" width="6" height="12"/>
</g>
<!-- Main cables -->
<g stroke="#cc3010" stroke-width="4" fill="none">
<path d="M0,145 Q77,105 130,130 Q183,105 260,130"/>
<path d="M0,150 Q77,110 130,135 Q183,110 260,135"/>
</g>
<!-- Hanger cables -->
<g stroke="#cc3010" stroke-width="1" fill="none" opacity=".7">
<line x1="20" y1="148" x2="20" y2="178"/><line x1="40" y1="138" x2="40" y2="178"/>
<line x1="60" y1="132" x2="60" y2="178"/><line x1="100" y1="125" x2="100" y2="178"/>
<line x1="120" y1="125" x2="120" y2="178"/><line x1="140" y1="125" x2="140" y2="178"/>
<line x1="160" y1="126" x2="160" y2="178"/><line x1="200" y1="130" x2="200" y2="178"/>
<line x1="220" y1="136" x2="220" y2="178"/><line x1="240" y1="142" x2="240" y2="178"/>
</g>
<!-- Deck -->
<rect x="0" y="178" width="260" height="8" fill="#aa2808"/>
<!-- Hills bg -->
<g fill="#1a3a1a" opacity=".5"><polygon points="0,185 0,160 45,140 90,160 90,185"/><polygon points="170,185 170,158 215,138 260,158 260,185"/></g>
<!-- Fog wisps -->
<g opacity=".3" fill="#c8d8e8" filter="url(#ggf)"><ellipse cx="40" cy="160" rx="50" ry="18"/><ellipse cx="215" cy="155" rx="45" ry="16"/></g>
</svg>
</div>
<!-- Right: Sydney Harbour Bridge -->
<div class="ig-13__face ig-13__face--right">
<svg viewBox="0 0 260 260" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="shg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#1a3a5c"/><stop offset="50%" stop-color="#2a5a80"/><stop offset="100%" stop-color="#1a3050"/></linearGradient></defs>
<rect width="260" height="260" fill="url(#shg)"/>
<!-- Harbour water -->
<path d="M0,190 Q65,178 130,185 Q195,178 260,188 L260,260 L0,260 Z" fill="#1a3a5a"/>
<!-- Sydney Opera House in bg -->
<g fill="#d8d0c8" opacity=".7">
<path d="M10,190 Q30,160 50,185 Z"/><path d="M22,190 Q45,155 68,185 Z"/>
<path d="M55,190 Q72,165 90,185 Z"/>
</g>
<!-- Bridge arch -->
<path d="M30,195 Q130,40 230,195" stroke="#555566" stroke-width="22" fill="none"/>
<path d="M30,195 Q130,45 230,195" stroke="#888898" stroke-width="8" fill="none"/>
<!-- Pylons -->
<g fill="#3a3a4a"><rect x="22" y="160" width="18" height="40"/><rect x="220" y="160" width="18" height="40"/><rect x="18" y="157" width="26" height="10" rx="2"/><rect x="216" y="157" width="26" height="10" rx="2"/></g>
<!-- Hanger rods -->
<g stroke="#555566" stroke-width="1.5" fill="none">
<line x1="50" y1="152" x2="50" y2="190"/><line x1="70" y1="120" x2="70" y2="190"/>
<line x1="90" y1="100" x2="90" y2="190"/><line x1="110" y1="88" x2="110" y2="190"/>
<line x1="130" y1="82" x2="130" y2="190"/><line x1="150" y1="88" x2="150" y2="190"/>
<line x1="170" y1="100" x2="170" y2="190"/><line x1="190" y1="120" x2="190" y2="190"/>
<line x1="210" y1="152" x2="210" y2="190"/>
</g>
<!-- Bridge deck -->
<rect x="25" y="185" width="210" height="10" fill="#4a4a5a"/>
<!-- City skyline -->
<g fill="#1a2a3a"><rect x="120" y="155" width="25" height="35"/><rect x="148" y="148" width="20" height="42"/><rect x="170" y="158" width="18" height="32"/><rect x="190" y="152" width="22" height="38"/><rect x="215" y="160" width="15" height="30"/></g>
<!-- Stars -->
<g fill="#fff" opacity=".6"><circle cx="25" cy="20" r="1"/><circle cx="70" cy="8" r="1.1"/><circle cx="120" cy="15" r=".9"/><circle cx="185" cy="8" r="1"/><circle cx="235" cy="20" r=".9"/></g>
<!-- Fireworks glow -->
<circle cx="130" cy="55" r="30" fill="#ff4020" opacity=".08"/>
</svg>
</div>
<!-- Back: Tower Bridge -->
<div class="ig-13__face ig-13__face--back">
<svg viewBox="0 0 260 260" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="tbg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#c8d8e8"/><stop offset="40%" stop-color="#a0b8cc"/><stop offset="100%" stop-color="#3a5a6a"/></linearGradient><filter id="tbf"><feGaussianBlur stdDeviation="4"/></filter></defs>
<rect width="260" height="260" fill="url(#tbg)"/>
<!-- Overcast fog -->
<g filter="url(#tbf)" opacity=".5"><ellipse cx="80" cy="50" rx="80" ry="30" fill="#d0dce8"/><ellipse cx="190" cy="40" rx="70" ry="25" fill="#c8d8e8"/></g>
<!-- Thames river -->
<path d="M0,195 Q65,183 130,190 Q195,183 260,192 L260,260 L0,260 Z" fill="#3a5a70"/>
<!-- Victorian towers -->
<g fill="#5a4a30">
<!-- Left tower -->
<rect x="60" y="120" width="34" height="80"/>
<rect x="55" y="118" width="44" height="12"/>
<!-- Tower turrets -->
<rect x="58" y="90" width="10" height="32"/><rect x="76" y="90" width="10" height="32"/>
<polygon points="55,90 63,72 71,90"/><polygon points="73,90 81,72 89,90"/>
<!-- Windows -->
<g fill="#6888aa" opacity=".7"><rect x="63" y="128" width="8" height="12" rx="2"/><rect x="75" y="128" width="8" height="12" rx="2"/><rect x="63" y="148" width="8" height="12" rx="2"/><rect x="75" y="148" width="8" height="12" rx="2"/></g>
</g>
<g fill="#5a4a30">
<!-- Right tower -->
<rect x="166" y="120" width="34" height="80"/>
<rect x="161" y="118" width="44" height="12"/>
<rect x="164" y="90" width="10" height="32"/><rect x="182" y="90" width="10" height="32"/>
<polygon points="161,90 169,72 177,90"/><polygon points="179,90 187,72 195,90"/>
<g fill="#6888aa" opacity=".7"><rect x="169" y="128" width="8" height="12" rx="2"/><rect x="181" y="128" width="8" height="12" rx="2"/><rect x="169" y="148" width="8" height="12" rx="2"/><rect x="181" y="148" width="8" height="12" rx="2"/></g>
</g>
<!-- High walkway -->
<rect x="70" y="108" width="120" height="8" fill="#6a5a40"/>
<!-- Bridge deck with bascules -->
<rect x="0" y="185" width="60" height="10" fill="#5a4a30"/>
<rect x="200" y="185" width="60" height="10" fill="#5a4a30"/>
<!-- Open bascules (raised) -->
<path d="M60,190 Q72,170 80,140 L94,195" fill="#6a5a40" opacity=".9"/>
<path d="M200,190 Q188,170 180,140 L166,195" fill="#6a5a40" opacity=".9"/>
<!-- Suspension cables -->
<g stroke="#6a5a40" stroke-width="3" fill="none"><path d="M0,178 Q65,165 94,185"/><path d="M260,178 Q195,165 166,185"/></g>
<!-- City / St Paul's in background -->
<g fill="#4a4838" opacity=".4"><rect x="100" y="150" width="60" height="45"/><polygon points="95,150 130,130 165,150"/><circle cx="130" cy="130" r="12" fill="none" stroke="#4a4838" stroke-width="3" opacity=".4"/></g>
<!-- River reflections -->
<g stroke="#6a8898" stroke-width="1" fill="none" opacity=".4"><path d="M0,205 Q65,198 130,203 Q195,198 260,202"/></g>
</svg>
</div>
<!-- Left: Millau Viaduct -->
<div class="ig-13__face ig-13__face--left">
<svg viewBox="0 0 260 260" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="mvg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#8ab0c8"/><stop offset="40%" stop-color="#b0c8d8"/><stop offset="100%" stop-color="#d0e0e8"/></linearGradient></defs>
<rect width="260" height="260" fill="url(#mvg)"/>
<!-- Valley mist -->
<g opacity=".4"><ellipse cx="130" cy="215" rx="200" ry="55" fill="#d8e8f0"/></g>
<!-- Mountain cliffs each side -->
<polygon points="0,260 0,140 55,100 80,160 80,260" fill="#6a7a6a"/>
<polygon points="260,260 260,135 205,95 180,155 180,260" fill="#6a7a6a"/>
<!-- Valley -->
<path d="M75,230 Q130,215 185,230 L185,260 L75,260 Z" fill="#3a5a3a" opacity=".5"/>
<!-- Mast towers -->
<g fill="#bbbbc0">
<!-- 7 masts -->
<rect x="30" y="130" width="6" height="80"/><line x1="33" y1="100" x2="33" y2="135" stroke="#bbbbc0" stroke-width="6"/>
<rect x="65" y="118" width="6" height="82"/><line x1="68" y1="88" x2="68" y2="122" stroke="#bbbbc0" stroke-width="6"/>
<rect x="100" y="108" width="6" height="82"/><line x1="103" y1="78" x2="103" y2="112" stroke="#bbbbc0" stroke-width="6"/>
<rect x="127" y="105" width="6" height="80"/><line x1="130" y1="75" x2="130" y2="109" stroke="#bbbbc0" stroke-width="6"/>
<rect x="154" y="108" width="6" height="82"/><line x1="157" y1="78" x2="157" y2="112" stroke="#bbbbc0" stroke-width="6"/>
<rect x="189" y="118" width="6" height="82"/><line x1="192" y1="88" x2="192" y2="122" stroke="#bbbbc0" stroke-width="6"/>
<rect x="224" y="130" width="6" height="80"/><line x1="227" y1="100" x2="227" y2="135" stroke="#bbbbc0" stroke-width="6"/>
</g>
<!-- Stay cables from mast tops -->
<g stroke="#aaaaaf" stroke-width="1" fill="none" opacity=".7">
<path d="M33,100 Q50,155 65,160"/><path d="M33,100 Q18,155 10,165"/>
<path d="M68,88 Q84,148 100,158"/><path d="M68,88 Q52,148 40,158"/>
<path d="M130,75 Q115,148 100,160"/><path d="M130,75 Q145,148 160,160"/>
<path d="M192,88 Q176,148 160,158"/><path d="M192,88 Q208,148 220,158"/>
<path d="M227,100 Q210,155 195,160"/><path d="M227,100 Q242,155 250,165"/>
</g>
<!-- Deck -->
<rect x="8" y="160" width="244" height="8" fill="#b0b8be"/>
<!-- Pier legs taper down into mist -->
<g stroke="#bbbbc0" stroke-width="8" fill="none" opacity=".6">
<line x1="33" y1="167" x2="33" y2="230"/><line x1="68" y1="167" x2="68" y2="225"/>
<line x1="103" y1="167" x2="103" y2="220"/><line x1="130" y1="167" x2="130" y2="218"/>
<line x1="157" y1="167" x2="157" y2="220"/><line x1="192" y1="167" x2="192" y2="225"/>
<line x1="227" y1="167" x2="227" y2="230"/>
</g>
<!-- Clouds in valley -->
<g fill="#e8f0f8" opacity=".5"><ellipse cx="80" cy="218" rx="55" ry="22"/><ellipse cx="180" cy="215" rx="50" ry="20"/></g>
</svg>
</div>
<!-- Top: Rialto Bridge -->
<div class="ig-13__face ig-13__face--top">
<svg viewBox="0 0 260 260" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="rbg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#6aaad4"/><stop offset="50%" stop-color="#88c4e8"/><stop offset="100%" stop-color="#4488b0"/></linearGradient></defs>
<rect width="260" height="260" fill="url(#rbg)"/>
<!-- Venetian canal -->
<!-- Buildings flanking canal -->
<g fill="#c8a870"><rect x="0" y="60" width="65" height="200"/><rect x="195" y="55" width="65" height="205"/></g>
<g fill="#b89858"><rect x="0" y="60" width="65" height="12"/><rect x="195" y="55" width="65" height="12"/></g>
<!-- Windows -->
<g fill="#6888aa" opacity=".7"><rect x="8" y="75" width="10" height="14" rx="2"/><rect x="24" y="75" width="10" height="14" rx="2"/><rect x="40" y="75" width="10" height="14" rx="2"/><rect x="8" y="100" width="10" height="14" rx="2"/><rect x="24" y="100" width="10" height="14" rx="2"/><rect x="205" y="70" width="10" height="14" rx="2"/><rect x="220" y="70" width="10" height="14" rx="2"/><rect x="238" y="70" width="10" height="14" rx="2"/></g>
<!-- Canal water -->
<rect x="65" y="0" width="130" height="260" fill="#4488aa"/>
<!-- Canal reflections -->
<g stroke="#5599bb" stroke-width="1" fill="none" opacity=".4"><path d="M65,80 Q130,72 195,80"/><path d="M65,110 Q130,103 195,110"/><path d="M65,140 Q130,133 195,140"/><path d="M65,170 Q130,163 195,170"/></g>
<!-- Rialto bridge arch -->
<g fill="#d4b080">
<path d="M65,140 Q95,90 130,75 Q165,90 195,140 L195,155 Q165,105 130,90 Q95,105 65,155 Z"/>
<rect x="65" y="155" width="130" height="12"/>
</g>
<!-- Bridge arcade shops -->
<g fill="#8a6030">
<rect x="80" y="100" width="12" height="35" rx="2"/><rect x="96" y="95" width="12" height="40" rx="2"/>
<rect x="112" y="92" width="12" height="42" rx="2"/><rect x="128" y="91" width="12" height="42" rx="2"/>
<rect x="144" y="92" width="12" height="40" rx="2"/><rect x="160" y="95" width="12" height="38" rx="2"/>
</g>
<!-- Center arch opening -->
<path d="M107,100 Q130,80 153,100 L153,145 L107,145 Z" fill="#4488aa" opacity=".8"/>
<!-- Gondola beneath -->
<g transform="translate(130,210)">
<path d="M-20,0 Q-15,-5 0,-4 Q15,-5 22,0 Q18,6 -18,6 Z" fill="#0a0a0a"/>
<rect x="-2" y="-12" width="3" height="12" fill="#6a4020"/>
</g>
</svg>
</div>
<!-- Bottom: Brooklyn Bridge -->
<div class="ig-13__face ig-13__face--bottom">
<svg viewBox="0 0 260 260" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="bbg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#1a2a4a"/><stop offset="50%" stop-color="#2a4060"/><stop offset="100%" stop-color="#1a2a3a"/></linearGradient></defs>
<rect width="260" height="260" fill="url(#bbg)"/>
<!-- City lights distant -->
<g fill="#ffd060" opacity=".6"><rect x="5" y="185" width="4" height="6"/><rect x="14" y="180" width="4" height="8"/><rect x="22" y="183" width="4" height="5"/><rect x="220" y="180" width="4" height="8"/><rect x="230" y="184" width="4" height="6"/><rect x="240" y="178" width="4" height="10"/><rect x="250" y="182" width="4" height="7"/></g>
<!-- East River -->
<path d="M0,195 Q65,183 130,190 Q195,183 260,192 L260,260 L0,260 Z" fill="#141e30"/>
<g stroke="#1e3040" stroke-width="1.5" fill="none" opacity=".5"><path d="M0,210 Q65,202 130,207 Q195,202 260,206"/></g>
<!-- Gothic towers -->
<g fill="#8a7050">
<!-- Left tower -->
<rect x="72" y="100" width="36" height="100"/>
<rect x="69" y="98" width="42" height="12"/>
<!-- Gothic arches at top -->
<path d="M72,98 Q90,78 108,98" fill="#7a6040"/>
<path d="M75,98 Q90,81 105,98" fill="none" stroke="#6a5030" stroke-width="2"/>
<!-- Windows -->
<g fill="#3a5070" opacity=".8"><path d="M78,110 Q85,100 92,110 L92,128 L78,128 Z"/><path d="M96,112 Q103,102 110,112 L110,128 L96,128 Z"/></g>
<!-- Right tower -->
<rect x="152" y="100" width="36" height="100"/>
<rect x="149" y="98" width="42" height="12"/>
<path d="M152,98 Q170,78 188,98" fill="#7a6040"/>
<path d="M155,98 Q170,81 185,98" fill="none" stroke="#6a5030" stroke-width="2"/>
<g fill="#3a5070" opacity=".8"><path d="M158,110 Q165,100 172,110 L172,128 L158,128 Z"/><path d="M176,112 Q183,102 190,112 L190,128 L176,128 Z"/></g>
</g>
<!-- Main cables -->
<g stroke="#8a7050" stroke-width="5" fill="none"><path d="M0,158 Q90,118 130,140 Q170,118 260,145"/></g>
<!-- Suspender cables fan -->
<g stroke="#6a5840" stroke-width="1.2" fill="none" opacity=".7">
<line x1="90" y1="118" x2="40" y2="190"/><line x1="90" y1="118" x2="58" y2="190"/><line x1="90" y1="118" x2="76" y2="190"/><line x1="90" y1="118" x2="95" y2="190"/>
<line x1="170" y1="118" x2="165" y2="190"/><line x1="170" y1="118" x2="184" y2="190"/><line x1="170" y1="118" x2="202" y2="190"/><line x1="170" y1="118" x2="220" y2="190"/>
<line x1="130" y1="128" x2="112" y2="190"/><line x1="130" y1="128" x2="130" y2="190"/><line x1="130" y1="128" x2="148" y2="190"/>
</g>
<!-- Road deck -->
<rect x="0" y="190" width="260" height="8" fill="#5a5040"/>
<!-- Stars -->
<g fill="#fff" opacity=".6"><circle cx="20" cy="25" r="1"/><circle cx="60" cy="15" r="1.1"/><circle cx="105" cy="28" r=".9"/><circle cx="165" cy="18" r="1"/><circle cx="215" cy="25" r=".9"/><circle cx="248" cy="12" r="1.1"/></g>
<!-- Water taxi -->
<g transform="translate(60,222)">
<rect x="-18" y="-5" width="36" height="10" rx="4" fill="#cc2020"/>
<rect x="-8" y="-12" width="18" height="8" rx="2" fill="#aa1818"/>
</g>
</svg>
</div>
</div>
</div>
<div class="ig-13__controls" id="ig-13-controls">
<button class="ig-13__btn ig-13--active" data-y="0" data-x="-10">Front</button>
<button class="ig-13__btn" data-y="90" data-x="-10">Right</button>
<button class="ig-13__btn" data-y="180" data-x="-10">Back</button>
<button class="ig-13__btn" data-y="-90" data-x="-10">Left</button>
<button class="ig-13__btn" data-y="0" data-x="-90">Top</button>
<button class="ig-13__btn" data-y="0" data-x="90">Bottom</button>
</div>
<p class="ig-13__label">6 iconic bridges of the world</p>
</div>
<script>
(function(){
const cube=document.getElementById('ig-13-cube');
const btns=document.querySelectorAll('#ig-13-controls .ig-13__btn');
if(!cube)return;
btns.forEach(btn=>{
btn.addEventListener('click',()=>{
btns.forEach(b=>b.classList.remove('ig-13--active'));
btn.classList.add('ig-13--active');
const y=Number(btn.dataset.y)||0;
const x=Number(btn.dataset.x)||-10;
cube.style.transform=`rotateX(${x}deg) rotateY(${y}deg)`;
});
});
}());
</script> <div class="ig-13">
<div class="ig-13__viewport">
<div class="ig-13__cube" id="ig-13-cube">
<!-- Front: Golden Gate Bridge -->
<div class="ig-13__face ig-13__face--front">
<svg viewBox="0 0 260 260" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="ggg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#4488cc"/><stop offset="50%" stop-color="#88aacc"/><stop offset="100%" stop-color="#2a5a7a"/></linearGradient><filter id="ggf"><feGaussianBlur stdDeviation="4"/></filter></defs>
<rect width="260" height="260" fill="url(#ggg)"/>
<g filter="url(#ggf)" opacity=".4"><ellipse cx="130" cy="90" rx="100" ry="30" fill="#c8d8e8"/></g>
<!-- Bay -->
<path d="M0,185 Q65,172 130,180 Q195,172 260,182 L260,260 L0,260 Z" fill="#1a4a6a"/>
<!-- Bridge towers -->
<g fill="#cc3010">
<rect x="70" y="80" width="14" height="110"/><rect x="176" y="80" width="14" height="110"/>
<!-- Tower details -->
<rect x="66" y="80" width="22" height="10"/><rect x="172" y="80" width="22" height="10"/>
<rect x="66" y="100" width="22" height="8"/><rect x="172" y="100" width="22" height="8"/>
<rect x="66" y="120" width="22" height="8"/><rect x="172" y="120" width="22" height="8"/>
<!-- Tops -->
<rect x="74" y="72" width="6" height="12"/><rect x="180" y="72" width="6" height="12"/>
</g>
<!-- Main cables -->
<g stroke="#cc3010" stroke-width="4" fill="none">
<path d="M0,145 Q77,105 130,130 Q183,105 260,130"/>
<path d="M0,150 Q77,110 130,135 Q183,110 260,135"/>
</g>
<!-- Hanger cables -->
<g stroke="#cc3010" stroke-width="1" fill="none" opacity=".7">
<line x1="20" y1="148" x2="20" y2="178"/><line x1="40" y1="138" x2="40" y2="178"/>
<line x1="60" y1="132" x2="60" y2="178"/><line x1="100" y1="125" x2="100" y2="178"/>
<line x1="120" y1="125" x2="120" y2="178"/><line x1="140" y1="125" x2="140" y2="178"/>
<line x1="160" y1="126" x2="160" y2="178"/><line x1="200" y1="130" x2="200" y2="178"/>
<line x1="220" y1="136" x2="220" y2="178"/><line x1="240" y1="142" x2="240" y2="178"/>
</g>
<!-- Deck -->
<rect x="0" y="178" width="260" height="8" fill="#aa2808"/>
<!-- Hills bg -->
<g fill="#1a3a1a" opacity=".5"><polygon points="0,185 0,160 45,140 90,160 90,185"/><polygon points="170,185 170,158 215,138 260,158 260,185"/></g>
<!-- Fog wisps -->
<g opacity=".3" fill="#c8d8e8" filter="url(#ggf)"><ellipse cx="40" cy="160" rx="50" ry="18"/><ellipse cx="215" cy="155" rx="45" ry="16"/></g>
</svg>
</div>
<!-- Right: Sydney Harbour Bridge -->
<div class="ig-13__face ig-13__face--right">
<svg viewBox="0 0 260 260" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="shg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#1a3a5c"/><stop offset="50%" stop-color="#2a5a80"/><stop offset="100%" stop-color="#1a3050"/></linearGradient></defs>
<rect width="260" height="260" fill="url(#shg)"/>
<!-- Harbour water -->
<path d="M0,190 Q65,178 130,185 Q195,178 260,188 L260,260 L0,260 Z" fill="#1a3a5a"/>
<!-- Sydney Opera House in bg -->
<g fill="#d8d0c8" opacity=".7">
<path d="M10,190 Q30,160 50,185 Z"/><path d="M22,190 Q45,155 68,185 Z"/>
<path d="M55,190 Q72,165 90,185 Z"/>
</g>
<!-- Bridge arch -->
<path d="M30,195 Q130,40 230,195" stroke="#555566" stroke-width="22" fill="none"/>
<path d="M30,195 Q130,45 230,195" stroke="#888898" stroke-width="8" fill="none"/>
<!-- Pylons -->
<g fill="#3a3a4a"><rect x="22" y="160" width="18" height="40"/><rect x="220" y="160" width="18" height="40"/><rect x="18" y="157" width="26" height="10" rx="2"/><rect x="216" y="157" width="26" height="10" rx="2"/></g>
<!-- Hanger rods -->
<g stroke="#555566" stroke-width="1.5" fill="none">
<line x1="50" y1="152" x2="50" y2="190"/><line x1="70" y1="120" x2="70" y2="190"/>
<line x1="90" y1="100" x2="90" y2="190"/><line x1="110" y1="88" x2="110" y2="190"/>
<line x1="130" y1="82" x2="130" y2="190"/><line x1="150" y1="88" x2="150" y2="190"/>
<line x1="170" y1="100" x2="170" y2="190"/><line x1="190" y1="120" x2="190" y2="190"/>
<line x1="210" y1="152" x2="210" y2="190"/>
</g>
<!-- Bridge deck -->
<rect x="25" y="185" width="210" height="10" fill="#4a4a5a"/>
<!-- City skyline -->
<g fill="#1a2a3a"><rect x="120" y="155" width="25" height="35"/><rect x="148" y="148" width="20" height="42"/><rect x="170" y="158" width="18" height="32"/><rect x="190" y="152" width="22" height="38"/><rect x="215" y="160" width="15" height="30"/></g>
<!-- Stars -->
<g fill="#fff" opacity=".6"><circle cx="25" cy="20" r="1"/><circle cx="70" cy="8" r="1.1"/><circle cx="120" cy="15" r=".9"/><circle cx="185" cy="8" r="1"/><circle cx="235" cy="20" r=".9"/></g>
<!-- Fireworks glow -->
<circle cx="130" cy="55" r="30" fill="#ff4020" opacity=".08"/>
</svg>
</div>
<!-- Back: Tower Bridge -->
<div class="ig-13__face ig-13__face--back">
<svg viewBox="0 0 260 260" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="tbg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#c8d8e8"/><stop offset="40%" stop-color="#a0b8cc"/><stop offset="100%" stop-color="#3a5a6a"/></linearGradient><filter id="tbf"><feGaussianBlur stdDeviation="4"/></filter></defs>
<rect width="260" height="260" fill="url(#tbg)"/>
<!-- Overcast fog -->
<g filter="url(#tbf)" opacity=".5"><ellipse cx="80" cy="50" rx="80" ry="30" fill="#d0dce8"/><ellipse cx="190" cy="40" rx="70" ry="25" fill="#c8d8e8"/></g>
<!-- Thames river -->
<path d="M0,195 Q65,183 130,190 Q195,183 260,192 L260,260 L0,260 Z" fill="#3a5a70"/>
<!-- Victorian towers -->
<g fill="#5a4a30">
<!-- Left tower -->
<rect x="60" y="120" width="34" height="80"/>
<rect x="55" y="118" width="44" height="12"/>
<!-- Tower turrets -->
<rect x="58" y="90" width="10" height="32"/><rect x="76" y="90" width="10" height="32"/>
<polygon points="55,90 63,72 71,90"/><polygon points="73,90 81,72 89,90"/>
<!-- Windows -->
<g fill="#6888aa" opacity=".7"><rect x="63" y="128" width="8" height="12" rx="2"/><rect x="75" y="128" width="8" height="12" rx="2"/><rect x="63" y="148" width="8" height="12" rx="2"/><rect x="75" y="148" width="8" height="12" rx="2"/></g>
</g>
<g fill="#5a4a30">
<!-- Right tower -->
<rect x="166" y="120" width="34" height="80"/>
<rect x="161" y="118" width="44" height="12"/>
<rect x="164" y="90" width="10" height="32"/><rect x="182" y="90" width="10" height="32"/>
<polygon points="161,90 169,72 177,90"/><polygon points="179,90 187,72 195,90"/>
<g fill="#6888aa" opacity=".7"><rect x="169" y="128" width="8" height="12" rx="2"/><rect x="181" y="128" width="8" height="12" rx="2"/><rect x="169" y="148" width="8" height="12" rx="2"/><rect x="181" y="148" width="8" height="12" rx="2"/></g>
</g>
<!-- High walkway -->
<rect x="70" y="108" width="120" height="8" fill="#6a5a40"/>
<!-- Bridge deck with bascules -->
<rect x="0" y="185" width="60" height="10" fill="#5a4a30"/>
<rect x="200" y="185" width="60" height="10" fill="#5a4a30"/>
<!-- Open bascules (raised) -->
<path d="M60,190 Q72,170 80,140 L94,195" fill="#6a5a40" opacity=".9"/>
<path d="M200,190 Q188,170 180,140 L166,195" fill="#6a5a40" opacity=".9"/>
<!-- Suspension cables -->
<g stroke="#6a5a40" stroke-width="3" fill="none"><path d="M0,178 Q65,165 94,185"/><path d="M260,178 Q195,165 166,185"/></g>
<!-- City / St Paul's in background -->
<g fill="#4a4838" opacity=".4"><rect x="100" y="150" width="60" height="45"/><polygon points="95,150 130,130 165,150"/><circle cx="130" cy="130" r="12" fill="none" stroke="#4a4838" stroke-width="3" opacity=".4"/></g>
<!-- River reflections -->
<g stroke="#6a8898" stroke-width="1" fill="none" opacity=".4"><path d="M0,205 Q65,198 130,203 Q195,198 260,202"/></g>
</svg>
</div>
<!-- Left: Millau Viaduct -->
<div class="ig-13__face ig-13__face--left">
<svg viewBox="0 0 260 260" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="mvg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#8ab0c8"/><stop offset="40%" stop-color="#b0c8d8"/><stop offset="100%" stop-color="#d0e0e8"/></linearGradient></defs>
<rect width="260" height="260" fill="url(#mvg)"/>
<!-- Valley mist -->
<g opacity=".4"><ellipse cx="130" cy="215" rx="200" ry="55" fill="#d8e8f0"/></g>
<!-- Mountain cliffs each side -->
<polygon points="0,260 0,140 55,100 80,160 80,260" fill="#6a7a6a"/>
<polygon points="260,260 260,135 205,95 180,155 180,260" fill="#6a7a6a"/>
<!-- Valley -->
<path d="M75,230 Q130,215 185,230 L185,260 L75,260 Z" fill="#3a5a3a" opacity=".5"/>
<!-- Mast towers -->
<g fill="#bbbbc0">
<!-- 7 masts -->
<rect x="30" y="130" width="6" height="80"/><line x1="33" y1="100" x2="33" y2="135" stroke="#bbbbc0" stroke-width="6"/>
<rect x="65" y="118" width="6" height="82"/><line x1="68" y1="88" x2="68" y2="122" stroke="#bbbbc0" stroke-width="6"/>
<rect x="100" y="108" width="6" height="82"/><line x1="103" y1="78" x2="103" y2="112" stroke="#bbbbc0" stroke-width="6"/>
<rect x="127" y="105" width="6" height="80"/><line x1="130" y1="75" x2="130" y2="109" stroke="#bbbbc0" stroke-width="6"/>
<rect x="154" y="108" width="6" height="82"/><line x1="157" y1="78" x2="157" y2="112" stroke="#bbbbc0" stroke-width="6"/>
<rect x="189" y="118" width="6" height="82"/><line x1="192" y1="88" x2="192" y2="122" stroke="#bbbbc0" stroke-width="6"/>
<rect x="224" y="130" width="6" height="80"/><line x1="227" y1="100" x2="227" y2="135" stroke="#bbbbc0" stroke-width="6"/>
</g>
<!-- Stay cables from mast tops -->
<g stroke="#aaaaaf" stroke-width="1" fill="none" opacity=".7">
<path d="M33,100 Q50,155 65,160"/><path d="M33,100 Q18,155 10,165"/>
<path d="M68,88 Q84,148 100,158"/><path d="M68,88 Q52,148 40,158"/>
<path d="M130,75 Q115,148 100,160"/><path d="M130,75 Q145,148 160,160"/>
<path d="M192,88 Q176,148 160,158"/><path d="M192,88 Q208,148 220,158"/>
<path d="M227,100 Q210,155 195,160"/><path d="M227,100 Q242,155 250,165"/>
</g>
<!-- Deck -->
<rect x="8" y="160" width="244" height="8" fill="#b0b8be"/>
<!-- Pier legs taper down into mist -->
<g stroke="#bbbbc0" stroke-width="8" fill="none" opacity=".6">
<line x1="33" y1="167" x2="33" y2="230"/><line x1="68" y1="167" x2="68" y2="225"/>
<line x1="103" y1="167" x2="103" y2="220"/><line x1="130" y1="167" x2="130" y2="218"/>
<line x1="157" y1="167" x2="157" y2="220"/><line x1="192" y1="167" x2="192" y2="225"/>
<line x1="227" y1="167" x2="227" y2="230"/>
</g>
<!-- Clouds in valley -->
<g fill="#e8f0f8" opacity=".5"><ellipse cx="80" cy="218" rx="55" ry="22"/><ellipse cx="180" cy="215" rx="50" ry="20"/></g>
</svg>
</div>
<!-- Top: Rialto Bridge -->
<div class="ig-13__face ig-13__face--top">
<svg viewBox="0 0 260 260" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="rbg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#6aaad4"/><stop offset="50%" stop-color="#88c4e8"/><stop offset="100%" stop-color="#4488b0"/></linearGradient></defs>
<rect width="260" height="260" fill="url(#rbg)"/>
<!-- Venetian canal -->
<!-- Buildings flanking canal -->
<g fill="#c8a870"><rect x="0" y="60" width="65" height="200"/><rect x="195" y="55" width="65" height="205"/></g>
<g fill="#b89858"><rect x="0" y="60" width="65" height="12"/><rect x="195" y="55" width="65" height="12"/></g>
<!-- Windows -->
<g fill="#6888aa" opacity=".7"><rect x="8" y="75" width="10" height="14" rx="2"/><rect x="24" y="75" width="10" height="14" rx="2"/><rect x="40" y="75" width="10" height="14" rx="2"/><rect x="8" y="100" width="10" height="14" rx="2"/><rect x="24" y="100" width="10" height="14" rx="2"/><rect x="205" y="70" width="10" height="14" rx="2"/><rect x="220" y="70" width="10" height="14" rx="2"/><rect x="238" y="70" width="10" height="14" rx="2"/></g>
<!-- Canal water -->
<rect x="65" y="0" width="130" height="260" fill="#4488aa"/>
<!-- Canal reflections -->
<g stroke="#5599bb" stroke-width="1" fill="none" opacity=".4"><path d="M65,80 Q130,72 195,80"/><path d="M65,110 Q130,103 195,110"/><path d="M65,140 Q130,133 195,140"/><path d="M65,170 Q130,163 195,170"/></g>
<!-- Rialto bridge arch -->
<g fill="#d4b080">
<path d="M65,140 Q95,90 130,75 Q165,90 195,140 L195,155 Q165,105 130,90 Q95,105 65,155 Z"/>
<rect x="65" y="155" width="130" height="12"/>
</g>
<!-- Bridge arcade shops -->
<g fill="#8a6030">
<rect x="80" y="100" width="12" height="35" rx="2"/><rect x="96" y="95" width="12" height="40" rx="2"/>
<rect x="112" y="92" width="12" height="42" rx="2"/><rect x="128" y="91" width="12" height="42" rx="2"/>
<rect x="144" y="92" width="12" height="40" rx="2"/><rect x="160" y="95" width="12" height="38" rx="2"/>
</g>
<!-- Center arch opening -->
<path d="M107,100 Q130,80 153,100 L153,145 L107,145 Z" fill="#4488aa" opacity=".8"/>
<!-- Gondola beneath -->
<g transform="translate(130,210)">
<path d="M-20,0 Q-15,-5 0,-4 Q15,-5 22,0 Q18,6 -18,6 Z" fill="#0a0a0a"/>
<rect x="-2" y="-12" width="3" height="12" fill="#6a4020"/>
</g>
</svg>
</div>
<!-- Bottom: Brooklyn Bridge -->
<div class="ig-13__face ig-13__face--bottom">
<svg viewBox="0 0 260 260" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="bbg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#1a2a4a"/><stop offset="50%" stop-color="#2a4060"/><stop offset="100%" stop-color="#1a2a3a"/></linearGradient></defs>
<rect width="260" height="260" fill="url(#bbg)"/>
<!-- City lights distant -->
<g fill="#ffd060" opacity=".6"><rect x="5" y="185" width="4" height="6"/><rect x="14" y="180" width="4" height="8"/><rect x="22" y="183" width="4" height="5"/><rect x="220" y="180" width="4" height="8"/><rect x="230" y="184" width="4" height="6"/><rect x="240" y="178" width="4" height="10"/><rect x="250" y="182" width="4" height="7"/></g>
<!-- East River -->
<path d="M0,195 Q65,183 130,190 Q195,183 260,192 L260,260 L0,260 Z" fill="#141e30"/>
<g stroke="#1e3040" stroke-width="1.5" fill="none" opacity=".5"><path d="M0,210 Q65,202 130,207 Q195,202 260,206"/></g>
<!-- Gothic towers -->
<g fill="#8a7050">
<!-- Left tower -->
<rect x="72" y="100" width="36" height="100"/>
<rect x="69" y="98" width="42" height="12"/>
<!-- Gothic arches at top -->
<path d="M72,98 Q90,78 108,98" fill="#7a6040"/>
<path d="M75,98 Q90,81 105,98" fill="none" stroke="#6a5030" stroke-width="2"/>
<!-- Windows -->
<g fill="#3a5070" opacity=".8"><path d="M78,110 Q85,100 92,110 L92,128 L78,128 Z"/><path d="M96,112 Q103,102 110,112 L110,128 L96,128 Z"/></g>
<!-- Right tower -->
<rect x="152" y="100" width="36" height="100"/>
<rect x="149" y="98" width="42" height="12"/>
<path d="M152,98 Q170,78 188,98" fill="#7a6040"/>
<path d="M155,98 Q170,81 185,98" fill="none" stroke="#6a5030" stroke-width="2"/>
<g fill="#3a5070" opacity=".8"><path d="M158,110 Q165,100 172,110 L172,128 L158,128 Z"/><path d="M176,112 Q183,102 190,112 L190,128 L176,128 Z"/></g>
</g>
<!-- Main cables -->
<g stroke="#8a7050" stroke-width="5" fill="none"><path d="M0,158 Q90,118 130,140 Q170,118 260,145"/></g>
<!-- Suspender cables fan -->
<g stroke="#6a5840" stroke-width="1.2" fill="none" opacity=".7">
<line x1="90" y1="118" x2="40" y2="190"/><line x1="90" y1="118" x2="58" y2="190"/><line x1="90" y1="118" x2="76" y2="190"/><line x1="90" y1="118" x2="95" y2="190"/>
<line x1="170" y1="118" x2="165" y2="190"/><line x1="170" y1="118" x2="184" y2="190"/><line x1="170" y1="118" x2="202" y2="190"/><line x1="170" y1="118" x2="220" y2="190"/>
<line x1="130" y1="128" x2="112" y2="190"/><line x1="130" y1="128" x2="130" y2="190"/><line x1="130" y1="128" x2="148" y2="190"/>
</g>
<!-- Road deck -->
<rect x="0" y="190" width="260" height="8" fill="#5a5040"/>
<!-- Stars -->
<g fill="#fff" opacity=".6"><circle cx="20" cy="25" r="1"/><circle cx="60" cy="15" r="1.1"/><circle cx="105" cy="28" r=".9"/><circle cx="165" cy="18" r="1"/><circle cx="215" cy="25" r=".9"/><circle cx="248" cy="12" r="1.1"/></g>
<!-- Water taxi -->
<g transform="translate(60,222)">
<rect x="-18" y="-5" width="36" height="10" rx="4" fill="#cc2020"/>
<rect x="-8" y="-12" width="18" height="8" rx="2" fill="#aa1818"/>
</g>
</svg>
</div>
</div>
</div>
<div class="ig-13__controls" id="ig-13-controls">
<button class="ig-13__btn ig-13--active" data-y="0" data-x="-10">Front</button>
<button class="ig-13__btn" data-y="90" data-x="-10">Right</button>
<button class="ig-13__btn" data-y="180" data-x="-10">Back</button>
<button class="ig-13__btn" data-y="-90" data-x="-10">Left</button>
<button class="ig-13__btn" data-y="0" data-x="-90">Top</button>
<button class="ig-13__btn" data-y="0" data-x="90">Bottom</button>
</div>
<p class="ig-13__label">6 iconic bridges of the world</p>
</div>
<script>
(function(){
const cube=document.getElementById('ig-13-cube');
const btns=document.querySelectorAll('#ig-13-controls .ig-13__btn');
if(!cube)return;
btns.forEach(btn=>{
btn.addEventListener('click',()=>{
btns.forEach(b=>b.classList.remove('ig-13--active'));
btn.classList.add('ig-13--active');
const y=Number(btn.dataset.y)||0;
const x=Number(btn.dataset.x)||-10;
cube.style.transform=`rotateX(${x}deg) rotateY(${y}deg)`;
});
});
}());
</script>*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
body{background:#0a0c10;font-family:'DM Sans',sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;gap:2rem;padding:2rem}
.ig-13{display:flex;flex-direction:column;align-items:center;gap:1.8rem}
.ig-13__viewport{perspective:900px;width:260px;height:260px}
.ig-13__cube{width:100%;height:100%;position:relative;transform-style:preserve-3d;transform:rotateX(-10deg) rotateY(0deg);transition:transform .65s cubic-bezier(.25,.46,.45,.94)}
.ig-13__face{position:absolute;width:100%;height:100%;backface-visibility:hidden;border-radius:8px;overflow:hidden;border:2px solid rgba(255,255,255,.12)}
.ig-13__face svg{width:100%;height:100%;display:block}
.ig-13__face--front {transform:translateZ(130px)}
.ig-13__face--back {transform:rotateY(180deg) translateZ(130px)}
.ig-13__face--right {transform:rotateY(90deg) translateZ(130px)}
.ig-13__face--left {transform:rotateY(-90deg) translateZ(130px)}
.ig-13__face--top {transform:rotateX(90deg) translateZ(130px)}
.ig-13__face--bottom{transform:rotateX(-90deg) translateZ(130px)}
.ig-13__controls{display:flex;gap:.6rem;flex-wrap:wrap;justify-content:center}
.ig-13__btn{background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.15);color:rgba(255,255,255,.75);font-size:.72rem;font-weight:600;letter-spacing:.08em;padding:.4rem .9rem;border-radius:8px;cursor:pointer;font-family:'DM Sans',sans-serif;transition:background .2s ease,color .2s ease;text-transform:uppercase}
.ig-13__btn:hover{background:rgba(255,255,255,.18);color:#fff}
.ig-13__btn.ig-13--active{background:rgba(255,255,255,.22);color:#fff;border-color:rgba(255,255,255,.4)}
.ig-13__label{color:rgba(255,255,255,.35);font-size:.7rem;letter-spacing:.08em;text-transform:uppercase}
@media(prefers-reduced-motion:reduce){.ig-13__cube{transition:none}} *,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
body{background:#0a0c10;font-family:'DM Sans',sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;gap:2rem;padding:2rem}
.ig-13{display:flex;flex-direction:column;align-items:center;gap:1.8rem}
.ig-13__viewport{perspective:900px;width:260px;height:260px}
.ig-13__cube{width:100%;height:100%;position:relative;transform-style:preserve-3d;transform:rotateX(-10deg) rotateY(0deg);transition:transform .65s cubic-bezier(.25,.46,.45,.94)}
.ig-13__face{position:absolute;width:100%;height:100%;backface-visibility:hidden;border-radius:8px;overflow:hidden;border:2px solid rgba(255,255,255,.12)}
.ig-13__face svg{width:100%;height:100%;display:block}
.ig-13__face--front {transform:translateZ(130px)}
.ig-13__face--back {transform:rotateY(180deg) translateZ(130px)}
.ig-13__face--right {transform:rotateY(90deg) translateZ(130px)}
.ig-13__face--left {transform:rotateY(-90deg) translateZ(130px)}
.ig-13__face--top {transform:rotateX(90deg) translateZ(130px)}
.ig-13__face--bottom{transform:rotateX(-90deg) translateZ(130px)}
.ig-13__controls{display:flex;gap:.6rem;flex-wrap:wrap;justify-content:center}
.ig-13__btn{background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.15);color:rgba(255,255,255,.75);font-size:.72rem;font-weight:600;letter-spacing:.08em;padding:.4rem .9rem;border-radius:8px;cursor:pointer;font-family:'DM Sans',sans-serif;transition:background .2s ease,color .2s ease;text-transform:uppercase}
.ig-13__btn:hover{background:rgba(255,255,255,.18);color:#fff}
.ig-13__btn.ig-13--active{background:rgba(255,255,255,.22);color:#fff;border-color:rgba(255,255,255,.4)}
.ig-13__label{color:rgba(255,255,255,.35);font-size:.7rem;letter-spacing:.08em;text-transform:uppercase}
@media(prefers-reduced-motion:reduce){.ig-13__cube{transition:none}}(function(){
const cube=document.getElementById('ig-13-cube');
const btns=document.querySelectorAll('#ig-13-controls .ig-13__btn');
if(!cube)return;
btns.forEach(btn=>{
btn.addEventListener('click',()=>{
btns.forEach(b=>b.classList.remove('ig-13--active'));
btn.classList.add('ig-13--active');
const y=Number(btn.dataset.y)||0;
const x=Number(btn.dataset.x)||-10;
cube.style.transform=`rotateX(${x}deg) rotateY(${y}deg)`;
});
});
}()); (function(){
const cube=document.getElementById('ig-13-cube');
const btns=document.querySelectorAll('#ig-13-controls .ig-13__btn');
if(!cube)return;
btns.forEach(btn=>{
btn.addEventListener('click',()=>{
btns.forEach(b=>b.classList.remove('ig-13--active'));
btn.classList.add('ig-13--active');
const y=Number(btn.dataset.y)||0;
const x=Number(btn.dataset.x)||-10;
cube.style.transform=`rotateX(${x}deg) rotateY(${y}deg)`;
});
});
}());How this works
The cube is a div with transform-style: preserve-3d inside a perspective: 900px viewport. The six face elements each receive a different translateZ and rotateX/Y to place them on the correct side of a cube: front uses translateZ(130px), back rotateY(180deg) translateZ(130px), and the four sides use 90-degree rotations. The translateZ value (130px) equals half the cube edge length (260px).
JavaScript maps each button's data-x and data-y attributes to a rotateX / rotateY transform applied to the cube container. Because the cube rotates as a whole unit, the faces follow automatically. A CSS transition: transform .65s cubic-bezier animates the rotation smoothly between any two states.
Customize
- Change cube size by editing the face
position: absolute; width/height: 100%and thetranslateZ(130px)value — the Z offset must always equal half the cube edge length. - Add an auto-rotation idle animation by applying a CSS
@keyframesrotation to the cube and pausing it viaanimation-play-stateon user interaction. - Change the transition easing from
cubic-bezier(.25,.46,.45,.94)tocubic-bezier(.34,1.56,.64,1)for a spring overshoot on face changes. - Add face labels as
position: absoluteoverlays on each face usingz-indexto appear above the SVG content. - Change the viewport perspective from
900pxto600pxfor a wider-angle 3D look, or1400pxfor a flatter near-isometric appearance.
Watch out for
- The cube
translateZvalue must exactly equal half the edge length — if the cube is 260px wide but translateZ is 120px, the faces will overlap or gap. backface-visibility: hiddenon each face prevents back faces from showing through — without it, the back face appears mirrored over the front when rotating.- CSS 3D transforms require
transform-style: preserve-3don every intermediate ancestor between the perspective parent and the 3D elements; any ancestor withoverflow: hiddenwill flatten the 3D context.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 36+ | 9+ | 16+ | 36+ |
CSS 3D transforms with preserve-3d broadly supported; -webkit- prefix needed for older Safari.