...
CSS Scroll snap
CSS Scroll snap은 웹 페이지에서 스크롤을 할 때, 요소가 스크롤되는 위치에 자동으로 스냅되도록 하는 CSS 속성이다.
예를들어 용자가 웹 페이지를 스크롤할 때 중간에 멈춰버리면 콘텐츠의 중간에서 멈춰 주요 콘텐츠의 일부만 보이게 되는데, 이를 미리 설정한 위치로 자동 스냅하여 자연스러운 스크롤 움직임과 함께 사용자 경험을 더욱 향상시키는 것이다.
스크롤 스냅이 없던 시절에는 자바스크립트로 일일히 요소 위치를 계산해서 조정해야 됬지만, CSS 속성을 통해 공식 지원함으로써 개발의 편리함과 더불어 성능도 비약적으로 상승했다고 볼 수 있다.
Scroll snap 사용법
우선 스크롤 스냅을 적용할 부모 컨테이너 영역을 만들고, 그 안에 스냅될 자식 요소 영역을 만들어 준다. 그리고 부모에 scroll-snap-type 속성과 자식에 scroll-snap-align 속성을 적용해주면 된다. (이들 속성에 대해서는 아래 자세히 다룬다)
<div class="scroll-container">
<div class="scroll-area">1</div>
<div class="scroll-area">2</div>
<div class="scroll-area">3</div>
<div class="scroll-area">4</div>
</div>
/* 부모 스크롤 스냅 컨테이너 */
.scroll-container {
overflow: auto;
scroll-snap-type: y mandatory; /* y 축 방향으로만 scroll snap 적용 */
}
/* 자식 스크롤 스냅 영역 */
.scroll-area {
scroll-snap-align: start; /* 스크롤 위치 맞춤 */
}
/* 여기서부턴 단순 꾸미기 --------------------------- */
.scroll-area:nth-of-type(1) {
background: #49b293;
}
.scroll-area:nth-of-type(2) {
background: #c94e4b;
}
.scroll-area:nth-of-type(3) {
background: #4cc1be;
}
.scroll-area:nth-of-type(4) {
background: #8360A6;
}
See the Pen Scroll Snap Demo by Envato Tuts+ (@tutsplus) on CodePen.
Scroll snap 속성
Scroll snap에는 사용할 수 있는 4 가지 속성이 있다.
- scroll-snap-type
- scroll-snap-align
- scroll-padding
- scroll-margin
아래의 CSS 예시는 다음 HTML 엘리먼트 구성을 기준으로 설명한다.
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
scroll-snap-type
scroll-snap-type 속성은 스크롤 스냅이 동작하는 방식을 지정한다. 첫 번째 인자로 스냅이 적용될 축을 지정하고, 두 번째 인자로 스냅 적용 방식을 지정한다.
.container {
scroll-snap-type : [scroll snap axis], [scroll snap strictness];
}
/* y 방향으로 스크롤 스냅을 적용 */
.container {
scroll-snap-type: y mandatory;
}
/* x 방향으로 스크롤 스냅을 적용 */
.container {
scroll-snap-type: x proximity;
}
[ scroll snap axis ]
- x: 수평(가로) 축으로 snap position 지정
- y: 수직(세로) 축으로 snap position 지정
- block: snap area의 block 축으로 지정
- inline: inline 축으로 지정
- both: 두 축의 위치를 개별적으로 스냅.
[ scroll snap strictness ]
- none: 스냅하지 않음.
- proximity: 스크롤 위치가 스냅 위치에 가까워지면 자연스럽게 스냅
- mandatory: 스크롤 위치가 스냅 위치와 정확히 일치해야만 스냅
scroll-snap-type 속성 값을 mandatory 로 선언 시 주의할점은, 콘텐츠 간의 간격이 넓을 때 강제로 스냅을 하게 되면 중간 콘텐츠를 건너뛰고 다음 콘텐츠로 이동하는 경우가 발생할 수 있다는 점이다.
See the Pen scroll snap by barzz12 (@inpaSkyrim) on CodePen.
scroll-snap-align
scroll-snap-align 속성은 스크롤 스냅이 적용되는 요소가 스냅 위치에 정렬되는 방식을 지정한다. scroll-snap-type에서 지정한 축을 기준으로 snap area의 정렬을 정한다.
- none: snap position을 지정하지 않음
- start: 스크롤 스냅 위치를 snap area 시작 부분에 맞추도록 지정
- end: 스크롤 스냅 위치를 snap area의 끝 부분에 맞추도록 지정
- center: 스크롤 스냅 위치를 snap area의 가운데 부분에 맞추도록 지정
/* 스냅 위치에 맞춰 요소 시작 부분을 정렬 */
.item {
scroll-snap-align: start;
}
/* 스냅 위치에 맞춰 요소 중앙 부분을 정렬 */
.item {
scroll-snap-align: center;
}
/* 스냅 위치에 맞춰 요소 끝 부분을 정렬 */
.item {
scroll-snap-align: end;
}
scroll-padding
scroll-padding 속성은 스크롤 영역의 패딩(padding)을 조정하는 속성이다. 이 속성을 사용하면 스크롤 스냅이 적용되는 영역을 확보할 수 있다.
정말로 요소의 padding 값이 변경되는 것이 아니고, 해당 뷰 포트(viewport)의 가짜 padding이 적용되는 것이다.
/* 스크롤 영역 위/아래로 패딩 100px 추가 */
.container {
scroll-snap-type: y mandatory;
scroll-padding: 100px 0 100px 0; /* `scroll-padding-top`, `scroll-padding-right`, `scroll-padding-bottom`, `scroll-padding-left` */
}
/* 스크롤 영역 상/하/좌/우 모두에 패딩 50px 추가 */
.container {
scroll-snap-type: y mandatory;
scroll-padding: 50px;
}
scroll-margin
scroll-padding 과 마찬가지로 뷰 포트의 가짜 margin 영역을 지정하는 속성이다.
/* 스크롤 스냅이 적용되는 영역의 상/하/좌/우 마진을 100px로 지정 */
.container {
scroll-margin: 100px; /* `scroll-margin-top`, `scroll-margin-right`, `scroll-margin-bottom`, `scroll-margin-left` */
}
/* 스크롤 스냅이 적용되는 영역의 상/하 마진을 50px, 좌/우 마진을 100px로 지정 */
.container {
scroll-margin: 50px 100px;
}
이러한 scroll-padding , scroll-margin 속성을 응용하자면, 이전 혹은 다음 콘텐츠에 대한 예상 시나리오를 사용자에게 제공할 수 있다.
scroll-snap-stop
scroll-snap-stop 속성은 스크롤 스냅 위치에 도달했을 때 스크롤을 중지할 지 여부를 지정한다.
- normal: 스크롤이 스냅되더라도 계속 진행될 수 있음
- always: 스크롤이 스냅 위치에 도달하면 중지
/* 스크롤 스냅이 요소의 끝에서 중단되도록 지정 */
.item {
scroll-snap-stop: always;
}
/* 스크롤 스냅이 요소의 중앙에서만 중단되도록 지정 */
.item {
scroll-snap-stop: normal;
}
# 참고자료
https://wit.nts-corp.com/2018/08/28/5317
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Scroll_Snap
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.