[CSS] Pure CSS Parallax Websites
Parallax는 거의 JavaScript를 사용하여 처리되며, scroll 이벤트를 통하여 이벤트 핸들러에서 직접 DOM을 직접 수정하여 불필요한 reflows
와 paints
를 발생시킨다.
따라서, 브라우저 렌더링 파이프라인과 동기화되지 않은 상태에서 발생하여 프레임이 손실되고 버벅거린다.
그러나 모두 부정적인 것만은 아니다, requestAnimationFrame
, DOM 업데이트의 지연은 parallax websites 을 긍정적으로 바꿀 수 있다.
결과적으로는, 만약 JavaScript의 의존성을 완전히 제거할 수 있다면 어떨까?
parallax effect
를CSS
로 구현하면, 모든 문제가 해소되고 브라우저가 hardware acceleration 을 이용할 수 있기 때문에 compositor가 모든 것을 처리할 수 있게된다. 그 결과, 프레임 rate가 일정하고, 스크롤이 매우 부드러워진다.
The theory
html
<div class="parallax">
<div class="parallax__layer parallax__layer--back">
<div class="title">This is the "back" background</div>
</div>
<div class="parallax__layer parallax__layer--base">
<div class="title">This is the "base" background</div>
</div>
</div>
css
* {
margin: 0;
padding: 0;
}
.parallax {
perspective: 1px;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
font-size: 200%;
}
.parallax__layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 100vh 0;
}
.parallax__layer--base {
transform: translateZ(0);
}
.parallax__layer--back {
transform: translateZ(-1px);
}
.title {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.parallax
<div class="parallax">
<div class="parallax__layer parallax__layer--back">
<div class="title">This is the "back" background</div>
</div>
<div class="parallax__layer parallax__layer--base">
<div class="title">This is the "base" background</div>
</div>
</div>
* {
margin: 0;
padding: 0;
}
.parallax {
perspective: 1px;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
font-size: 200%;
}
.parallax__layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 100vh 0;
}
.parallax__layer--base {
transform: translateZ(0);
}
.parallax__layer--back {
transform: translateZ(-1px);
}
.title {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
parallax
class 는 parallex magic 이 발생하는 곳이다.
height
와 perspective
를 정의하면, 원근범이 중심에 잠기므로 고정된 원점 3D 뷰포트가 생성된다.
overflow-y: auto
를 설정하면 요소 내부의 콘텐츠를 일반적인 방법으로 스크롤할 수 있지만, 하위 요소는 고정된 시점을 기준으로 렌더링된다. 이것이 parallax 효과를 만드는 핵심이다.
.parallax__layer
이름에서 알 수 있듯이 parallax 효과가 적용되는 콘텐츠의 레이어를 정의한다. 콘텐츠 흐름에서 요소를 꺼내 컨테이너의 공간을 채우도록 설정한다.
.parallax__layer--base & .parallax__layer--back
parallax 요소를 Z축을 따라 변환하여 (parallax 요소를 더 멀리 이동하거나 뷰포트에 더 가깝게 이동) parallax 요소의 스크롤 속도를 결정하는 데 사용된다. 간략하게 하기 위해 2개의 레이어 속도만 정의했다. 추후에 더 추가할 예정이다.
결과물을 살펴보면, "back" background font size가 줄어든 것처럼 보인다. 이처럼 3D 변환을 사용하면 요소의 크기가 변경되는 것처럼 보이는 부작용이 발생한다.
Depth correction 내용을 보며 이 문제를 해결해보자.
Depth correction
parallax 효과는 3D 변환을 사용하여 생성되므로 요소를 Z축을 따라 변환하면 뷰포트에 더 가까이 또는 더 멀리 이동하면 요소의 유효 크기가 변경되는 부작용이 있다. 이를 방지하기 위해서는 원래 크기로 렌더링되도록 요소에 scale() 변환을 적용해야 한다.
.parallax__layer--back {
transform: translateZ(-1px) scale(2);
}
scale
은 1 + (translateZ * -1) / perspective
으로 계산할 수 있다. 예를 들어 viewport perspective
을 1px로 설정하고 Z축을 따라 요소 -2px
를 변환하면 scale 계수는 3이 된다.
Controlling layer speed
Layer 속도는 perspective 과 Z 변환값의 조합에 의해 제어된다다. 음의 Z 값을 가진 요소는 양의 값을 가진 요소보다 느리게 스크롤된다. 값이 0
에서 멀어질수록 Parallax 효과가 두드러진다. (즉, translateZ(-10px)
는 translateZ(-1px)
보다 느리게 스크롤된다).
Parallax sections
앞의 예에서는 매우 간단한 내용을 사용하여 기본적인 기술을 설명했지만, 대부분의 Parallax 사이트는 페이지를 다른 효과를 적용할 수 있는 개별 섹션으로 나눈다. 방법은 아래와 같다.
먼저 layers
를 그룹화하기 위한 parallax__group
요소가 필요하다.
<div class="parallax">
<div class="parallax__group">
<div class="parallax__layer parallax__layer--back">
...
</div>
<div class="parallax__layer parallax__layer--base">
...
</div>
</div>
<div class="parallax__group">
...
</div>
</div>
.parallax__group {
position: relative;
height: 100vh;
transform-style: preserve-3d;
}
이 예에서는 각 그룹이 뷰포트를 채우고 높이를 100vh로 설정하지만 필요에 따라 각 그룹에 임의의 값을 설정할 수 있다.
transform-style: preserve-3d
는 브라우저가 parallax_layer
요소와 위치를 평평하게 하는 것을 방지한다. position: relative
는 자식 parallax_layer
요소를 그룹에 상대적으로 배치하기 위해 사용된다.
요소를 그룹화할 때 기억해야 할 중요한 규칙 중 하나는 그룹의 내용을 클리핑할 수 없다는 것이다.
parallax__group
에 overflow: hidden
을 적용하면 Parallax 효과가 사라진다. 클리핑되지 않은 콘텐츠는 하위 요소가 넘치게 되므로 방문자가 문서를 스크롤할 때 콘텐츠가 올바르게 표시/숨겨지도록 그룹의 z-index
값을 창의적으로 사용해야 한다.
설계마다 구현이 다르기 때문에 계층화에 대한 명확한 규칙은 없다. Parallax 효과가 어떻게 작동하는지 알 수 있다면 계층화 문제를 디버깅하는 것이 훨씬 쉽다. 그룹 요소에 간단한 변환을 적용하면 이 작업을 수행할 수 있다.
.parallax__group {
transform: translate3d(700px, 0, -800px) rotateY(30deg);
}
Example - debug option
https://keithclark.co.uk/articles/pure-css-parallax-websites/demo3/
개발자 도구 > Layers
https://keithclark.co.uk/articles/pure-css-parallax-websites/demo3/
디버깅을 할 때, 개발자 도구를 열어서 Layers
를 클릭하여 들어가서 확인해보면 더 정확하 게 디버깅을 할 때 도움이 될 것 같다.
오류 해결
웹킷 기반 브라우저는 3D 공간으로 변환되고 확장되면서 요소의 유효 폭을 올바르게 계산하지 못하는 것이다. 이 버그로 인해 사용자는 overflow
속성으로 정의된 조건을 무시하고 콘텐츠를 가로로 스크롤할 수 있다. transform-origin
및 perspective-origin
을 뷰포트 오른쪽에 고정함으로써 이 오류를 회피할 수 있다.
.parallax {
perspective-origin-x: 100%;
}
.parallax__layer {
transform-origin-x: 100%;
}
REFERENCE
https://keithclark.co.uk/articles/pure-css-parallax-websites/
Author And Source
이 문제에 관하여([CSS] Pure CSS Parallax Websites), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@godud2604/CSS-Pure-CSS-Parallax-Websites저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)