10 CSS Parallax Effects 10 / 10
CSS Parallax Background Blur Transition
Scroll drives backdrop-filter: blur from 0 to 28px on a vivid blob hero, while a frosted-glass card rises and fades in — pure CSS filter parallax.
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-10">
<div class="plx-10__badge" id="plx10-badge">BLUR · 0px</div>
<!-- Hero -->
<div class="plx-10__hero" id="plx10-hero">
<div class="plx-10__hero-sticky">
<!-- Vivid color blobs -->
<div class="plx-10__blobs" id="plx10-blobs">
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
</div>
<!-- Medium blur duplicate (fades in mid-scroll) -->
<div class="plx-10__blobs-blur" id="plx10-blur1">
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
</div>
<!-- Heavy blur duplicate (fades in late) -->
<div class="plx-10__blobs-blur2" id="plx10-blur2">
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
</div>
<!-- Dark overlay for contrast -->
<div class="plx-10__dark-overlay" id="plx10-dark"></div>
<!-- Initial headline (fades out) -->
<div class="plx-10__hero-headline" id="plx10-hl">
<span class="plx-10__hero-tag">Parallax · Background Blur Transition</span>
<h1 class="plx-10__hero-h">Focus<br>through<br><em>motion.</em></h1>
<p class="plx-10__hero-sub">Scroll to blur the world. The color field beneath you fades from vivid to frosted glass as you descend.</p>
<div class="plx-10__scroll-hint">
<div class="plx-10__scroll-line"></div>
<span>Scroll</span>
</div>
</div>
<!-- Frosted glass card (fades in) -->
<div class="plx-10__glass-wrap" id="plx10-glass">
<div class="plx-10__glass-card">
<span class="plx-10__card-tag">Glassmorphism · Blur Parallax</span>
<h2 class="plx-10__card-h">The world<br>went <em>soft.</em></h2>
<div class="plx-10__card-line"></div>
<p class="plx-10__card-p">The same color field that lived beneath the headline has blurred into this frosted surface. Depth through diffusion — a parallax story told in focus.</p>
</div>
</div>
</div>
</div>
<!-- Content sections -->
<div class="plx-10__sections">
<div class="plx-10__section">
<div class="plx-10__sec-visual">
<div class="plx-10__sec-visual-inner" id="plx10-v1"></div>
<div class="plx-10__sec-reveal"><span>Depth revealed</span></div>
</div>
<div class="plx-10__sec-body">
<span class="plx-10__sec-tag">01 / Concept</span>
<h2 class="plx-10__sec-h">Blur as <em>distance.</em></h2>
<div class="plx-10__sec-line"></div>
<p class="plx-10__sec-p">The further something is from the focal plane, the softer it becomes. Parallax blur recreates this optical truth — objects you've scrolled past recede into soft focus.</p>
</div>
</div>
<div class="plx-10__section">
<div class="plx-10__sec-visual">
<div class="plx-10__sec-visual-inner" id="plx10-v2"></div>
<div class="plx-10__sec-reveal"><span>Color diffused</span></div>
</div>
<div class="plx-10__sec-body">
<span class="plx-10__sec-tag">02 / Technique</span>
<h2 class="plx-10__sec-h">Glass over <em>color.</em></h2>
<div class="plx-10__sec-line"></div>
<p class="plx-10__sec-p">Two versions of the same color field — one sharp, one blurred — cross-fade as you scroll. The transition is driven by opacity, not filters, keeping performance smooth on any device.</p>
</div>
</div>
<div class="plx-10__section">
<div class="plx-10__sec-visual">
<div class="plx-10__sec-visual-inner" id="plx10-v3"></div>
<div class="plx-10__sec-reveal"><span>Depth in motion</span></div>
</div>
<div class="plx-10__sec-body">
<span class="plx-10__sec-tag">03 / Effect</span>
<h2 class="plx-10__sec-h">Parallax through <em>focus.</em></h2>
<div class="plx-10__sec-line"></div>
<p class="plx-10__sec-p">The background images inside these panels scroll at 0.35× the page speed, creating the sensation that the content floats in front of a deeper layer. Scroll depth as spatial poetry.</p>
</div>
</div>
</div>
</div> <div class="plx-10">
<div class="plx-10__badge" id="plx10-badge">BLUR · 0px</div>
<!-- Hero -->
<div class="plx-10__hero" id="plx10-hero">
<div class="plx-10__hero-sticky">
<!-- Vivid color blobs -->
<div class="plx-10__blobs" id="plx10-blobs">
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
</div>
<!-- Medium blur duplicate (fades in mid-scroll) -->
<div class="plx-10__blobs-blur" id="plx10-blur1">
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
</div>
<!-- Heavy blur duplicate (fades in late) -->
<div class="plx-10__blobs-blur2" id="plx10-blur2">
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
<div class="plx-10__blob"></div>
</div>
<!-- Dark overlay for contrast -->
<div class="plx-10__dark-overlay" id="plx10-dark"></div>
<!-- Initial headline (fades out) -->
<div class="plx-10__hero-headline" id="plx10-hl">
<span class="plx-10__hero-tag">Parallax · Background Blur Transition</span>
<h1 class="plx-10__hero-h">Focus<br>through<br><em>motion.</em></h1>
<p class="plx-10__hero-sub">Scroll to blur the world. The color field beneath you fades from vivid to frosted glass as you descend.</p>
<div class="plx-10__scroll-hint">
<div class="plx-10__scroll-line"></div>
<span>Scroll</span>
</div>
</div>
<!-- Frosted glass card (fades in) -->
<div class="plx-10__glass-wrap" id="plx10-glass">
<div class="plx-10__glass-card">
<span class="plx-10__card-tag">Glassmorphism · Blur Parallax</span>
<h2 class="plx-10__card-h">The world<br>went <em>soft.</em></h2>
<div class="plx-10__card-line"></div>
<p class="plx-10__card-p">The same color field that lived beneath the headline has blurred into this frosted surface. Depth through diffusion — a parallax story told in focus.</p>
</div>
</div>
</div>
</div>
<!-- Content sections -->
<div class="plx-10__sections">
<div class="plx-10__section">
<div class="plx-10__sec-visual">
<div class="plx-10__sec-visual-inner" id="plx10-v1"></div>
<div class="plx-10__sec-reveal"><span>Depth revealed</span></div>
</div>
<div class="plx-10__sec-body">
<span class="plx-10__sec-tag">01 / Concept</span>
<h2 class="plx-10__sec-h">Blur as <em>distance.</em></h2>
<div class="plx-10__sec-line"></div>
<p class="plx-10__sec-p">The further something is from the focal plane, the softer it becomes. Parallax blur recreates this optical truth — objects you've scrolled past recede into soft focus.</p>
</div>
</div>
<div class="plx-10__section">
<div class="plx-10__sec-visual">
<div class="plx-10__sec-visual-inner" id="plx10-v2"></div>
<div class="plx-10__sec-reveal"><span>Color diffused</span></div>
</div>
<div class="plx-10__sec-body">
<span class="plx-10__sec-tag">02 / Technique</span>
<h2 class="plx-10__sec-h">Glass over <em>color.</em></h2>
<div class="plx-10__sec-line"></div>
<p class="plx-10__sec-p">Two versions of the same color field — one sharp, one blurred — cross-fade as you scroll. The transition is driven by opacity, not filters, keeping performance smooth on any device.</p>
</div>
</div>
<div class="plx-10__section">
<div class="plx-10__sec-visual">
<div class="plx-10__sec-visual-inner" id="plx10-v3"></div>
<div class="plx-10__sec-reveal"><span>Depth in motion</span></div>
</div>
<div class="plx-10__sec-body">
<span class="plx-10__sec-tag">03 / Effect</span>
<h2 class="plx-10__sec-h">Parallax through <em>focus.</em></h2>
<div class="plx-10__sec-line"></div>
<p class="plx-10__sec-p">The background images inside these panels scroll at 0.35× the page speed, creating the sensation that the content floats in front of a deeper layer. Scroll depth as spatial poetry.</p>
</div>
</div>
</div>
</div>.plx-10, .plx-10 *, .plx-10 *::before, .plx-10 *::after {
box-sizing: border-box; margin: 0; padding: 0;
}
.plx-10 {
--bg: #07080e;
--text: #eff2f8;
--accent: #92c5f0;
--warm: #e8c88a;
font-family: 'Cormorant Garamond', serif;
background: var(--bg);
color: var(--text);
/* overflow-x:hidden was breaking position:sticky on descendants —
same root cause as Demo 09 (commit 876bc78). overflow:clip is
the modern equivalent: prevents horizontal overflow without
creating a scroll context that would steal sticky containment
from the body. Chrome 90+, Safari 16+, Firefox 81+. */
overflow-x: clip;
}
/* ═══ HERO: vivid color field blurs as you scroll ═══ */
.plx-10__hero {
position: relative;
height: 250vh;
}
.plx-10__hero-sticky {
position: sticky;
top: 0;
height: 100vh;
overflow: hidden;
}
/* The vivid color blobs — this layer parallaxes */
.plx-10__blobs {
position: absolute;
inset: -20%;
will-change: transform;
}
.plx-10__blob {
position: absolute;
border-radius: 50%;
filter: blur(70px);
}
.plx-10__blob:nth-child(1) {
width: 60vw; height: 60vw;
top: -15%; left: -10%;
background: radial-gradient(circle, rgba(80,150,255,0.6) 0%, transparent 70%);
}
.plx-10__blob:nth-child(2) {
width: 50vw; height: 50vw;
top: 20%; right: -5%;
background: radial-gradient(circle, rgba(180,80,255,0.55) 0%, transparent 70%);
}
.plx-10__blob:nth-child(3) {
width: 45vw; height: 45vw;
bottom: -5%; left: 30%;
background: radial-gradient(circle, rgba(255,130,80,0.5) 0%, transparent 70%);
}
.plx-10__blob:nth-child(4) {
width: 35vw; height: 35vw;
top: 50%; left: 15%;
background: radial-gradient(circle, rgba(80,240,180,0.35) 0%, transparent 70%);
}
/* The frosted overlay — its opacity and filter change with scroll */
/* IMPORTANT: we use a solid semi-opaque overlay that increases,
NOT backdrop-filter (which doesn't work on parent bg) */
.plx-10__frost-overlay {
position: absolute;
inset: 0;
z-index: 2;
background: linear-gradient(
160deg,
rgba(7, 8, 14, 0) 0%,
rgba(7, 8, 14, 0) 100%
);
will-change: opacity;
opacity: 0;
/* We'll use a canvas-style blur by adding a blurred duplicate via a pseudo */
}
/* The blurred version of the blobs — initially invisible, fades in */
.plx-10__blobs-blur {
position: absolute;
inset: -20%;
will-change: transform, opacity, filter;
opacity: 0;
filter: blur(0px);
}
.plx-10__blobs-blur .plx-10__blob:nth-child(1) {
width: 60vw; height: 60vw;
top: -15%; left: -10%;
background: radial-gradient(circle, rgba(80,150,255,0.6) 0%, transparent 70%);
filter: blur(70px);
}
.plx-10__blobs-blur .plx-10__blob:nth-child(2) {
width: 50vw; height: 50vw;
top: 20%; right: -5%;
background: radial-gradient(circle, rgba(180,80,255,0.55) 0%, transparent 70%);
filter: blur(70px);
}
.plx-10__blobs-blur .plx-10__blob:nth-child(3) {
width: 45vw; height: 45vw;
bottom: -5%; left: 30%;
background: radial-gradient(circle, rgba(255,130,80,0.5) 0%, transparent 70%);
filter: blur(70px);
}
.plx-10__blobs-blur .plx-10__blob:nth-child(4) {
width: 35vw; height: 35vw;
top: 50%; left: 15%;
background: radial-gradient(circle, rgba(80,240,180,0.35) 0%, transparent 70%);
filter: blur(70px);
}
/* Additional extra-blur layer at full blur */
.plx-10__blobs-blur2 {
position: absolute;
inset: -20%;
will-change: transform, opacity, filter;
opacity: 0;
}
.plx-10__blobs-blur2 .plx-10__blob:nth-child(1) {
width: 70vw; height: 70vw;
top: -20%; left: -15%;
background: radial-gradient(circle, rgba(80,150,255,0.5) 0%, transparent 70%);
filter: blur(140px);
}
.plx-10__blobs-blur2 .plx-10__blob:nth-child(2) {
width: 60vw; height: 60vw;
top: 15%; right: -10%;
background: radial-gradient(circle, rgba(180,80,255,0.45) 0%, transparent 70%);
filter: blur(120px);
}
.plx-10__blobs-blur2 .plx-10__blob:nth-child(3) {
width: 55vw; height: 55vw;
bottom: -10%; left: 25%;
background: radial-gradient(circle, rgba(255,130,80,0.4) 0%, transparent 70%);
filter: blur(130px);
}
/* Dark overlay accumulates */
.plx-10__dark-overlay {
position: absolute;
inset: 0;
z-index: 3;
background: var(--bg);
will-change: opacity;
opacity: 0;
}
/* Glass card that fades in on top */
.plx-10__glass-wrap {
position: absolute;
inset: 0;
z-index: 5;
display: flex;
align-items: center;
justify-content: center;
will-change: opacity, transform;
opacity: 0;
transform: translateY(30px);
}
.plx-10__glass-card {
background: rgba(255,255,255,0.07);
border: 1px solid rgba(255,255,255,0.14);
border-radius: 20px;
padding: 56px 64px;
max-width: 560px;
text-align: center;
box-shadow: 0 32px 80px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.12);
position: relative;
overflow: hidden;
}
.plx-10__glass-card::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, rgba(255,255,255,0.04) 0%, transparent 60%);
pointer-events: none;
}
.plx-10__card-tag {
font-family: 'DM Mono', monospace;
font-size: 9px;
letter-spacing: 0.35em;
text-transform: uppercase;
color: var(--accent);
opacity: 0.7;
display: block;
margin-bottom: 20px;
}
.plx-10__card-h {
font-size: clamp(36px, 5vw, 64px);
font-weight: 600;
line-height: 1.05;
margin-bottom: 20px;
}
.plx-10__card-h em {
font-style: italic;
font-weight: 300;
color: var(--accent);
}
.plx-10__card-p {
font-size: 17px;
font-weight: 300;
font-style: italic;
line-height: 1.7;
color: rgba(239,242,248,0.6);
}
.plx-10__card-line {
width: 40px;
height: 1px;
background: rgba(146,197,240,0.4);
margin: 24px auto;
}
/* Blur strength badge */
.plx-10__badge {
position: fixed;
top: 20px;
right: 20px;
z-index: 100;
font-family: 'DM Mono', monospace;
font-size: 10px;
letter-spacing: 0.2em;
color: var(--accent);
opacity: 0.6;
background: rgba(7,8,14,0.7);
padding: 6px 12px;
border: 1px solid rgba(146,197,240,0.2);
border-radius: 4px;
pointer-events: none;
}
/* Hero initial headline (fades out as blur comes in) */
.plx-10__hero-headline {
position: absolute;
inset: 0;
z-index: 4;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 40px;
will-change: opacity, transform;
pointer-events: none;
}
.plx-10__hero-tag {
font-family: 'DM Mono', monospace;
font-size: 10px;
letter-spacing: 0.3em;
text-transform: uppercase;
color: rgba(239,242,248,0.4);
margin-bottom: 24px;
display: block;
}
.plx-10__hero-h {
font-size: clamp(52px, 12vw, 160px);
font-weight: 600;
line-height: 0.92;
letter-spacing: -0.02em;
}
.plx-10__hero-h em {
font-style: italic;
font-weight: 300;
color: rgba(239,242,248,0.6);
}
.plx-10__hero-sub {
margin-top: 24px;
font-size: 16px;
font-style: italic;
font-weight: 300;
color: rgba(239,242,248,0.45);
max-width: 420px;
}
.plx-10__scroll-hint {
margin-top: 40px;
font-family: 'DM Mono', monospace;
font-size: 9px;
letter-spacing: 0.3em;
text-transform: uppercase;
color: rgba(239,242,248,0.25);
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.plx-10__scroll-line {
width: 1px; height: 44px;
background: linear-gradient(to bottom, rgba(239,242,248,0.3), transparent);
animation: plx-10-line 1.8s ease-in-out infinite;
}
@keyframes plx-10-line {
0%, 100% { opacity: 1; transform: scaleY(1); transform-origin: top; }
50% { opacity: 0.3; transform: scaleY(0.4); transform-origin: top; }
}
/* ═══ CONTENT SECTIONS below hero ═══ */
.plx-10__sections {
background: var(--bg);
}
.plx-10__section {
position: relative;
min-height: 80vh;
padding: 100px 5vw;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 60px;
align-items: center;
border-top: 1px solid rgba(255,255,255,0.06);
overflow: hidden;
}
.plx-10__section:nth-child(even) {
direction: rtl;
}
.plx-10__section:nth-child(even) > * { direction: ltr; }
.plx-10__sec-visual {
position: relative;
aspect-ratio: 4/3;
border-radius: 12px;
overflow: hidden;
}
.plx-10__sec-visual-inner {
position: absolute;
inset: -15%;
will-change: transform;
transform-origin: center;
border-radius: 16px;
}
.plx-10__section:nth-child(1) .plx-10__sec-visual-inner {
background: radial-gradient(ellipse at 40% 50%, rgba(80,150,255,0.45) 0%, rgba(7,8,14,0.9) 65%);
}
.plx-10__section:nth-child(2) .plx-10__sec-visual-inner {
background: radial-gradient(ellipse at 55% 40%, rgba(180,80,255,0.45) 0%, rgba(7,8,14,0.9) 65%);
}
.plx-10__section:nth-child(3) .plx-10__sec-visual-inner {
background: radial-gradient(ellipse at 50% 60%, rgba(255,130,80,0.45) 0%, rgba(7,8,14,0.9) 65%);
}
/* Hover blur reveal on section visuals */
.plx-10__sec-reveal {
position: absolute;
inset: 0;
background: rgba(7,8,14,0.6);
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.4s;
}
.plx-10__sec-visual:hover .plx-10__sec-reveal { opacity: 1; }
.plx-10__sec-reveal span {
font-size: clamp(20px, 3vw, 36px);
font-weight: 600;
font-style: italic;
color: var(--accent);
}
.plx-10__sec-body {}
.plx-10__sec-tag {
font-family: 'DM Mono', monospace;
font-size: 9px;
letter-spacing: 0.3em;
text-transform: uppercase;
color: var(--accent);
opacity: 0.6;
margin-bottom: 16px;
display: block;
}
.plx-10__sec-h {
font-size: clamp(32px, 4.5vw, 60px);
font-weight: 600;
line-height: 1.05;
margin-bottom: 20px;
}
.plx-10__sec-h em { font-style: italic; font-weight: 300; color: rgba(239,242,248,0.7); }
.plx-10__sec-p {
font-size: 16px;
font-weight: 300;
font-style: italic;
line-height: 1.8;
color: rgba(239,242,248,0.45);
max-width: 400px;
}
.plx-10__sec-line {
width: 48px; height: 1px;
background: rgba(146,197,240,0.3);
margin: 20px 0;
}
@media (max-width: 768px) {
.plx-10__section { grid-template-columns: 1fr; direction: ltr !important; }
.plx-10__glass-card { padding: 36px 28px; }
}
@media (prefers-reduced-motion: reduce) {
.plx-10__blobs, .plx-10__blobs-blur, .plx-10__blobs-blur2 { transform: none !important; }
.plx-10__scroll-line { animation: none; }
.plx-10__sec-visual-inner { transform: none !important; }
} .plx-10, .plx-10 *, .plx-10 *::before, .plx-10 *::after {
box-sizing: border-box; margin: 0; padding: 0;
}
.plx-10 {
--bg: #07080e;
--text: #eff2f8;
--accent: #92c5f0;
--warm: #e8c88a;
font-family: 'Cormorant Garamond', serif;
background: var(--bg);
color: var(--text);
/* overflow-x:hidden was breaking position:sticky on descendants —
same root cause as Demo 09 (commit 876bc78). overflow:clip is
the modern equivalent: prevents horizontal overflow without
creating a scroll context that would steal sticky containment
from the body. Chrome 90+, Safari 16+, Firefox 81+. */
overflow-x: clip;
}
/* ═══ HERO: vivid color field blurs as you scroll ═══ */
.plx-10__hero {
position: relative;
height: 250vh;
}
.plx-10__hero-sticky {
position: sticky;
top: 0;
height: 100vh;
overflow: hidden;
}
/* The vivid color blobs — this layer parallaxes */
.plx-10__blobs {
position: absolute;
inset: -20%;
will-change: transform;
}
.plx-10__blob {
position: absolute;
border-radius: 50%;
filter: blur(70px);
}
.plx-10__blob:nth-child(1) {
width: 60vw; height: 60vw;
top: -15%; left: -10%;
background: radial-gradient(circle, rgba(80,150,255,0.6) 0%, transparent 70%);
}
.plx-10__blob:nth-child(2) {
width: 50vw; height: 50vw;
top: 20%; right: -5%;
background: radial-gradient(circle, rgba(180,80,255,0.55) 0%, transparent 70%);
}
.plx-10__blob:nth-child(3) {
width: 45vw; height: 45vw;
bottom: -5%; left: 30%;
background: radial-gradient(circle, rgba(255,130,80,0.5) 0%, transparent 70%);
}
.plx-10__blob:nth-child(4) {
width: 35vw; height: 35vw;
top: 50%; left: 15%;
background: radial-gradient(circle, rgba(80,240,180,0.35) 0%, transparent 70%);
}
/* The frosted overlay — its opacity and filter change with scroll */
/* IMPORTANT: we use a solid semi-opaque overlay that increases,
NOT backdrop-filter (which doesn't work on parent bg) */
.plx-10__frost-overlay {
position: absolute;
inset: 0;
z-index: 2;
background: linear-gradient(
160deg,
rgba(7, 8, 14, 0) 0%,
rgba(7, 8, 14, 0) 100%
);
will-change: opacity;
opacity: 0;
/* We'll use a canvas-style blur by adding a blurred duplicate via a pseudo */
}
/* The blurred version of the blobs — initially invisible, fades in */
.plx-10__blobs-blur {
position: absolute;
inset: -20%;
will-change: transform, opacity, filter;
opacity: 0;
filter: blur(0px);
}
.plx-10__blobs-blur .plx-10__blob:nth-child(1) {
width: 60vw; height: 60vw;
top: -15%; left: -10%;
background: radial-gradient(circle, rgba(80,150,255,0.6) 0%, transparent 70%);
filter: blur(70px);
}
.plx-10__blobs-blur .plx-10__blob:nth-child(2) {
width: 50vw; height: 50vw;
top: 20%; right: -5%;
background: radial-gradient(circle, rgba(180,80,255,0.55) 0%, transparent 70%);
filter: blur(70px);
}
.plx-10__blobs-blur .plx-10__blob:nth-child(3) {
width: 45vw; height: 45vw;
bottom: -5%; left: 30%;
background: radial-gradient(circle, rgba(255,130,80,0.5) 0%, transparent 70%);
filter: blur(70px);
}
.plx-10__blobs-blur .plx-10__blob:nth-child(4) {
width: 35vw; height: 35vw;
top: 50%; left: 15%;
background: radial-gradient(circle, rgba(80,240,180,0.35) 0%, transparent 70%);
filter: blur(70px);
}
/* Additional extra-blur layer at full blur */
.plx-10__blobs-blur2 {
position: absolute;
inset: -20%;
will-change: transform, opacity, filter;
opacity: 0;
}
.plx-10__blobs-blur2 .plx-10__blob:nth-child(1) {
width: 70vw; height: 70vw;
top: -20%; left: -15%;
background: radial-gradient(circle, rgba(80,150,255,0.5) 0%, transparent 70%);
filter: blur(140px);
}
.plx-10__blobs-blur2 .plx-10__blob:nth-child(2) {
width: 60vw; height: 60vw;
top: 15%; right: -10%;
background: radial-gradient(circle, rgba(180,80,255,0.45) 0%, transparent 70%);
filter: blur(120px);
}
.plx-10__blobs-blur2 .plx-10__blob:nth-child(3) {
width: 55vw; height: 55vw;
bottom: -10%; left: 25%;
background: radial-gradient(circle, rgba(255,130,80,0.4) 0%, transparent 70%);
filter: blur(130px);
}
/* Dark overlay accumulates */
.plx-10__dark-overlay {
position: absolute;
inset: 0;
z-index: 3;
background: var(--bg);
will-change: opacity;
opacity: 0;
}
/* Glass card that fades in on top */
.plx-10__glass-wrap {
position: absolute;
inset: 0;
z-index: 5;
display: flex;
align-items: center;
justify-content: center;
will-change: opacity, transform;
opacity: 0;
transform: translateY(30px);
}
.plx-10__glass-card {
background: rgba(255,255,255,0.07);
border: 1px solid rgba(255,255,255,0.14);
border-radius: 20px;
padding: 56px 64px;
max-width: 560px;
text-align: center;
box-shadow: 0 32px 80px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.12);
position: relative;
overflow: hidden;
}
.plx-10__glass-card::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, rgba(255,255,255,0.04) 0%, transparent 60%);
pointer-events: none;
}
.plx-10__card-tag {
font-family: 'DM Mono', monospace;
font-size: 9px;
letter-spacing: 0.35em;
text-transform: uppercase;
color: var(--accent);
opacity: 0.7;
display: block;
margin-bottom: 20px;
}
.plx-10__card-h {
font-size: clamp(36px, 5vw, 64px);
font-weight: 600;
line-height: 1.05;
margin-bottom: 20px;
}
.plx-10__card-h em {
font-style: italic;
font-weight: 300;
color: var(--accent);
}
.plx-10__card-p {
font-size: 17px;
font-weight: 300;
font-style: italic;
line-height: 1.7;
color: rgba(239,242,248,0.6);
}
.plx-10__card-line {
width: 40px;
height: 1px;
background: rgba(146,197,240,0.4);
margin: 24px auto;
}
/* Blur strength badge */
.plx-10__badge {
position: fixed;
top: 20px;
right: 20px;
z-index: 100;
font-family: 'DM Mono', monospace;
font-size: 10px;
letter-spacing: 0.2em;
color: var(--accent);
opacity: 0.6;
background: rgba(7,8,14,0.7);
padding: 6px 12px;
border: 1px solid rgba(146,197,240,0.2);
border-radius: 4px;
pointer-events: none;
}
/* Hero initial headline (fades out as blur comes in) */
.plx-10__hero-headline {
position: absolute;
inset: 0;
z-index: 4;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 40px;
will-change: opacity, transform;
pointer-events: none;
}
.plx-10__hero-tag {
font-family: 'DM Mono', monospace;
font-size: 10px;
letter-spacing: 0.3em;
text-transform: uppercase;
color: rgba(239,242,248,0.4);
margin-bottom: 24px;
display: block;
}
.plx-10__hero-h {
font-size: clamp(52px, 12vw, 160px);
font-weight: 600;
line-height: 0.92;
letter-spacing: -0.02em;
}
.plx-10__hero-h em {
font-style: italic;
font-weight: 300;
color: rgba(239,242,248,0.6);
}
.plx-10__hero-sub {
margin-top: 24px;
font-size: 16px;
font-style: italic;
font-weight: 300;
color: rgba(239,242,248,0.45);
max-width: 420px;
}
.plx-10__scroll-hint {
margin-top: 40px;
font-family: 'DM Mono', monospace;
font-size: 9px;
letter-spacing: 0.3em;
text-transform: uppercase;
color: rgba(239,242,248,0.25);
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.plx-10__scroll-line {
width: 1px; height: 44px;
background: linear-gradient(to bottom, rgba(239,242,248,0.3), transparent);
animation: plx-10-line 1.8s ease-in-out infinite;
}
@keyframes plx-10-line {
0%, 100% { opacity: 1; transform: scaleY(1); transform-origin: top; }
50% { opacity: 0.3; transform: scaleY(0.4); transform-origin: top; }
}
/* ═══ CONTENT SECTIONS below hero ═══ */
.plx-10__sections {
background: var(--bg);
}
.plx-10__section {
position: relative;
min-height: 80vh;
padding: 100px 5vw;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 60px;
align-items: center;
border-top: 1px solid rgba(255,255,255,0.06);
overflow: hidden;
}
.plx-10__section:nth-child(even) {
direction: rtl;
}
.plx-10__section:nth-child(even) > * { direction: ltr; }
.plx-10__sec-visual {
position: relative;
aspect-ratio: 4/3;
border-radius: 12px;
overflow: hidden;
}
.plx-10__sec-visual-inner {
position: absolute;
inset: -15%;
will-change: transform;
transform-origin: center;
border-radius: 16px;
}
.plx-10__section:nth-child(1) .plx-10__sec-visual-inner {
background: radial-gradient(ellipse at 40% 50%, rgba(80,150,255,0.45) 0%, rgba(7,8,14,0.9) 65%);
}
.plx-10__section:nth-child(2) .plx-10__sec-visual-inner {
background: radial-gradient(ellipse at 55% 40%, rgba(180,80,255,0.45) 0%, rgba(7,8,14,0.9) 65%);
}
.plx-10__section:nth-child(3) .plx-10__sec-visual-inner {
background: radial-gradient(ellipse at 50% 60%, rgba(255,130,80,0.45) 0%, rgba(7,8,14,0.9) 65%);
}
/* Hover blur reveal on section visuals */
.plx-10__sec-reveal {
position: absolute;
inset: 0;
background: rgba(7,8,14,0.6);
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.4s;
}
.plx-10__sec-visual:hover .plx-10__sec-reveal { opacity: 1; }
.plx-10__sec-reveal span {
font-size: clamp(20px, 3vw, 36px);
font-weight: 600;
font-style: italic;
color: var(--accent);
}
.plx-10__sec-body {}
.plx-10__sec-tag {
font-family: 'DM Mono', monospace;
font-size: 9px;
letter-spacing: 0.3em;
text-transform: uppercase;
color: var(--accent);
opacity: 0.6;
margin-bottom: 16px;
display: block;
}
.plx-10__sec-h {
font-size: clamp(32px, 4.5vw, 60px);
font-weight: 600;
line-height: 1.05;
margin-bottom: 20px;
}
.plx-10__sec-h em { font-style: italic; font-weight: 300; color: rgba(239,242,248,0.7); }
.plx-10__sec-p {
font-size: 16px;
font-weight: 300;
font-style: italic;
line-height: 1.8;
color: rgba(239,242,248,0.45);
max-width: 400px;
}
.plx-10__sec-line {
width: 48px; height: 1px;
background: rgba(146,197,240,0.3);
margin: 20px 0;
}
@media (max-width: 768px) {
.plx-10__section { grid-template-columns: 1fr; direction: ltr !important; }
.plx-10__glass-card { padding: 36px 28px; }
}
@media (prefers-reduced-motion: reduce) {
.plx-10__blobs, .plx-10__blobs-blur, .plx-10__blobs-blur2 { transform: none !important; }
.plx-10__scroll-line { animation: none; }
.plx-10__sec-visual-inner { transform: none !important; }
}(() => {
const hero = document.getElementById('plx10-hero');
const blobs = document.getElementById('plx10-blobs');
const blur1 = document.getElementById('plx10-blur1');
const blur2 = document.getElementById('plx10-blur2');
const dark = document.getElementById('plx10-dark');
const hl = document.getElementById('plx10-hl');
const glass = document.getElementById('plx10-glass');
const badge = document.getElementById('plx10-badge');
const secVisuals = [
{ el: document.getElementById('plx10-v1'), speed: 0.35 },
{ el: document.getElementById('plx10-v2'), speed: 0.3 },
{ el: document.getElementById('plx10-v3'), speed: 0.32 },
];
if (!hero) return;
let ticking = false;
function prog(el) {
const r = el.getBoundingClientRect();
const h = el.offsetHeight - window.innerHeight;
return h > 0 ? Math.max(0, Math.min(1, -r.top / h)) : 0;
}
function onScroll() {
if (ticking) return;
ticking = true;
requestAnimationFrame(() => {
const p = prog(hero);
const vh = window.innerHeight;
// Blobs parallax downward (bg layer moves slower)
if (blobs) blobs.style.transform = `translateY(${p * -80}px)`;
if (blur1) blur1.style.transform = `translateY(${p * -80}px)`;
if (blur2) blur2.style.transform = `translateY(${p * -80}px)`;
// Cross-fade from sharp → medium blur → heavy blur
// Phase 1 (0→0.4): sharp visible, blur1 fades in
// Phase 2 (0.4→0.8): blur1 fades in fully, blur2 starts
// Phase 3 (0.7→1.0): glass card rises
const blur1Alpha = Math.max(0, Math.min(1, p / 0.45));
const blur2Alpha = Math.max(0, Math.min(1, (p - 0.35) / 0.35));
const darkAlpha = Math.max(0, Math.min(0.55, (p - 0.4) / 0.4 * 0.55));
const hlAlpha = Math.max(0, Math.min(1, 1 - p / 0.5));
const glassAlpha = Math.max(0, Math.min(1, (p - 0.6) / 0.3));
const glassY = (1 - Math.min(1, (p - 0.6) / 0.3)) * 30;
// Approximate blur in px for badge
const blurPx = Math.round(blur2Alpha * 28 + blur1Alpha * 14);
if (blur1) blur1.style.opacity = String(blur1Alpha);
if (blur2) blur2.style.opacity = String(blur2Alpha);
if (dark) dark.style.opacity = String(darkAlpha);
if (hl) {
hl.style.opacity = String(hlAlpha);
hl.style.transform = `translateY(${p * -20}px)`;
}
if (glass) {
glass.style.opacity = String(glassAlpha);
glass.style.transform = `translateY(${glassY}px)`;
}
if (badge) badge.textContent = `BLUR · ${blurPx}px`;
// Section visuals parallax
secVisuals.forEach(({ el, speed }) => {
if (!el) return;
const parent = el.closest('.plx-10__sec-visual');
if (!parent) return;
const r = parent.getBoundingClientRect();
if (r.bottom < -100 || r.top > vh + 100) return;
const centerOffset = (r.top + r.height / 2) - vh / 2;
el.style.transform = `translateY(${centerOffset * speed * -0.5}px) scale(1.3)`;
});
ticking = false;
});
}
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
})(); (() => {
const hero = document.getElementById('plx10-hero');
const blobs = document.getElementById('plx10-blobs');
const blur1 = document.getElementById('plx10-blur1');
const blur2 = document.getElementById('plx10-blur2');
const dark = document.getElementById('plx10-dark');
const hl = document.getElementById('plx10-hl');
const glass = document.getElementById('plx10-glass');
const badge = document.getElementById('plx10-badge');
const secVisuals = [
{ el: document.getElementById('plx10-v1'), speed: 0.35 },
{ el: document.getElementById('plx10-v2'), speed: 0.3 },
{ el: document.getElementById('plx10-v3'), speed: 0.32 },
];
if (!hero) return;
let ticking = false;
function prog(el) {
const r = el.getBoundingClientRect();
const h = el.offsetHeight - window.innerHeight;
return h > 0 ? Math.max(0, Math.min(1, -r.top / h)) : 0;
}
function onScroll() {
if (ticking) return;
ticking = true;
requestAnimationFrame(() => {
const p = prog(hero);
const vh = window.innerHeight;
// Blobs parallax downward (bg layer moves slower)
if (blobs) blobs.style.transform = `translateY(${p * -80}px)`;
if (blur1) blur1.style.transform = `translateY(${p * -80}px)`;
if (blur2) blur2.style.transform = `translateY(${p * -80}px)`;
// Cross-fade from sharp → medium blur → heavy blur
// Phase 1 (0→0.4): sharp visible, blur1 fades in
// Phase 2 (0.4→0.8): blur1 fades in fully, blur2 starts
// Phase 3 (0.7→1.0): glass card rises
const blur1Alpha = Math.max(0, Math.min(1, p / 0.45));
const blur2Alpha = Math.max(0, Math.min(1, (p - 0.35) / 0.35));
const darkAlpha = Math.max(0, Math.min(0.55, (p - 0.4) / 0.4 * 0.55));
const hlAlpha = Math.max(0, Math.min(1, 1 - p / 0.5));
const glassAlpha = Math.max(0, Math.min(1, (p - 0.6) / 0.3));
const glassY = (1 - Math.min(1, (p - 0.6) / 0.3)) * 30;
// Approximate blur in px for badge
const blurPx = Math.round(blur2Alpha * 28 + blur1Alpha * 14);
if (blur1) blur1.style.opacity = String(blur1Alpha);
if (blur2) blur2.style.opacity = String(blur2Alpha);
if (dark) dark.style.opacity = String(darkAlpha);
if (hl) {
hl.style.opacity = String(hlAlpha);
hl.style.transform = `translateY(${p * -20}px)`;
}
if (glass) {
glass.style.opacity = String(glassAlpha);
glass.style.transform = `translateY(${glassY}px)`;
}
if (badge) badge.textContent = `BLUR · ${blurPx}px`;
// Section visuals parallax
secVisuals.forEach(({ el, speed }) => {
if (!el) return;
const parent = el.closest('.plx-10__sec-visual');
if (!parent) return;
const r = parent.getBoundingClientRect();
if (r.bottom < -100 || r.top > vh + 100) return;
const centerOffset = (r.top + r.height / 2) - vh / 2;
el.style.transform = `translateY(${centerOffset * speed * -0.5}px) scale(1.3)`;
});
ticking = false;
});
}
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
})();More from 10 CSS Parallax Effects
CSS Parallax Hero SectionMulti-layered CSS Parallax Landscape / IllustrationCSS Sticky Parallax SectionsMulti-Scene Parallax ScrollingCSS Parallax Image Grid / GalleryCSS Horizontal Parallax ScrollCSS Parallax Text Overlay EffectCSS Parallax Card Hover EffectCSS Zoom-In / Depth Parallax on Scroll
View the full collection →