CSS Scroll snap points 알아보기

Posted by in Research

Safari에서만 사용할 수 있던 Scroll snap 모듈이 9월 4일 릴리즈되는 Chrome 69부터 지원합니다.

배경

Scroll snap 모듈을 사용하면 사용자가 터치, 휠 스크롤 조작을 마쳤을 때의 오프셋을 설정할 수 있습니다.

스크롤링은 사용자와 웹 콘텐츠간의 자연스러운 인터랙션이지만
정밀도가 부족하여 콘텐츠의 중간에서 멈추거나 주요 콘텐츠의 일부만 보이기도 합니다.
하지만 미리 설정한 위치로 이동한다면 자연스러운 스크롤 움직임과 함께 사용자 경험은 더욱 향상될 수 있습니다.
CSS Scroll snap 모듈을 사용하면 스크롤 동작을 정의하기 위한 JavaScript 사용을 줄일 수 있고,
하드웨어 가속을 사용하기 때문에 웹 브라우저에서 원활한 동작과 성능 향상을 기대할 수 있습니다.

이해

Scroll Container는 Scroll snap 동작이 발생하는 영역을 의미합니다.
사용자가 터치, 휠 마우스를 조작하여 스크롤링하면 Scroll Container에서 Scroll snap이 동작합니다.
그림에서처럼 scrollport/snapport와 동일한 경우가 대부분이지만,
특정 속성(scroll-padding)을 선언하면 scrollport/snapport의 위치는 조정될 수 있습니다.

Scroll Container 내부의 각 요소는 snap area입니다.
스크롤링 시 타겟이 되는 오브젝트이며, snap area에 snap position을 지정할 수 있습니다.
빨간 점선으로 표시된 부분은 스크롤 조작을 마친 후 Scroll Container(scrollport/snapport)의 snap position입니다.

다음은 Scroll snap을 적용하기 전/후의 화면입니다.

적용 전

적용 후

비교해보면,
Scroll snap을 적용한 화면은 부드럽게 다음 컨텐츠로 이동합니다.
Scroll Snap Demo 에서 직접 확인할 수 있는데,
현재 Scroll snap은 Safari 브라우저에서만 지원 하고 있습니다!

활용

[ ! ]  W3C CR::CSS Scroll Snap Module Level 1 기준으로 작성하였습니다.

Scroll snap에 사용할 수 있는 네 가지 속성입니다.

  • scroll-snap-type
  • scroll-snap-align
  • scroll-padding
  • scroll-margin

scroll-snap-type

snap position을 지정할 수 있는 축을 결정하는 Scroll Snap Axis, 스냅의 엄격도를 지정하는 Scroll Snap Strictness 를 함께 선언합니다.

scroll snap axis

  • x: 수평(가로) 축으로 snap position 지정
  • y: 수직(세로) 축으로 snap position 지정
  • block: snap area의 block 축으로 지정
  • inline: inline 축으로 지정
  • both: 두 축의 위치를 개별적으로 스냅. 잠재적으로 각 축의 다른 요소에 스냅이 가능.

scroll snap strictness

  • none: 스냅하지 않음.
  • proximity: snap position을 지정하였다면 해당 설정에 맞춰 스냅하고, 미지정 상태라면 유저 에이전트에 따릅니다.
  • mandatory: 항상 스냅.

엄격도는 지정하지 않을 경우 proximity로 설정된다

scroll-snap-align

snap position은 snap area 안에서 원하는 정렬 방식을 설정할 수 있습니다.
scroll-snap-type에서 지정한 축을 기준으로 snap area의 정렬을 정합니다.

  • none: snap position을 지정하지 않음
  • start: 축을 기준으로 snap area의 시작 부분에 맞춰 정렬
  • end: snap area의 끝에 맞춰 정렬
  • center: snap area의 가운데에 맞춰 정렬

scroll-padding

Scroll Container에 선언하지만, 해당 요소의 padding 값이 변경되는 것이 아니고, 해당 뷰포트의 padding이 적용됩니다.
Scroll Contatiner에 선언한 수치만큼 snapport가 조정되기 때문에 스크롤 할 수 있는 영역이 줄어들고
레이아웃, 스크롤 원점, 요소의 위치, 실제로 보여지는 것에는 영향을 주지 않습니다.

다음의 CSS를 적용해봤습니다.

scroll-margin

스냅 타겟이 되는 snap area에 지정하며, scroll-padding과 동일하게 실제 요소에 영향을 미치지 않습니다.

다음의 CSS 적용했습니다. 두번째 상자에만 적용

scroll-paddingscroll-margin을 활용하면 이전 혹은 다음 콘텐츠에 대한 예상 시나리오를 사용자에게 제공할 수 있습니다.

참고 사항

  • scroll-snap-type mandatory 값 선언 시 주의
    콘텐츠 간의 간격이 넓을 때 강제로 스냅을 하게 되면 중간 콘텐츠를 건너뛰고 다음 콘텐츠로 이동하는 경우가 발생하니 주의해야합니다.
  • Scroll snap 사용 시, 신뢰할 수 없는 scroll-snap-type 속성이 아닌 확실한 속성으로 지원 여부를 검증하세요.

지원

IE, Edge, Firefox는 구 버전의 사양을 제공하고 있지만,
Safari, Chrome 69부터는 Scroll snap points를 W3C CR(Candidate Recommendation, 후보권고안)에 맞춰 제공합니다.
Chrome 69 이후에도 키보드 스크롤링, 네비게이션 활용, 부드러운 애니메이션, 관련한 devTools 기능 등에 대한 개선을 준비중이라고 합니다.
Scroll snap 모듈에 대한 브라우저 지원이 안정되면 터치 장치에서 특히 유용할 것으로 기대됩니다.

감사합니다!

참고 자료