Parallax

패럴랙스

Moving near layers fast and far layers slow to fake depth — background, midground and foreground scroll at different speeds.

Also known as: Parallax scrolling
···
html
<div class="scene">
  <div class="layer far"></div>
  <div class="layer mid"></div>
  <div class="layer near"></div>
  <div class="ground"></div>
</div>
css
.scene{position:absolute;inset:0;overflow:hidden}
.layer{position:absolute;left:0;right:0;background-repeat:repeat-x}
.far{top:0;height:55%;opacity:.45;
  background-image:radial-gradient(circle at 10% 80%, var(--accent) 0 26px, transparent 27px),
    radial-gradient(circle at 45% 70%, var(--accent) 0 34px, transparent 35px),
    radial-gradient(circle at 80% 85%, var(--accent) 0 20px, transparent 21px);
  background-size:260px 100%}
.mid{top:30%;height:50%;opacity:.7;
  background-image:radial-gradient(circle at 20% 60%, var(--accent-2) 0 20px, transparent 21px),
    radial-gradient(circle at 65% 50%, var(--accent-2) 0 30px, transparent 31px);
  background-size:200px 100%}
.near{bottom:0;height:34%;
  background-image:linear-gradient(180deg, transparent 40%, var(--accent-3) 40%);
  background-size:120px 100%}
.ground{position:absolute;left:0;right:0;bottom:0;height:10%;background:var(--surface);border-top:1px solid var(--line)}
js
const far = document.querySelector('.far');
const mid = document.querySelector('.mid');
const near = document.querySelector('.near');
let x = 0;
function loop() {
  x += 1;
  far.style.backgroundPositionX = (-x * 0.2) + 'px';
  mid.style.backgroundPositionX = (-x * 0.5) + 'px';
  near.style.backgroundPositionX = (-x * 1) + 'px';
  requestAnimationFrame(loop);
}
requestAnimationFrame(loop);

You multiply scroll distance by a per-layer factor (say background ×0.2, midground ×0.5, foreground ×1) to get how far each layer moves. Closer to 1 tracks the screen; closer to 0 barely moves, reading as distant.

CSS alone only gets you background-attachment: fixed, so in practice you update each layer's transform from a scroll listener (or IntersectionObserver). With many layers this can jank the scroll frame, so stick to transform only — never layout properties like top or margin.

Since a card preview can't be scrolled, this demo moves the layers on its own, like a camera panning through the scene, instead of waiting for scroll input.

When to use

Save it for a single hero section. Overusing it across a whole page can trigger motion sickness.