10 CSS Parallax Effects 02 / 10
Multi-layered CSS Parallax Landscape / Illustration
Cinematic twilight scene with eight independent SVG layers — star field, crescent moon, sun glow corona, drifting clouds, far and near mountain ranges, tree silhouettes, and rolling ground — each scrolling 0.08× to 0.94× viewport speed for convincing pseudo-3D depth. Cinzel serif headline. Right-edge depth-indicator dots. Rich indigo-to-amber sunset gradient sky.
This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.
The code
<div class="plx-02">
<div class="plx-02__scene">
<!-- Layer 0: Sky (fixed) -->
<div class="plx-02__sky"></div>
<!-- Layer 1: Stars — slowest -->
<div class="plx-02__stars" data-plx="0.08">
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<defs><radialGradient id="star"><stop offset="0%" stop-color="#fff"/><stop offset="100%" stop-color="transparent"/></radialGradient></defs>
<!-- scattered stars -->
<circle cx="8%" cy="12%" r="1.2" fill="#fff" opacity="0.9"/>
<circle cx="18%" cy="5%" r="0.8" fill="#fff" opacity="0.7"/>
<circle cx="27%" cy="18%" r="1" fill="#fff" opacity="0.85"/>
<circle cx="35%" cy="8%" r="1.5" fill="#ffd" opacity="0.95"/>
<circle cx="42%" cy="22%" r="0.7" fill="#fff" opacity="0.6"/>
<circle cx="55%" cy="6%" r="1.1" fill="#fff" opacity="0.8"/>
<circle cx="63%" cy="16%" r="0.9" fill="#fff" opacity="0.75"/>
<circle cx="71%" cy="4%" r="1.3" fill="#ffd" opacity="0.9"/>
<circle cx="80%" cy="14%" r="0.8" fill="#fff" opacity="0.65"/>
<circle cx="88%" cy="8%" r="1.0" fill="#fff" opacity="0.8"/>
<circle cx="93%" cy="22%" r="0.7" fill="#fff" opacity="0.55"/>
<circle cx="12%" cy="28%" r="0.6" fill="#fff" opacity="0.5"/>
<circle cx="48%" cy="32%" r="0.5" fill="#fff" opacity="0.4"/>
<circle cx="76%" cy="27%" r="0.8" fill="#fff" opacity="0.6"/>
</svg>
</div>
<!-- Layer 2: Moon -->
<div class="plx-02__moon" data-plx="0.12"></div>
<!-- Layer 3: Sun glow at horizon -->
<div class="plx-02__sun" data-plx="0.25"></div>
<!-- Layer 4: Clouds -->
<div class="plx-02__clouds" data-plx="0.18">
<div class="plx-02__cloud"></div>
<div class="plx-02__cloud"></div>
<div class="plx-02__cloud"></div>
<div class="plx-02__cloud"></div>
</div>
<!-- Layer 5: Far mountains -->
<div class="plx-02__layer plx-02__mtn-far" data-plx="0.35">
<svg viewBox="0 0 1440 300" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<path d="M0,300 L0,180 L60,130 L120,160 L200,80 L280,140 L360,70 L440,120 L520,50 L600,110 L680,40 L760,100 L840,55 L920,115 L1000,65 L1080,125 L1160,85 L1240,145 L1320,90 L1440,150 L1440,300 Z"
fill="#1e2d4a"/>
<path d="M0,300 L0,200 L80,155 L160,185 L240,115 L320,155 L400,95 L480,145 L560,75 L640,130 L720,65 L800,125 L880,80 L960,140 L1040,90 L1120,150 L1200,105 L1280,165 L1360,110 L1440,175 L1440,300 Z"
fill="#253566" opacity="0.6"/>
</svg>
</div>
<!-- Layer 6: Mid mountains -->
<div class="plx-02__layer plx-02__mtn-mid" data-plx="0.5">
<svg viewBox="0 0 1440 260" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<path d="M0,260 L0,160 L90,100 L180,140 L270,70 L360,120 L450,55 L540,105 L630,40 L720,95 L810,30 L900,90 L990,60 L1080,115 L1170,75 L1260,130 L1350,85 L1440,140 L1440,260 Z"
fill="#2a3d60"/>
<path d="M0,260 L0,190 L100,150 L200,175 L300,115 L400,155 L500,90 L600,140 L700,80 L800,130 L900,70 L1000,125 L1100,95 L1200,150 L1300,110 L1440,165 L1440,260 Z"
fill="#3a5278" opacity="0.7"/>
</svg>
</div>
<!-- Fog layers -->
<div class="plx-02__fog plx-02__fog--a" data-plx="0.6"></div>
<div class="plx-02__fog plx-02__fog--b" data-plx="0.65"></div>
<!-- Layer 7: Near mountains / hills -->
<div class="plx-02__layer plx-02__mtn-near" data-plx="0.7">
<svg viewBox="0 0 1440 220" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<path d="M0,220 L0,140 L120,80 L240,130 L360,60 L480,110 L600,45 L720,100 L840,35 L960,95 L1080,50 L1200,110 L1320,70 L1440,120 L1440,220 Z"
fill="#0d1a0d"/>
</svg>
</div>
<!-- Layer 8: Far trees -->
<div class="plx-02__layer plx-02__trees-far" data-plx="0.82">
<svg viewBox="0 0 1440 140" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<path d="M0,140 L0,60 Q18,20 36,60 Q54,20 72,60 Q90,25 108,60 Q126,15 144,60 Q162,22 180,60 Q198,18 216,60 Q234,28 252,60 Q270,12 288,60 Q306,20 324,60 Q342,16 360,60 Q378,25 396,60 Q414,18 432,60 Q450,22 468,60 Q486,14 504,60 Q522,20 540,60 Q558,18 576,60 Q594,24 612,60 Q630,16 648,60 Q666,22 684,60 Q702,14 720,60 Q738,20 756,60 Q774,18 792,60 Q810,26 828,60 Q846,15 864,60 Q882,21 900,60 Q918,17 936,60 Q954,23 972,60 Q990,15 1008,60 Q1026,21 1044,60 Q1062,17 1080,60 Q1098,24 1116,60 Q1134,16 1152,60 Q1170,22 1188,60 Q1206,18 1224,60 Q1242,25 1260,60 Q1278,15 1296,60 Q1314,21 1332,60 Q1350,17 1368,60 Q1386,23 1404,60 Q1422,19 1440,60 L1440,140 Z"
fill="#0d1f0d" opacity="0.9"/>
</svg>
</div>
<!-- Layer 9: Near trees -->
<div class="plx-02__layer plx-02__trees-near" data-plx="0.94">
<svg viewBox="0 0 1440 110" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<path d="M-20,110 L-20,30 Q0,-10 20,30 Q40,-15 60,30 Q80,-8 100,30 Q120,-18 140,30 Q160,-10 180,30 Q200,-16 220,30 Q240,-5 260,30 Q280,-20 300,30 Q320,-12 340,30 Q360,-8 380,30 Q400,-18 420,30 Q440,-10 460,30 Q480,-14 500,30 Q520,-6 540,30 Q560,-20 580,30 Q600,-12 620,30 Q640,-8 660,30 Q680,-18 700,30 Q720,-10 740,30 Q760,-14 780,30 Q800,-6 820,30 Q840,-20 860,30 Q880,-12 900,30 Q920,-8 940,30 Q960,-18 980,30 Q1000,-10 1020,30 Q1040,-14 1060,30 Q1080,-6 1100,30 Q1120,-20 1140,30 Q1160,-12 1180,30 Q1200,-8 1220,30 Q1240,-18 1260,30 Q1280,-10 1300,30 Q1320,-14 1340,30 Q1360,-6 1380,30 Q1400,-20 1420,30 Q1440,-10 1460,30 L1460,110 Z"
fill="#0a160a"/>
</svg>
</div>
<!-- Layer 10: Ground -->
<div class="plx-02__ground"></div>
<!-- Content overlay -->
<div class="plx-02__overlay" data-plx="-0.06">
<h1 class="plx-02__title">
<em>The Last</em>
HORIZON
</h1>
<div class="plx-02__divider"></div>
<p class="plx-02__tagline">Five layers. One infinite depth.<br>Pure CSS parallax landscape.</p>
</div>
<!-- Layer depth indicator -->
<div class="plx-02__layers-ui">
<div class="plx-02__layer-dot" data-label="Stars"></div>
<div class="plx-02__layer-dot" data-label="Moon"></div>
<div class="plx-02__layer-dot" data-label="Clouds"></div>
<div class="plx-02__layer-dot" data-label="Far Mtns"></div>
<div class="plx-02__layer-dot" data-label="Mid Mtns"></div>
<div class="plx-02__layer-dot" data-label="Near Mtns"></div>
<div class="plx-02__layer-dot" data-label="Far Trees"></div>
<div class="plx-02__layer-dot" data-label="Near Trees"></div>
</div>
</div>
<!-- Below fold -->
<div class="plx-02__narrative">
<h2>Five Depths, One Horizon</h2>
<p>Each layer moves at its own pace — sky barely drifts, foreground trees rush by. The result is a pseudo-3D parallax landscape built entirely in CSS SVG layers, no canvas, no WebGL.</p>
</div>
</div> <div class="plx-02">
<div class="plx-02__scene">
<!-- Layer 0: Sky (fixed) -->
<div class="plx-02__sky"></div>
<!-- Layer 1: Stars — slowest -->
<div class="plx-02__stars" data-plx="0.08">
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<defs><radialGradient id="star"><stop offset="0%" stop-color="#fff"/><stop offset="100%" stop-color="transparent"/></radialGradient></defs>
<!-- scattered stars -->
<circle cx="8%" cy="12%" r="1.2" fill="#fff" opacity="0.9"/>
<circle cx="18%" cy="5%" r="0.8" fill="#fff" opacity="0.7"/>
<circle cx="27%" cy="18%" r="1" fill="#fff" opacity="0.85"/>
<circle cx="35%" cy="8%" r="1.5" fill="#ffd" opacity="0.95"/>
<circle cx="42%" cy="22%" r="0.7" fill="#fff" opacity="0.6"/>
<circle cx="55%" cy="6%" r="1.1" fill="#fff" opacity="0.8"/>
<circle cx="63%" cy="16%" r="0.9" fill="#fff" opacity="0.75"/>
<circle cx="71%" cy="4%" r="1.3" fill="#ffd" opacity="0.9"/>
<circle cx="80%" cy="14%" r="0.8" fill="#fff" opacity="0.65"/>
<circle cx="88%" cy="8%" r="1.0" fill="#fff" opacity="0.8"/>
<circle cx="93%" cy="22%" r="0.7" fill="#fff" opacity="0.55"/>
<circle cx="12%" cy="28%" r="0.6" fill="#fff" opacity="0.5"/>
<circle cx="48%" cy="32%" r="0.5" fill="#fff" opacity="0.4"/>
<circle cx="76%" cy="27%" r="0.8" fill="#fff" opacity="0.6"/>
</svg>
</div>
<!-- Layer 2: Moon -->
<div class="plx-02__moon" data-plx="0.12"></div>
<!-- Layer 3: Sun glow at horizon -->
<div class="plx-02__sun" data-plx="0.25"></div>
<!-- Layer 4: Clouds -->
<div class="plx-02__clouds" data-plx="0.18">
<div class="plx-02__cloud"></div>
<div class="plx-02__cloud"></div>
<div class="plx-02__cloud"></div>
<div class="plx-02__cloud"></div>
</div>
<!-- Layer 5: Far mountains -->
<div class="plx-02__layer plx-02__mtn-far" data-plx="0.35">
<svg viewBox="0 0 1440 300" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<path d="M0,300 L0,180 L60,130 L120,160 L200,80 L280,140 L360,70 L440,120 L520,50 L600,110 L680,40 L760,100 L840,55 L920,115 L1000,65 L1080,125 L1160,85 L1240,145 L1320,90 L1440,150 L1440,300 Z"
fill="#1e2d4a"/>
<path d="M0,300 L0,200 L80,155 L160,185 L240,115 L320,155 L400,95 L480,145 L560,75 L640,130 L720,65 L800,125 L880,80 L960,140 L1040,90 L1120,150 L1200,105 L1280,165 L1360,110 L1440,175 L1440,300 Z"
fill="#253566" opacity="0.6"/>
</svg>
</div>
<!-- Layer 6: Mid mountains -->
<div class="plx-02__layer plx-02__mtn-mid" data-plx="0.5">
<svg viewBox="0 0 1440 260" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<path d="M0,260 L0,160 L90,100 L180,140 L270,70 L360,120 L450,55 L540,105 L630,40 L720,95 L810,30 L900,90 L990,60 L1080,115 L1170,75 L1260,130 L1350,85 L1440,140 L1440,260 Z"
fill="#2a3d60"/>
<path d="M0,260 L0,190 L100,150 L200,175 L300,115 L400,155 L500,90 L600,140 L700,80 L800,130 L900,70 L1000,125 L1100,95 L1200,150 L1300,110 L1440,165 L1440,260 Z"
fill="#3a5278" opacity="0.7"/>
</svg>
</div>
<!-- Fog layers -->
<div class="plx-02__fog plx-02__fog--a" data-plx="0.6"></div>
<div class="plx-02__fog plx-02__fog--b" data-plx="0.65"></div>
<!-- Layer 7: Near mountains / hills -->
<div class="plx-02__layer plx-02__mtn-near" data-plx="0.7">
<svg viewBox="0 0 1440 220" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<path d="M0,220 L0,140 L120,80 L240,130 L360,60 L480,110 L600,45 L720,100 L840,35 L960,95 L1080,50 L1200,110 L1320,70 L1440,120 L1440,220 Z"
fill="#0d1a0d"/>
</svg>
</div>
<!-- Layer 8: Far trees -->
<div class="plx-02__layer plx-02__trees-far" data-plx="0.82">
<svg viewBox="0 0 1440 140" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<path d="M0,140 L0,60 Q18,20 36,60 Q54,20 72,60 Q90,25 108,60 Q126,15 144,60 Q162,22 180,60 Q198,18 216,60 Q234,28 252,60 Q270,12 288,60 Q306,20 324,60 Q342,16 360,60 Q378,25 396,60 Q414,18 432,60 Q450,22 468,60 Q486,14 504,60 Q522,20 540,60 Q558,18 576,60 Q594,24 612,60 Q630,16 648,60 Q666,22 684,60 Q702,14 720,60 Q738,20 756,60 Q774,18 792,60 Q810,26 828,60 Q846,15 864,60 Q882,21 900,60 Q918,17 936,60 Q954,23 972,60 Q990,15 1008,60 Q1026,21 1044,60 Q1062,17 1080,60 Q1098,24 1116,60 Q1134,16 1152,60 Q1170,22 1188,60 Q1206,18 1224,60 Q1242,25 1260,60 Q1278,15 1296,60 Q1314,21 1332,60 Q1350,17 1368,60 Q1386,23 1404,60 Q1422,19 1440,60 L1440,140 Z"
fill="#0d1f0d" opacity="0.9"/>
</svg>
</div>
<!-- Layer 9: Near trees -->
<div class="plx-02__layer plx-02__trees-near" data-plx="0.94">
<svg viewBox="0 0 1440 110" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<path d="M-20,110 L-20,30 Q0,-10 20,30 Q40,-15 60,30 Q80,-8 100,30 Q120,-18 140,30 Q160,-10 180,30 Q200,-16 220,30 Q240,-5 260,30 Q280,-20 300,30 Q320,-12 340,30 Q360,-8 380,30 Q400,-18 420,30 Q440,-10 460,30 Q480,-14 500,30 Q520,-6 540,30 Q560,-20 580,30 Q600,-12 620,30 Q640,-8 660,30 Q680,-18 700,30 Q720,-10 740,30 Q760,-14 780,30 Q800,-6 820,30 Q840,-20 860,30 Q880,-12 900,30 Q920,-8 940,30 Q960,-18 980,30 Q1000,-10 1020,30 Q1040,-14 1060,30 Q1080,-6 1100,30 Q1120,-20 1140,30 Q1160,-12 1180,30 Q1200,-8 1220,30 Q1240,-18 1260,30 Q1280,-10 1300,30 Q1320,-14 1340,30 Q1360,-6 1380,30 Q1400,-20 1420,30 Q1440,-10 1460,30 L1460,110 Z"
fill="#0a160a"/>
</svg>
</div>
<!-- Layer 10: Ground -->
<div class="plx-02__ground"></div>
<!-- Content overlay -->
<div class="plx-02__overlay" data-plx="-0.06">
<h1 class="plx-02__title">
<em>The Last</em>
HORIZON
</h1>
<div class="plx-02__divider"></div>
<p class="plx-02__tagline">Five layers. One infinite depth.<br>Pure CSS parallax landscape.</p>
</div>
<!-- Layer depth indicator -->
<div class="plx-02__layers-ui">
<div class="plx-02__layer-dot" data-label="Stars"></div>
<div class="plx-02__layer-dot" data-label="Moon"></div>
<div class="plx-02__layer-dot" data-label="Clouds"></div>
<div class="plx-02__layer-dot" data-label="Far Mtns"></div>
<div class="plx-02__layer-dot" data-label="Mid Mtns"></div>
<div class="plx-02__layer-dot" data-label="Near Mtns"></div>
<div class="plx-02__layer-dot" data-label="Far Trees"></div>
<div class="plx-02__layer-dot" data-label="Near Trees"></div>
</div>
</div>
<!-- Below fold -->
<div class="plx-02__narrative">
<h2>Five Depths, One Horizon</h2>
<p>Each layer moves at its own pace — sky barely drifts, foreground trees rush by. The result is a pseudo-3D parallax landscape built entirely in CSS SVG layers, no canvas, no WebGL.</p>
</div>
</div>*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
.plx-02 {
--sky-top: #0d1b3e;
--sky-mid: #1a2f5a;
--sky-low: #2d4a8a;
--horizon: #e85d2a;
--fog: #c4a97a;
--mt1: #1e2d4a;
--mt2: #2a3d60;
--mt3: #3a5278;
--tree: #0d1f0d;
--tree2: #112411;
--ground: #0a140a;
font-family: 'Lato', sans-serif;
background: var(--sky-top);
overflow-x: hidden;
}
/* ── Scene wrapper ── */
.plx-02__scene {
position: relative;
height: 100vh;
min-height: 600px;
overflow: hidden;
}
/* Each layer is absolutely positioned, full width */
.plx-02__layer {
position: absolute;
width: 100%;
bottom: 0;
will-change: transform;
}
/* Layer 0: Sky gradient */
.plx-02__sky {
inset: 0;
background: linear-gradient(
to bottom,
#040d20 0%,
#0d1b3e 25%,
#1a2f5a 50%,
#2d4a8a 70%,
#e85d2a 88%,
#f5a623 95%,
#ffd680 100%
);
position: absolute;
}
/* Stars */
.plx-02__stars {
position: absolute;
inset: 0 0 40% 0;
will-change: transform;
}
/* Moon */
.plx-02__moon {
position: absolute;
top: 8%;
right: 12%;
width: 60px;
height: 60px;
border-radius: 50%;
background: radial-gradient(circle at 35% 35%, #fff9e6, #f0d080);
box-shadow: 0 0 30px rgba(240,208,128,0.6), 0 0 80px rgba(240,208,128,0.2);
will-change: transform;
}
/* Sun/horizon glow.
Horizontal centering uses calc() on the left property instead
of transform: translateX(-50%) — this element carries data-plx
so the JS parallax handler clobbers style.transform with
translateY() on every scroll, which would erase the centering
and shift the sun to the right of the headline. */
.plx-02__sun {
position: absolute;
bottom: -30px;
left: calc(50% - 100px);
width: 200px;
height: 200px;
border-radius: 50%;
background: radial-gradient(circle, #ffd680 0%, #f5a623 30%, #e85d2a 60%, transparent 80%);
filter: blur(8px);
will-change: transform;
}
/* Cloud wisps */
.plx-02__clouds {
position: absolute;
inset: 15% 0 40% 0;
will-change: transform;
}
.plx-02__cloud {
position: absolute;
border-radius: 50px;
background: rgba(255,255,255,0.05);
filter: blur(6px);
}
.plx-02__cloud:nth-child(1) { width: 300px; height: 40px; top: 20%; left: 5%; }
.plx-02__cloud:nth-child(2) { width: 200px; height: 30px; top: 35%; left: 60%; background: rgba(255,200,100,0.08); }
.plx-02__cloud:nth-child(3) { width: 400px; height: 50px; top: 50%; left: 20%; }
.plx-02__cloud:nth-child(4) { width: 250px; height: 35px; top: 60%; left: 50%; background: rgba(255,150,50,0.1); }
/* Mountain layers — SVG inline */
.plx-02__mtn-far {
height: 45vh;
}
.plx-02__mtn-mid {
height: 38vh;
}
.plx-02__mtn-near {
height: 30vh;
}
/* Tree lines */
.plx-02__trees-far {
height: 22vh;
}
.plx-02__trees-near {
height: 16vh;
}
/* Ground */
.plx-02__ground {
height: 12vh;
background: linear-gradient(to bottom, #0a140a, #050a05);
position: absolute;
bottom: 0;
width: 100%;
}
/* Fog band */
.plx-02__fog {
position: absolute;
height: 100px;
width: 120%;
left: -10%;
background: linear-gradient(to bottom, transparent, rgba(196,169,122,0.18) 50%, transparent);
filter: blur(12px);
will-change: transform;
}
.plx-02__fog--a { bottom: 20%; }
.plx-02__fog--b { bottom: 12%; opacity: 0.6; }
/* ── Content overlay ── */
.plx-02__overlay {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 20;
text-align: center;
padding: 20px;
will-change: transform;
}
.plx-02__title {
font-family: 'Cinzel', serif;
font-size: clamp(40px, 9vw, 110px);
font-weight: 900;
color: #fff;
line-height: 0.9;
text-shadow:
0 0 40px rgba(232,93,42,0.5),
0 2px 60px rgba(0,0,0,0.8);
letter-spacing: 0.04em;
}
.plx-02__title em {
font-style: normal;
display: block;
font-size: 0.35em;
letter-spacing: 0.3em;
font-weight: 400;
color: rgba(255,214,128,0.85);
text-shadow: 0 0 20px rgba(245,166,35,0.6);
margin-bottom: 12px;
}
.plx-02__divider {
width: 80px;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(255,214,128,0.6), transparent);
margin: 24px auto;
}
.plx-02__tagline {
font-size: 13px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: rgba(255,255,255,0.5);
max-width: 380px;
line-height: 1.8;
}
/* ── Below-fold narrative ── */
.plx-02__narrative {
background: #050a05;
padding: 100px 40px;
text-align: center;
}
.plx-02__narrative h2 {
font-family: 'Cinzel', serif;
font-size: clamp(28px, 4vw, 48px);
color: #f0d080;
margin-bottom: 20px;
}
.plx-02__narrative p {
font-size: 15px;
line-height: 1.8;
color: rgba(255,255,255,0.45);
max-width: 600px;
margin: 0 auto;
}
/* Layer depth badges */
.plx-02__layers-ui {
position: absolute;
right: 24px;
top: 50%;
transform: translateY(-50%);
z-index: 30;
display: flex;
flex-direction: column;
gap: 8px;
}
.plx-02__layer-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: rgba(255,255,255,0.3);
cursor: default;
transition: all 0.3s;
position: relative;
}
.plx-02__layer-dot::after {
content: attr(data-label);
position: absolute;
right: 14px;
top: 50%;
transform: translateY(-50%);
font-size: 9px;
letter-spacing: 0.12em;
text-transform: uppercase;
color: rgba(255,255,255,0.4);
white-space: nowrap;
opacity: 0;
transition: opacity 0.3s;
}
.plx-02__layer-dot:hover {
background: rgba(245,166,35,0.9);
transform: scale(1.8);
}
.plx-02__layer-dot:hover::after { opacity: 1; }
@media (max-width: 600px) {
.plx-02__layers-ui { display: none; }
}
@media (prefers-reduced-motion: reduce) {
.plx-02__stars,
.plx-02__moon,
.plx-02__sun,
.plx-02__clouds,
.plx-02__mtn-far,
.plx-02__mtn-mid,
.plx-02__mtn-near,
.plx-02__trees-far,
.plx-02__trees-near,
.plx-02__fog,
.plx-02__overlay { transform: none !important; }
} *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
.plx-02 {
--sky-top: #0d1b3e;
--sky-mid: #1a2f5a;
--sky-low: #2d4a8a;
--horizon: #e85d2a;
--fog: #c4a97a;
--mt1: #1e2d4a;
--mt2: #2a3d60;
--mt3: #3a5278;
--tree: #0d1f0d;
--tree2: #112411;
--ground: #0a140a;
font-family: 'Lato', sans-serif;
background: var(--sky-top);
overflow-x: hidden;
}
/* ── Scene wrapper ── */
.plx-02__scene {
position: relative;
height: 100vh;
min-height: 600px;
overflow: hidden;
}
/* Each layer is absolutely positioned, full width */
.plx-02__layer {
position: absolute;
width: 100%;
bottom: 0;
will-change: transform;
}
/* Layer 0: Sky gradient */
.plx-02__sky {
inset: 0;
background: linear-gradient(
to bottom,
#040d20 0%,
#0d1b3e 25%,
#1a2f5a 50%,
#2d4a8a 70%,
#e85d2a 88%,
#f5a623 95%,
#ffd680 100%
);
position: absolute;
}
/* Stars */
.plx-02__stars {
position: absolute;
inset: 0 0 40% 0;
will-change: transform;
}
/* Moon */
.plx-02__moon {
position: absolute;
top: 8%;
right: 12%;
width: 60px;
height: 60px;
border-radius: 50%;
background: radial-gradient(circle at 35% 35%, #fff9e6, #f0d080);
box-shadow: 0 0 30px rgba(240,208,128,0.6), 0 0 80px rgba(240,208,128,0.2);
will-change: transform;
}
/* Sun/horizon glow.
Horizontal centering uses calc() on the left property instead
of transform: translateX(-50%) — this element carries data-plx
so the JS parallax handler clobbers style.transform with
translateY() on every scroll, which would erase the centering
and shift the sun to the right of the headline. */
.plx-02__sun {
position: absolute;
bottom: -30px;
left: calc(50% - 100px);
width: 200px;
height: 200px;
border-radius: 50%;
background: radial-gradient(circle, #ffd680 0%, #f5a623 30%, #e85d2a 60%, transparent 80%);
filter: blur(8px);
will-change: transform;
}
/* Cloud wisps */
.plx-02__clouds {
position: absolute;
inset: 15% 0 40% 0;
will-change: transform;
}
.plx-02__cloud {
position: absolute;
border-radius: 50px;
background: rgba(255,255,255,0.05);
filter: blur(6px);
}
.plx-02__cloud:nth-child(1) { width: 300px; height: 40px; top: 20%; left: 5%; }
.plx-02__cloud:nth-child(2) { width: 200px; height: 30px; top: 35%; left: 60%; background: rgba(255,200,100,0.08); }
.plx-02__cloud:nth-child(3) { width: 400px; height: 50px; top: 50%; left: 20%; }
.plx-02__cloud:nth-child(4) { width: 250px; height: 35px; top: 60%; left: 50%; background: rgba(255,150,50,0.1); }
/* Mountain layers — SVG inline */
.plx-02__mtn-far {
height: 45vh;
}
.plx-02__mtn-mid {
height: 38vh;
}
.plx-02__mtn-near {
height: 30vh;
}
/* Tree lines */
.plx-02__trees-far {
height: 22vh;
}
.plx-02__trees-near {
height: 16vh;
}
/* Ground */
.plx-02__ground {
height: 12vh;
background: linear-gradient(to bottom, #0a140a, #050a05);
position: absolute;
bottom: 0;
width: 100%;
}
/* Fog band */
.plx-02__fog {
position: absolute;
height: 100px;
width: 120%;
left: -10%;
background: linear-gradient(to bottom, transparent, rgba(196,169,122,0.18) 50%, transparent);
filter: blur(12px);
will-change: transform;
}
.plx-02__fog--a { bottom: 20%; }
.plx-02__fog--b { bottom: 12%; opacity: 0.6; }
/* ── Content overlay ── */
.plx-02__overlay {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 20;
text-align: center;
padding: 20px;
will-change: transform;
}
.plx-02__title {
font-family: 'Cinzel', serif;
font-size: clamp(40px, 9vw, 110px);
font-weight: 900;
color: #fff;
line-height: 0.9;
text-shadow:
0 0 40px rgba(232,93,42,0.5),
0 2px 60px rgba(0,0,0,0.8);
letter-spacing: 0.04em;
}
.plx-02__title em {
font-style: normal;
display: block;
font-size: 0.35em;
letter-spacing: 0.3em;
font-weight: 400;
color: rgba(255,214,128,0.85);
text-shadow: 0 0 20px rgba(245,166,35,0.6);
margin-bottom: 12px;
}
.plx-02__divider {
width: 80px;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(255,214,128,0.6), transparent);
margin: 24px auto;
}
.plx-02__tagline {
font-size: 13px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: rgba(255,255,255,0.5);
max-width: 380px;
line-height: 1.8;
}
/* ── Below-fold narrative ── */
.plx-02__narrative {
background: #050a05;
padding: 100px 40px;
text-align: center;
}
.plx-02__narrative h2 {
font-family: 'Cinzel', serif;
font-size: clamp(28px, 4vw, 48px);
color: #f0d080;
margin-bottom: 20px;
}
.plx-02__narrative p {
font-size: 15px;
line-height: 1.8;
color: rgba(255,255,255,0.45);
max-width: 600px;
margin: 0 auto;
}
/* Layer depth badges */
.plx-02__layers-ui {
position: absolute;
right: 24px;
top: 50%;
transform: translateY(-50%);
z-index: 30;
display: flex;
flex-direction: column;
gap: 8px;
}
.plx-02__layer-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: rgba(255,255,255,0.3);
cursor: default;
transition: all 0.3s;
position: relative;
}
.plx-02__layer-dot::after {
content: attr(data-label);
position: absolute;
right: 14px;
top: 50%;
transform: translateY(-50%);
font-size: 9px;
letter-spacing: 0.12em;
text-transform: uppercase;
color: rgba(255,255,255,0.4);
white-space: nowrap;
opacity: 0;
transition: opacity 0.3s;
}
.plx-02__layer-dot:hover {
background: rgba(245,166,35,0.9);
transform: scale(1.8);
}
.plx-02__layer-dot:hover::after { opacity: 1; }
@media (max-width: 600px) {
.plx-02__layers-ui { display: none; }
}
@media (prefers-reduced-motion: reduce) {
.plx-02__stars,
.plx-02__moon,
.plx-02__sun,
.plx-02__clouds,
.plx-02__mtn-far,
.plx-02__mtn-mid,
.plx-02__mtn-near,
.plx-02__trees-far,
.plx-02__trees-near,
.plx-02__fog,
.plx-02__overlay { transform: none !important; }
}(() => {
const root = document.querySelector('.plx-02');
if (!root) return;
const layers = Array.from(root.querySelectorAll('[data-plx]')).map(el => ({
el,
speed: parseFloat(el.dataset.plx)
}));
let ticking = false;
function onScroll() {
if (ticking) return;
ticking = true;
requestAnimationFrame(() => {
const sy = window.scrollY;
layers.forEach(({ el, speed }) => {
el.style.transform = `translateY(${sy * speed}px)`;
});
ticking = false;
});
}
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
})(); (() => {
const root = document.querySelector('.plx-02');
if (!root) return;
const layers = Array.from(root.querySelectorAll('[data-plx]')).map(el => ({
el,
speed: parseFloat(el.dataset.plx)
}));
let ticking = false;
function onScroll() {
if (ticking) return;
ticking = true;
requestAnimationFrame(() => {
const sy = window.scrollY;
layers.forEach(({ el, speed }) => {
el.style.transform = `translateY(${sy * speed}px)`;
});
ticking = false;
});
}
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
})();More from 10 CSS Parallax Effects
CSS Zoom-In / Depth Parallax on ScrollCSS Parallax Background Blur TransitionCSS Parallax Hero SectionCSS Sticky Parallax SectionsMulti-Scene Parallax ScrollingCSS Parallax Image Grid / GalleryCSS Horizontal Parallax ScrollCSS Parallax Text Overlay EffectCSS Parallax Card Hover Effect
View the full collection →