패럴랙스

Parallax

가까운 레이어는 빠르게, 먼 레이어는 느리게 움직여 화면에 깊이감을 만드는 기법. 배경·중경·전경의 속도를 다르게 줍니다.

다른 이름: 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);

스크롤량에 배율(예: 배경 0.2배, 중경 0.5배, 전경 1배)을 곱해 각 레이어의 이동 거리를 계산합니다. 배율이 1에 가까울수록 화면과 같은 속도로, 0에 가까울수록 거의 정지한 것처럼 멀게 느껴집니다.

CSS만으로는 background-attachment: fixed 정도가 한계라 실무에서는 스크롤 이벤트(또는 IntersectionObserver)로 각 레이어의 transform을 갱신합니다. 레이어가 많으면 스크롤 프레임이 버벅일 수 있어, will-change와 transform만 쓰고 레이아웃 속성은 건드리지 않는 게 안전합니다.

카드 미리보기는 스크롤할 수 없어서, 이 데모는 스크롤 대신 카메라가 지나가는 것처럼 레이어를 계속 움직입니다.

언제 쓰나

히어로 섹션 한 번 정도로 아껴 쓰세요. 페이지 전체에 남발하면 멀미(모션 시크니스)를 유발할 수 있습니다.