CSS 스크롤 스냅 모듈 레벨 1

W3C 후보 권고 스냅샷,

이 버전:
https://www.w3.org/TR/2021/CR-css-scroll-snap-1-20210311/
최신 공개 버전:
https://www.w3.org/TR/css-scroll-snap-1/
에디터스 드래프트:
https://drafts.csswg.org/css-scroll-snap-1/
이전 버전:
구현 보고서:
https://wpt.fyi/results/css/css-scroll-snap
테스트 스위트:
http://test.csswg.org/suites/css-scroll-snap-1_dev/nightly-unstable/
이슈 추적:
CSSWG 이슈 저장소
에디터:
Matt Rakow (Microsoft)
Jacob Rossi (Microsoft)
Tab Atkins-Bittner (Google)
Elika J. Etemad / fantasai (초청 전문가)
이 명세에 대한 편집 제안:
GitHub 에디터

요약

이 모듈은 “스냅 위치”를 통해 패닝 및 스크롤 동작을 제어하는 기능을 포함합니다.

CSS는 구조화된 문서(HTML과 XML 등)의 렌더링을 화면, 인쇄물 등에서 기술하는 언어입니다.

이 문서의 상태

이 섹션은 이 문서가 출판된 시점의 상태를 설명합니다. 다른 문서가 이 문서를 대체할 수 있습니다. 현재 W3C 발행물 목록과 이 기술 보고서의 최신 버전은 W3C 기술 보고서 색인 https://www.w3.org/TR/에서 확인할 수 있습니다.

이 문서는 CSS 작업 그룹에서 후보 권고 스냅샷으로 발행되었습니다. 후보 권고로 발행되었다고 해서 W3C 회원의 지지를 의미하지는 않습니다. 후보 권고 스냅샷은 폭넓은 검토를 받았으며 구현 경험을 수집하기 위한 목적입니다. 이 문서는 W3C 권고가 될 예정이며, 추가 피드백을 수집하기 위해 최소 까지 후보 권고 상태로 유지됩니다.

피드백은 GitHub에 이슈를 등록하여 보내주시기 바랍니다(권장). 제목에 명세 코드 "css-scroll-snap"을 포함하여, 다음과 같이 작성해 주세요: “[css-scroll-snap] …의견 요약…”. 모든 이슈와 의견은 아카이브에 저장됩니다. 또는 피드백은 (아카이브됨) 공개 메일링 리스트 www-style@w3.org로 보낼 수 있습니다.

이 문서는 2020년 9월 15일 W3C 프로세스 문서에 따라 관리됩니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성되었습니다. W3C는 그룹 산출물과 관련하여 제출된 특허 공개의 공개 목록을 유지합니다; 해당 페이지에는 특허 공개 방법도 포함되어 있습니다. 개별적으로 특허에 대한 실제 지식을 갖고 있고, 그 특허가 필수 청구항을 포함한다고 믿는 경우, W3C 특허 정책 6절에 따라 정보를 공개해야 합니다.

테스트 스위트와 구현 보고서는 CR 기간 동안 제작됩니다.

다음 기능은 위험에 처해 있으며, CR 기간 동안 제외될 수 있습니다:

“위험에 처함(At-risk)”은 W3C 프로세스의 용어로, 해당 기능이 반드시 제외되거나 지연될 위험이 있음을 의미하는 것은 아닙니다. 이는 WG가 기능이 상호 운용적으로 신속하게 구현되기 어려울 수 있다고 판단하며, 이렇게 표시함으로써 향후 제안 권고(Proposed Rec) 단계로 전환할 때 해당 기능을 필요하다면 제외할 수 있고, 기능이 없는 새로운 후보 권고를 다시 발행하지 않아도 되도록 하기 위함입니다.

1. 소개

이 섹션은 규범적이지 않습니다.

스크롤 가능한 콘텐츠를 위한 인기 있는 UX 패러다임은 종종 콘텐츠를 페이징하거나 논리적 구역으로 나누는 방식을 사용합니다. 특히 터치 인터랙션의 경우, 사용자가 계층 구조를 탭해 탐색하는 것보다 평면적으로 배치된 많은 콘텐츠를 빠르게 패닝하는 것이 더 빠르고 쉽습니다. 예를 들어, 사용자는 앨범에서 각각의 사진을 탭하여 보는 것보다 사진 슬라이드쇼 뷰를 패닝하여 여러 사진을 보는 것이 더 쉽습니다.

하지만 터치 패닝이나 마우스 휠 스크롤과 같은 스크롤 입력의 부정확한 특성 때문에, 웹 개발자가 스크롤 경험을 잘 제어하기란 어렵습니다. 특히 콘텐츠를 페이징하는 효과를 내는 것이 어렵습니다. 예를 들어, 사용자가 패닝할 때 아이템이 화면에 일부만 보이는 어색한 스크롤 위치에 도달하기 쉽습니다.

이를 위해, 이 모듈은 스크롤 스냅 위치를 도입하여 스크롤 컨테이너의 스크롤포트가 스크롤 동작이 완료된 후 도달할 수 있는 스크롤 위치를 강제합니다.

또한, 스냅이 꺼져 있을 때에도 페이징 및 스크롤 위치를 더 잘 제어할 수 있도록, 이 모듈은 모든 스크롤 컨테이너에서 사용할 수 있는 scroll-padding 속성을 정의하여 페이징 및 스크롤-인투-뷰 동작을 위해 스크롤 컨테이너최적 보기 영역을 조정할 수 있습니다. 이와 유사하게 scroll-margin 속성은 어떤 박스에든 사용할 수 있으며, 스크롤-인투-뷰 동작을 위해 시각적 영역을 조정할 수 있습니다.

1.1. 모듈 상호작용

이 모듈은 [CSS2] 11.1절에서 정의된 스크롤링 UI 기능을 확장합니다.

이 모듈의 어떤 속성도 ::first-line::first-letter 의사 요소에는 적용되지 않습니다.

1.2. 값 정의

이 명세는 CSS 속성 정의 규칙[CSS2]에서 따르며, 값 정의 문법[CSS-VALUES-3]에서 사용합니다. 이 명세에서 정의되지 않은 값 타입은 CSS Values & Units [CSS-VALUES-3]에서 정의됩니다. 다른 CSS 모듈과 조합되면 이러한 값 타입의 정의가 확장될 수 있습니다.

각 속성 정의에 나열된 속성별 값 외에도, 이 명세에서 정의된 모든 속성은 CSS-wide 키워드도 속성 값으로 허용합니다. 가독성을 위해 명시적으로 반복하지 않았습니다.

2. 동기 부여 예시

이 예시에서는 스크롤 컨테이너에 여러 이미지를 배치하여 포토 갤러리를 만듭니다. 이 예에서 스크롤 컨테이너는 내부의 사진들보다 크며 (여러 이미지를 동시에 볼 수 있음), 이미지 크기는 다양합니다. 필수(강제) 요소 기반 스냅 위치를 사용하면, 항상 이미지를 스크롤 컨테이너의 스크롤포트 중앙에 오도록 스크롤이 완료됩니다.
img {
    /* 각 사진의 중앙이 스크롤 컨테이너의 X축 중앙과 정렬되도록 지정합니다 */
    scroll-snap-align: none center;
}
.photoGallery {
    width: 500px;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    /* 스크롤 위치가 스크롤 동작이 끝날 때 항상 스냅 위치에 있어야 함을 요구합니다. */
    scroll-snap-type: x mandatory;
}
<div class="photoGallery">
    <img src="img1.jpg">
    <img src="img2.jpg">
    <img src="img3.jpg">
    <img src="img4.jpg">
    <img src="img5.jpg">
</div>
예시에서 스크롤 컨테이너 콘텐츠의 레이아웃입니다. 스냅포트는 빨간색 사각형으로 표시되며, 스냅 영역은 노란색 사각형으로 표시됩니다. scroll-snap-align이 인라인(수평) 축에서 “center”이기 때문에, 스냅포트의 X-중앙(빨간색 점선)과 스냅 영역의 X-중앙(노란색 점선)이 정렬되는 각 스크롤 위치에 스냅 위치가 설정됩니다.
이 예시에서는 각 페이지가 스크롤 컨테이너의 가장자리 근처(정확히 가장자리는 아님)에 정렬되는 페이지네이션 문서를 만듭니다. 이렇게 하면 이전 페이지가 위에서 “살짝 보이게” 되어 사용자가 아직 문서의 맨 위에 도달하지 않았음을 인식할 수 있습니다. 필수(강제) 스냅 위치 대신 proximity 스냅 위치를 사용하면 한 번에 한 페이지씩 강제로 스냅하지 않고, 사용자가 페이지 중간에서 멈출 수도 있습니다. 하지만 스크롤 동작이 스냅 위치 근처에서 끝나면, 스크롤이 지정된 대로 페이지를 정렬하도록 조정됩니다.
.page {
    /* 각 페이지의 윗부분을 스냅에 사용할 가장자리로 정의 */
    scroll-snap-align: start none;
}
.docScroller {
    width: 500px;
    overflow-x: hidden;
    overflow-y: auto;
    /* 각 요소의 스냅 영역이 위쪽에서 100px 오프셋과 정렬되도록 지정 */
    scroll-padding: 100px 0 0;
    /* 스크롤 동작이 끝날 때 스냅 위치에 가까우면 스냅 위치에서 끝나도록 유도 */
    scroll-snap-type: y proximity;
}
<div class="docScroller">
    <div class="page">페이지 1</div>
    <div class="page">페이지 2</div>
    <div class="page">페이지 3</div>
    <div class="page">페이지 4</div>
</div>
예시에서 스크롤 컨테이너 콘텐츠의 레이아웃입니다. 스냅포트는 빨간색 사각형으로 표시되며(스크롤 패딩으로 인해 상단에서 100px 안쪽에 위치), 스냅 영역은 노란색 사각형으로 표시됩니다. scroll-snap-align이 Y축에서 “start”이므로, 스냅포트의 Y-시작(빨간색 점선)과 스냅 영역의 Y-시작(노란색 점선)이 정렬되는 각 스크롤 위치에 스냅 위치가 생성됩니다.

3. 스크롤 스냅 모델

이 모듈은 스크롤 스냅 위치에 대한 제어를 정의합니다. 스크롤 스냅 위치는 스크롤 컨테이너 내에서 콘텐츠가 특정 정렬을 이루는 스크롤 위치입니다. 관련 scroll-snap-type 속성을 스크롤 컨테이너에 적용하면, 저자는 스크롤 동작(프로그램적 스크롤 포함, 예: scrollTo() 메서드) 이후에 스크롤포트가 스냅 위치에 도달하도록 바이어스를 요청할 수 있습니다.

스냅 위치는 요소의 scroll-snap-align 값에 따라 특정 정렬로 지정되며, 요소의 스크롤 스냅 영역(scroll-margin으로 수정된 경계 박스)을 스크롤 컨테이너스냅포트(scroll-padding으로 축소된 스크롤포트) 내에서 정렬합니다. 이는 정렬 대상정렬 컨테이너 내에서 정렬하는 것과 개념적으로 동일합니다. 지정된 정렬을 만족하는 스크롤 위치가 스냅 위치입니다.

스크롤 컨테이너의 스크롤포트의 스크롤 위치를 스냅 위치에 맞추도록 조정하는 행위를 스냅이라고 하며, 스크롤 컨테이너스냅된 상태란, 스크롤포트의 스크롤 위치가 스냅 위치이며, 활성 스크롤 동작이 없는 경우를 의미합니다. CSS 스크롤 스냅 모듈은 스냅 위치를 강제하기 위해 사용되는 정확한 애니메이션이나 물리를 명시하거나 요구하지 않습니다; 이는 사용자 에이전트에 맡깁니다.

스냅 위치는 요소의 포함 블록 체인에서 가장 가까운 상위 스크롤 컨테이너에만 영향을 줍니다.

4. 스크롤 스냅 영역 캡처: 스크롤 컨테이너의 속성

4.1. 스크롤 스냅 규칙: scroll-snap-type 속성

이름: scroll-snap-type
값: none | [ x | y | block | inline | both ] [ mandatory | proximity ]?
초기값: none
적용 대상: 모든 요소
상속 여부: no
백분율: 해당 없음
계산된 값: 지정된 키워드
정형 순서: 문법에 따름
애니메이션 타입: 불연속(discrete)

scroll-snap-type 속성은 스크롤 컨테이너스크롤 스냅 컨테이너인지 여부, 얼마나 엄격하게 스냅되는지, 그리고 어떤 축을 고려하는지 지정합니다. 엄격성 값이 지정되지 않으면 proximity 가 기본으로 사용됩니다.

이 예시에서는 block 축(수평 쓰기 시 y축, 수직 쓰기 시 x축)에서 제목에 스냅이 활성화됩니다:
html {
  scroll-snap-type: block;   /* 메인 문서 스크롤러에 적용 */
}
h1, h2, h3, h4, h5, h6 {
  scroll-snap-align: start;  /* 뷰포트의 시작(상단)에 스냅 */
}

UA는 루트 요소에 설정된 scroll-snap-type 값을 문서 뷰포트에 적용해야 합니다. overflow와 달리, scroll-snap-type 값은 HTML body에서 전달되지 않습니다.

4.1.1. 스크롤 스냅 축: x, y, block, inline, 그리고 both

축 값은 어떤 축(들)이 스냅 위치의 영향을 받는지, 그리고 스냅 위치가 각 축마다 독립적으로 평가되는지, 아니면 2D 포인트로 함께 평가되는지를 지정합니다. 값은 다음과 같이 정의됩니다:

x
스크롤 컨테이너는 수평축에서만 스냅하여 스냅 위치에 도달합니다.
y
스크롤 컨테이너는 수직축에서만 스냅하여 스냅 위치에 도달합니다.
block
스크롤 컨테이너는 block 축에서만 스냅하여 스냅 위치에 도달합니다.
inline
스크롤 컨테이너는 인라인 축에서만 스냅하여 스냅 위치에 도달합니다.
both
스크롤 컨테이너는 두 축 모두 독립적으로 스냅하여 스냅 위치에 도달할 수 있습니다 (각 축에서 서로 다른 요소에 스냅될 수도 있음).

4.1.2. 스크롤 스냅 엄격성: none, proximity, 그리고 mandatory

엄격성 값 (none, proximity, mandatory) 는 스냅 위치스크롤 컨테이너에서 (스크롤 위치를 강제로 조정함으로써) 얼마나 엄격하게 적용되는지 지정합니다. 값은 다음과 같이 정의됩니다:

none
스크롤 컨테이너에 지정되면, 스크롤 컨테이너스냅하지 않습니다.
mandatory
스크롤 컨테이너에 지정되면, 스크롤 컨테이너는 활성 스크롤 동작이 없을 때 반드시 스냅 위치에 스냅되어 있어야 합니다. 유효한 스냅 위치가 존재하면 스크롤 종료 시 반드시 스냅해야 합니다 (존재하지 않으면 스냅이 발생하지 않음).
proximity
스크롤 컨테이너에 지정되면, 스크롤 컨테이너는 스크롤 종료 시 UA의 판단에 따라, 스크롤 파라미터에 따라 스냅 위치에 스냅할 수 있습니다.

저자는 화면 크기와(적용되는 경우) 콘텐츠 크기가 다양할 수 있으므로, mandatory 스냅 위치 사용에 신중해야 합니다. 특히 스냅된 요소가 스크롤포트보다 큰 경우 UA가 접근을 처리하지만, 인접하지 않은 형제 요소에 mandatory 스냅을 지정하면, 그 사이의 콘텐츠가 화면보다 긴 경우 접근 불가가 될 수 있습니다.

박스는 스냅 위치를 캡처한다고 하며, 스크롤 컨테이너이거나 none이 아닌 scroll-snap-type 값을 가진 경우입니다. 박스의 스냅 위치 캡처 상위 요소가 포함 블록 체인에서 non-none 값을 가진 스크롤 컨테이너라면, 그 박스가 스크롤 스냅 컨테이너입니다. 그렇지 않으면 박스는 스크롤 스냅 컨테이너가 없으며, 스냅 위치스냅을 트리거하지 않습니다.

4.1.3. 레이아웃 변경 후 다시 스냅

문서의 콘텐츠나 레이아웃이 변경되어 (예: 콘텐츠가 추가, 이동, 삭제, 크기 변경됨) 스냅포트의 콘텐츠가 변경되면, UA는 결과 스크롤 위치를 재평가하고 필요하면 다시 스냅해야 합니다. 스크롤 컨테이너가 콘텐츠 변경 전에 스냅된 상태이고 동일한 스냅 위치가 여전히 존재한다면 (예: 관련 요소가 삭제되지 않았음), 콘텐츠 변경 후에도 스크롤 컨테이너는 반드시 동일한 스냅 위치로 다시 스냅되어야 합니다. 여러 박스가 이전에 스냅되어 있었고 그들의 스냅 위치가 더 이상 일치하지 않는다면, 그 중 하나가 포커스되거나 타겟팅되어 있다면 스크롤 컨테이너는 그 박스로 다시 스냅해야 하며, 그렇지 않으면 어느 박스에 다시 스냅할지 UA가 결정합니다. (UA는 예를 들어, 요소가 스냅된 상태를 추적하다가 레이아웃 변화로 다른 요소의 스냅 위치가 맞거나 틀어질 때 이를 관리할 수 있습니다.)

새로운 박스나 다른 박스로 다시 스냅해야 하는 경우의 스크롤은 다른 scroll-into-view 동작과 동일한 방식 및 애니메이션을 따라야 하며, scroll-behavior와 같은 컨트롤도 준수해야 합니다. 이전과 동일한 박스로 다시 스냅하는 경우의 스크롤 동작은 UA가 정의합니다. UA는 예를 들어, 섹션의 시작에 스냅되어 있을 때 문서 앞부분에 동적으로 콘텐츠가 추가되더라도 섹션의 새로운 위치로 스크롤 애니메이션을 하지 않고 스크롤이 발생하지 않는 것처럼 보이게 할 수 있습니다.

다음 예시에서 로그 콘솔은 처음 로드되었을 때와 각 메시지가 하단에 추가될 때, 사용자가 해당 가장자리에서 벗어나지 않는 한 콘텐츠의 하단에 스냅된 상태를 유지합니다:
.log {
  scroll-snap-type: proximity;
  align-content: end;
}
.log::after {
  display: block;
  content: "";
  scroll-snap-align: end;
}

이 규칙들은 scroll snap area 하나를 생성하며, ::after 의사 요소로 표현됩니다. 이는 스크롤 스냅 컨테이너의 맨 하단에 위치합니다. 사용자가 하단 “근처”로 스크롤하면, 컨테이너가 해당 위치로 스냅됩니다. 컨테이너에 더 많은 콘텐츠가 동적으로 추가되어도, 계속 해당 위치에 스냅된 상태가 유지됩니다 (스크롤 컨테이너는 어떤 변경 후에도 동일한 scroll snap area가 존재하면 반드시 다시 스냅해야 하기 때문). 하지만 사용자가 로그 안의 다른 곳으로 스크롤했다면, 아무 동작도 하지 않습니다.

4.2. 스크롤 스냅포트: scroll-padding 속성

이름: scroll-padding
값: [ auto | <length-percentage> ]{1,4}
초기값: auto
적용 대상: 스크롤 컨테이너
상속 여부: no
백분율: 스크롤 컨테이너의 스크롤포트의 해당 차원을 기준으로 상대적
계산된 값: 각 측면별, auto 키워드 또는 계산된 <length-percentage>
애니메이션 타입: 계산된 값 타입에 따라
정형 순서: 문법에 따름

이 속성은 (스크롤 컨테이너 전체에 대해, 스크롤 스냅 컨테이너만이 아니라) 스크롤포트의 최적 보기 영역을 정의하는 오프셋을 지정합니다: 사용자가 보는 영역에 요소를 배치할 때 대상이 되는 영역입니다. 저자는 스크롤포트의 일부 영역을 다른 콘텐츠(예: 고정 위치 툴바나 사이드바)에 의해 가려진 부분에서 제외하거나, 단순히 대상 요소와 스크롤포트의 가장자리 사이에 여유 공간을 줄 수 있습니다.

scroll-padding 속성은 축약 속성으로, scroll-padding-* 롱핸드를 한 번에 설정하며, 각 측면의 롱핸드에 값을 할당하는 방식은 padding 속성과 동일합니다. 값의 의미는 다음과 같습니다:

<length-percentage>

스크롤포트의 해당 가장자리에서 내부로의 오프셋을 정의합니다. 루트 뷰포트에 적용될 때, 오프셋은 레이아웃 뷰포트를 기준으로 계산 및 적용되며 (비주얼 뷰포트가 아님), inset 속성고정 위치 박스에서 적용되는 방식과 동일합니다; 최적 보기 영역은 남은 영역 중 비주얼 뷰포트와 교차하는 부분입니다.

auto

스크롤포트의 해당 가장자리 오프셋이 UA에 의해 결정됨을 나타냅니다. 일반적으로 0px로 기본값이 설정되어야 하지만, UA는 비영(0이 아닌 값이 더 적합할 때)을 감지하는 휴리스틱을 사용할 수 있습니다.

예를 들어, UA가 position:fixed 요소가 불투명하고 스크롤되지 않는 “헤더”로 사용되어 아래의 콘텐츠를 가리고 있음을 감지하면, 상단 오프셋을 해당 요소의 높이로 해석하여 “페이지 다운” 동작(예: PgDn 키를 누름)이 자동으로 “보이는 페이지”만큼 스크롤되게 할 수 있습니다.

이 오프셋들은 스크롤포트의 영역 중 스크롤 동작에서 “보기 가능”으로 간주되는 영역을 줄입니다: 레이아웃에는 영향을 주지 않으며, 스크롤 원점이나 초기 위치에도 영향을 주지 않고, 요소가 실제로 보이는지 여부에도 영향을 주지 않습니다. 하지만 요소나 캐럿이 스크롤되어 보이는 상태로 간주되는지(예: 타겟팅 또는 포커싱 작업에서), 페이징 동작(예: PgUp, PgDn 키 사용 또는 스크롤바에서 동등 동작 트리거)에서 스크롤되는 양을 줄여야 하며, 최적 보기 영역 내에서 스크롤포트가 사용자에게 연속적인 콘텐츠 스트림을 보여줍니다.

스크롤 스냅 컨테이너에서는 이 영역이 스크롤 스냅포트도 정의합니다—스냅 위치를 계산할 때 정렬 컨테이너로 사용되는 스크롤포트의 영역입니다. 스크롤 스냅 영역의 정렬에도 쓰입니다.

이 예시에서는 scroll-padding을 사용하여 고정 위치 툴바에 가려지지 않는 스크롤포트 영역의 중앙에 슬라이드쇼 이미지를 배치합니다.
html {
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-padding: 0 500px 0 0;
}
.toolbar {
    position: fixed;
    height: 100%;
    width: 500px;
    right: 0;
}
img {
    scroll-snap-align: none center;
}

UA는 루트 요소에 설정된 scroll-padding 값을 문서 뷰포트에 적용해야 합니다. (overflow와 달리, scroll-padding 값은 HTML body에서 전달되지 않습니다.)

5. 스크롤 스냅 영역 정렬: 요소의 속성

5.1. 스크롤 스냅 영역: scroll-margin 속성

이름: scroll-margin
값: <length>{1,4}
초기값: 0
적용 대상: 모든 요소
상속 여부: no
백분율: 해당 없음
계산된 값: 각 측면별 절대 길이
정형 순서: 문법에 따름
애니메이션 타입: 계산된 값 타입에 따라

이 속성은 축약 속성으로, scroll-margin-* 롱핸드를 한 번에 설정하며, 각 측면의 롱핸드에 값을 할당하는 방식은 margin 속성과 동일합니다.

값은 이 박스를 스냅포트에 스냅할 때 사용되는 스크롤 스냅 영역을 정의하는 외측 오프셋입니다. 스크롤 스냅 영역은 변형된 border 박스를 가져와 스크롤 컨테이너의 좌표 공간에서 축에 맞춘(축에 정렬된) 사각형 경계 박스를 찾은 뒤, 지정된 외측 오프셋을 더하여 결정됩니다.

참고: 이렇게 하면 스크롤 스냅 영역이 항상 사각형이며 스크롤 컨테이너의 좌표 공간에 맞게 축 정렬됩니다.

페이지가 프래그먼트로 탐색되어 타겟 요소가 정의되면 (:target으로 매칭되거나, scrollIntoView()의 대상인 경우), UA는 해당 요소의 스크롤 스냅 영역을 사용해야 하며, 단순 border 박스만이 아니라, 스크롤 가능한 오버플로우 영역 중 어느 영역을 보여줄지 판단할 때 사용해야 합니다. 스냅이 꺼져 있거나 이 요소에 적용되지 않아도 마찬가지입니다.

5.2. 스크롤 스냅 정렬: scroll-snap-align 속성

이름: scroll-snap-align
값: [ none | start | end | center ]{1,2}
초기값: none
적용 대상: 모든 요소
상속 여부: no
백분율: 해당 없음
계산된 값: 두 개의 키워드
정형 순서: 문법에 따름
애니메이션 타입: 불연속(discrete)

scroll-snap-align 속성은 박스의 스냅 위치스냅 영역의 정렬로 지정합니다 (정렬 대상으로). 박스의 스냅 컨테이너스냅포트 내에서(정렬 컨테이너로), 두 값은 각각 block 축inline 축의 스냅 정렬을 지정하며, 스냅 컨테이너writing mode에 따라 결정됩니다. 한 값만 지정되면, 두 번째 값은 첫 번째 값과 동일하게 기본값이 설정됩니다.

값은 다음과 같이 정의됩니다:

none
이 박스는 지정된 축에 스냅 위치를 정의하지 않습니다.
start
이 박스의 스크롤 스냅 영역스크롤 컨테이너스냅포트의 시작에 정렬하면 지정된 축에서 스냅 위치가 됩니다.
end
이 박스의 스크롤 스냅 영역스크롤 컨테이너스냅포트의 끝에 정렬하면 지정된 축에서 스냅 위치가 됩니다.
center
이 박스의 스크롤 스냅 영역스크롤 컨테이너스냅포트의 중앙에 정렬하면 지정된 축에서 스냅 위치가 됩니다.

start와 end 정렬은 writing mode에 따라 스냅 컨테이너 기준으로 해석되며, 스크롤 스냅 영역스냅포트보다 큰 경우에는 박스 자체의 writing mode 기준으로 해석됩니다. (이렇게 하면 컨테이너 내 아이템의 스냅 정렬이 일반적으로 일관성을 가지면서도, start가 항상 아이템의 시작이 읽기 편하도록 정렬됨을 보장할 수 있습니다.)

5.2.1. 유효한 스냅 위치의 범위 지정: 화면에 보이는 박스에 한정

스크롤 스냅의 목적이 스크롤포트 내의 콘텐츠를 최적의 보기로 정렬하는 것이므로, 스크롤 위치가 해당 스냅 위치스냅될 경우, 관련 스냅 영역이 전체적으로 스냅포트 밖에 위치한다면, 그 위치는 유효한 스냅 위치로 간주될 수 없습니다. (비록 스냅 영역의 정렬 조건을 만족하더라도)

예를 들어, 스냅 영역의 윗쪽이 스냅포트의 윗쪽과 일치하면 top 정렬로 간주합니다; 이것은 블록 축에서 시작 정렬 스냅의 유효한 스냅 위치가 될 수 있습니다 만약 스냅 영역의 일부라도 화면에 보이면. 만약 스냅 영역 전체가 스냅포트 밖에 있다면, 스크롤 컨테이너스냅된 것으로 간주하지 않으며, 요구되는 정렬이 충족되더라도 실제 뷰어에게는 관련이 없습니다.
╔════viewport════╗┈┈┈┈┈┈┈┈┌──────────────┐
║  ┌─────┐ ┌──┐  ║        │ top-snapping │
║  ├──┐  │ └──┘  ║        │   element    │
║  └──┴──┘       ║        │              │
╚════════════════╝        │              │
                          └──────────────┘
화면 밖 요소의 정렬은 스냅으로 간주하지 않습니다.
왜 스냅을 요소가 화면에 보일 때만 제한하나요? WebKit 구현자들이 지적한 것처럼, 스냅 엣지를 캔버스 전체에 무한히 확장하면 격자 레이아웃만 스냅할 수 있게 되고, 화면 밖 요소가 화면 안 요소와 정렬되지 않을 때 사용자가 이상한 동작을 경험하게 됩니다. (만약 이 요구사항이 구현자에게 부담스럽다면, 기본적으로 격자 기반 동작으로 하고, 나중에 더 스마트한 동작을 위한 스위치를 도입할 수 있습니다.)

참고: scroll-snap-type: both스냅 위치를 각 축에서 독립적으로 평가하지만, 한 축에서 스냅 위치를 선택할 때 다른 축의 스냅 위치의 영향도 받을 수 있습니다. 예를 들어, 한 축에서 스냅하면 다른 축이 정렬하려던 스냅 영역이 화면 밖으로 밀려나 해당 스냅 위치가 무효가 되어 선택할 수 없게 됩니다.

5.2.2. 스크롤포트를 넘치는 박스의 스냅

스냅 영역이 특정 축에서 스냅포트보다 크면, 그 축에서 스냅 영역스냅포트를 덮는 모든 스크롤 위치와, 해당 축에서 이전/다음 스냅 위치 사이의 거리가 스냅포트보다 크면, 그 위치는 해당 축에서 유효한 스냅 위치입니다. UA는 특정 스크롤 동작(예: 명시적 페이징)에 대해 지정된 정렬을 더 정확한 대상으로 사용할 수 있습니다.

예를 들어, § 2 동기 부여 예시의 첫 번째 예시에서 사진을 영역으로 사용합니다. 저자는 항목별로 mandatory 스냅을 원하지만, 항목이 뷰포트보다 크면, 해당 항목에 도달했을 때 전체를 자유롭게 스크롤할 수 있기를 원합니다.

스냅 영역스냅포트보다 크므로, 영역이 뷰포트를 가득 채울 때는 컨테이너를 자유롭게 스크롤할 수 있고 정렬 위치로 다시 스냅되지 않습니다. 하지만 컨테이너가 스크롤되어 영역이 축에서 뷰포트를 완전히 채우지 않게 되면, 영역은 바깥쪽으로 스크롤되는 것을 막으려고 하고, 충분히 스크롤되면 다른 스냅 위치로 스냅됩니다.

또 다른 예로, 중첩된 section 요소에 mandatory top 스냅을 적용하면 (상위 section이 큰 경우) 큰 스냅 영역이 만들어지고, 그 안에 더 작은 스냅 영역(하위 section)들이 들어갈 수 있습니다. 하위 section이 충분히 작으면 정상적으로 스냅되고, 길면 해당 영역 내에서 자유롭게 스크롤하거나, 하위 section이 없는 상위 section의 큰 영역을 자유롭게 스크롤할 수 있습니다.
┌─ top-level section ─┐ ━┓
│                     │ 1┃
│                     │  ┃
│                     │ ━┩
│                     │  ┆
│                     │  ┆
│┌─── sub-section ───┐│  ╯ ━┓
│└───────────────────┘│    2┃
│┌─── sub-section ───┐│ ━┓  ┃
││                   ││ 3┃ ━┛
│└───────────────────┘│  ┃
│┌─── sub-section ───┐│ ━┛ ━┓
│└───────────────────┘│    4┃
│┌─── sub-section ───┐│ ━┓  ┃
││                   ││ 5┃ ━┛
││                   ││  ┃
││                   ││ ━┩
││                   ││  ┆
││                   ││  ┆
││                   ││  ┆
│└───────────────────┘│  ┆
└─────────────────────┘  ╯
위 그림에서 숫자 표시된 다섯 개의 뷰포트가 상위 section과 네 개의 하위 section에 연결된 다섯 개의 스냅 위치를 나타냅니다. 첫 번째와 마지막 스냅 위치가 뷰포트보다 긴 영역에 포함되어 있으므로, 뷰어는 각 영역의 위쪽과 아래쪽 사이를 자유롭게 스크롤할 수 있습니다.

참고: 만약 저자가 각 section의 제목에 mandatory 스냅을 설정했다면 (section 자체가 아니라), 첫 번째와 다섯 번째 section의 콘텐츠 일부가 사용자에게 접근 불가가 됩니다. 헤딩 스냅 영역이 전체 section을 덮지 않기 때문입니다. 이런 이유로, 멀리 떨어진 요소에 mandatory 스냅을 사용하는 것은 바람직하지 않습니다.

5.2.3. 도달 불가능한 스냅 위치

스냅 위치가 지정된 대로 도달 불가능하므로, 해당 위치로 정렬하려면 스크롤 컨테이너의 뷰포트를 스크롤 가능한 오버플로우 영역의 가장자리 너머로 스크롤해야 할 경우, 이 스냅 영역사용된 스냅 위치는 원하는 스냅 위치 방향으로 각 축에서 최대한 스크롤한 위치입니다.

5.3. 스크롤 스냅 한계: scroll-snap-stop 속성

이름: scroll-snap-stop
값: normal | always
초기값: normal
적용 대상: 모든 요소
상속 여부: no
백분율: 해당 없음
계산된 값: 지정된 키워드
정형 순서: 문법에 따름
애니메이션 타입: 불연속(discrete)

의도된 방향으로 스크롤할 때, 스크롤 컨테이너는 여러 스냅 위치를 “넘어갈 수 있습니다” (같은 방향이지만 더 짧은 거리였다면 스냅될 수 있었던 위치), 스크롤 동작의 자연스러운 끝점에 도달해 최종 스크롤 위치를 선택하기 전까지. scroll-snap-stop 속성을 사용하면, 이런 스냅 위치에서 스크롤 동작을 “트랩”할 수 있어, 스크롤 컨테이너가 스크롤 동작이 자연스럽게 끝나기 전에 멈추도록 강제할 수 있습니다.

값은 다음과 같이 정의됩니다:

normal
스크롤 컨테이너는 스크롤 동작 중 이 요소가 정의한 스냅 위치를 넘어갈 수 있습니다.
always
스크롤 컨테이너는 스크롤 동작 중 이 요소가 정의한 스냅 위치를 넘어가면 안 되며, 대신 이 요소의 첫 번째 스냅 위치에 반드시 스냅해야 합니다.

이 속성은 의도된 끝 위치만 있는 스크롤 동작에는 영향을 주지 않습니다. 이런 경우에는 어떤 스냅 위치도 개념적으로 “넘어가는” 일이 없기 때문입니다.

6. 스냅 동작 메커니즘

어떤 스냅 위치로 스냅할지 선택하는 정확한 모델 알고리즘은 일부러 대부분 정의하지 않았습니다. 이렇게 하면 사용자 에이전트가 사용자의 의도 및 상호작용을 정교하게 모델링하고, 시간이 지남에 따라 반응 방식을 조정하여 사용자에게 최적의 경험을 제공할 수 있습니다.

이 섹션에서는 스크롤 스냅 동작을 논의하는 데 도움이 되는 몇 가지 개념을 정의하고, 효과적인 스크롤 스냅 전략이 어떤 모습일지에 대한 가이드라인을 제공합니다. 사용자 에이전트는 이 지침을 참고하되 자신만의 최선의 판단을 적용해 스냅 동작을 정의하는 것이 권장됩니다. 또한, 저자가 스크롤 스냅을 염두에 두고 인터페이스를 설계할 때 최소한의 합리적인 동작을 보장하기 위한 몇 가지 동작 요구사항도 포함되어 있습니다.

6.1. 스크롤 방식의 종류

페이지가 스크롤될 때, 스크롤은 의도된 끝 위치와/또는 의도된 방향을 가집니다. 이 두 가지의 조합마다 서로 다른 스크롤 카테고리가 정의되며, 각각 약간 다르게 처리할 수 있습니다:

의도된 끝 위치
의도된 끝 위치만 있는 스크롤의 흔한 예시는 다음과 같습니다:
  • 모멘텀 없이 릴리즈된 패닝 제스처

  • 스크롤바 “썸”을 직접 조작

  • scrollTo()와 같은 API로 프로그래밍적으로 스크롤

  • 문서의 포커스 가능한 요소를 탭으로 이동

  • 페이지 내 앵커로 네비게이션

  • Home/End 키와 같은 홈 동작

의도된 방향 및 끝 위치
의도된 방향 및 끝 위치가 모두 있는 스크롤의 흔한 예시는 다음과 같습니다:
  • 모멘텀이 적용되는 “플링” 제스처

  • scrollBy()와 같은 API로 프로그래밍적으로 스크롤

  • PgUp/PgDn 키(또는 스크롤바에서 동등 동작)로 페이징

스냅 포인트 등 기능 개입 이전의 스크롤 의도된 끝점은 자연스러운 끝점입니다.

의도된 방향
의도된 방향만 있는 스크롤의 흔한 예시는 다음과 같습니다:
  • 키보드의 방향키(또는 스크롤바에서 동등 동작) 누르기

  • 고정(관성 없는) 스크롤로 해석되는 스와이프 제스처

또한, 페이지 레이아웃이 일반적으로 수직/수평 정렬이기 때문에, UA는 스크롤의 방향이 충분히 수직/수평이면 축 고정(axis-lock)을 적용할 수 있습니다. 축이 고정된 스크롤은 해당 축만 따라 이동합니다. 이렇게 하면 덜 정밀한 입력장치가 비주 축으로 드리프트하는 것을 방지할 수 있습니다.

참고: 이 명세는 UA가 지원하는 스크롤 방식에만 적용됩니다; UA가 특정 입력이나 스크롤 방식을 반드시 지원해야 하는 것은 아닙니다.

6.2. 스냅 위치 선택

스크롤 컨테이너에는 스냅 영역스크롤 가능한 오버플로우 영역에 여러 군데 흩어져 있을 수 있습니다. 스냅 위치를 선택하는 단순한 알고리즘은 사용자가 직관적으로 이해하기 힘든 동작을 만들 수 있으므로, 선택 알고리즘 설계 시 주의가 필요합니다. 다음은 선택 과정에 도움이 될 수 있는 팁입니다:

부록 A: 롱핸드

물리적 및 논리적 롱핸드(및 해당 축약형)는 [CSS-LOGICAL-1]에서 정의된 대로 상호작용합니다.

물리적 롱핸드(scroll-padding)

이름: scroll-padding-top, scroll-padding-right, scroll-padding-bottom, scroll-padding-left
값: auto | <length-percentage>
초기값: auto
적용 대상: 스크롤 컨테이너
상속 여부: no
백분율: 스크롤 컨테이너의 스크롤포트 기준
계산된 값: auto 키워드 또는 계산된 <length-percentage>
정형 순서: 문법에 따름
애니메이션 타입: 계산된 값 타입에 따라

scroll-padding의 이 롱핸드들은 각각 스냅포트의 상, 우, 하, 좌 측면을 지정합니다. 음수 값은 허용되지 않습니다.

플로우 상대 롱핸드(scroll-padding)

이름: scroll-padding-inline-start, scroll-padding-block-start, scroll-padding-inline-end, scroll-padding-block-end
값: auto | <length-percentage>
초기값: auto
적용 대상: 스크롤 컨테이너
상속 여부: no
백분율: 스크롤 컨테이너의 스크롤포트 기준
계산된 값: auto 키워드 또는 계산된 <length-percentage>
정형 순서: 문법에 따름
애니메이션 타입: 계산된 값 타입에 따라

scroll-padding의 이 롱핸드들은 각각 스냅포트의 block-start, inline-start, block-end, inline-end 측면을 지정합니다. 음수 값은 허용되지 않습니다.

이름: scroll-padding-block, scroll-padding-inline
값: [ auto | <length-percentage> ]{1,2}
초기값: auto
적용 대상: 스크롤 컨테이너
상속 여부: no
백분율: 스크롤 컨테이너의 스크롤포트 기준
계산된 값: 각 개별 속성 참조
애니메이션 타입: 계산된 값 기준
정형 순서: 문법에 따름

축약 속성 scroll-padding-block-start + scroll-padding-block-end, scroll-padding-inline-start + scroll-padding-inline-endscroll-padding의 롱핸드들이며, 각각 스냅포트의 block 축과 inline 축의 측면을 지정합니다.

값이 두 개 지정되면, 첫 번째 값이 시작 값이고 두 번째 값이 끝 값입니다.

scroll-margin의 물리적 롱핸드

이름: scroll-margin-top, scroll-margin-right, scroll-margin-bottom, scroll-margin-left
값: <length>
초기값: 0
적용 대상: 모든 요소
상속 여부: no
백분율: 해당 없음
계산된 값: 절대 길이
정형 순서: 문법에 따름
애니메이션 타입: 계산된 값 타입 기준

scroll-margin의 이 롱핸드들은 각각 scroll-margin의 상, 우, 하, 좌 측면을 스크롤 스냅 영역에 지정합니다.

scroll-margin의 플로우 상대 롱핸드

이름: scroll-margin-block-start, scroll-margin-inline-start, scroll-margin-block-end, scroll-margin-inline-end
값: <length>
초기값: 0
적용 대상: 모든 요소
상속 여부: no
백분율: 해당 없음
계산된 값: 절대 길이
정형 순서: 문법에 따름
애니메이션 타입: 계산된 값 타입 기준

scroll-margin의 이 롱핸드들은 각각 scroll-margin의 block-start, inline-start, block-end, inline-end 측면을 스크롤 스냅 영역에 지정합니다.

이름: scroll-margin-block, scroll-margin-inline
값: <length>{1,2}
초기값: 0
적용 대상: 모든 요소
상속 여부: no
백분율: 해당 없음
계산된 값: 개별 속성 참조
애니메이션 타입: 계산된 값 타입 기준
정형 순서: 문법에 따름

scroll-margin-block-start + scroll-margin-block-end, scroll-margin-inline-start + scroll-margin-inline-endscroll-margin의 롱핸드들이며, 각각 스크롤 스냅 영역의 block 축과 inline 축의 측면을 지정합니다.

값이 두 개 지정되면, 첫 번째 값이 시작 값이고 두 번째 값이 끝 값입니다.

7. 개인정보 및 보안 고려사항

이 명세는 DOM에 이미 직접 노출된 정보 외에 다른 정보를 노출하지 않습니다; 단지 스크롤 기능을 조금 더 향상시킬 뿐입니다. 새로운 개인정보 또는 보안 고려사항은 없습니다.

8. 감사의 글

David Baron, Simon Fraser, Håkon Wium Lie, Theresa O’Connor, François Remy, Majid Valpour, 그리고 특히 Robert O’Callahan에게 제안과 권고에 깊은 감사를 드립니다. 그들의 의견이 이 문서에 반영되었습니다.

9. 변경 사항

9.1. 2019년 3월 19일 CR 이후 변경 사항

2019년 3월 19일 후보 권고 이후의 변경 사항은 다음과 같습니다:

의견 처리 결과(Disposition of Comments)를 확인할 수 있습니다.

9.2. 2019년 1월 31일 CR 이후 변경 사항

2019년 1월 31일 후보 권고 이후의 변경 사항은 다음과 같습니다:

9.3. 2018년 8월 14일 CR 이후 변경 사항

2018년 8월 14일 후보 권고 이후의 변경 사항은 다음과 같습니다:

의견 처리 결과(Disposition of Comments)를 확인할 수 있습니다.

9.4. 2017년 12월 14일 CR 이후 변경 사항

2017년 12월 14일 후보 권고 이후의 변경 사항은 다음과 같습니다:

의견 처리 결과(Disposition of Comments)를 확인할 수 있습니다.

9.5. 2017년 8월 24일 CR 이후 변경 사항

2017년 8월 24일 후보 권고 이후의 변경 사항은 다음과 같습니다:

의견 처리 결과(Disposition of Comments)를 확인할 수 있습니다.

9.6. 2016년 10월 20일 CR 이후 변경 사항

2016년 10월 20일 후보 권고 이후의 변경 사항은 다음과 같습니다:

의견 처리 결과(Disposition of Comments)를 확인할 수 있습니다.

적합성(Conformance)

문서 규칙(Document conventions)

적합성 요구사항은 설명적인 명제와 RFC 2119 용어의 조합으로 표현됩니다. 규범적 부분에서 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL” 등의 주요 단어는 RFC 2119에 정의된 대로 해석해야 합니다. 단, 가독성을 위해 이 명세에서는 모두 대문자로 표기하지 않습니다.

이 명세의 모든 텍스트는 명시적으로 비규범적, 예시, 참고로 표시된 부분을 제외하면 규범적입니다. [RFC2119]

이 명세의 예제는 "for example"이라는 단어로 소개되거나, class="example"와 같이 규범적 텍스트와 구분되어 있습니다. 예시:

이것은 안내용 예시입니다.

안내용 참고는 "Note"라는 단어로 시작하며, class="note"와 같이 규범적 텍스트와 구분되어 있습니다. 예시:

참고, 이것은 안내용 참고입니다.

권고(Advisement)는 규범적 섹션 중 특별한 주의를 환기하기 위해 스타일링되며, <strong class="advisement">로 구분됩니다. 예시: UA는 반드시 접근 가능한 대안을 제공해야 합니다.

적합성 클래스(Conformance classes)

이 명세의 적합성은 세 가지 적합성 클래스에 대해 정의됩니다:

스타일 시트
CSS 스타일 시트.
렌더러
UA가 스타일 시트의 의미를 해석하고 해당 스타일 시트를 사용하는 문서를 렌더링하는 경우.
저작 도구
UA가 스타일 시트를 작성하는 경우.

스타일 시트가 이 명세에 적합하려면, 이 모듈에서 정의된 문법을 사용하는 모든 명령문이 CSS의 일반 문법과 이 모듈에서 정의된 각 기능의 개별 문법에 따라 유효해야 합니다.

렌더러가 이 명세에 적합하려면, 적합한 명세대로 스타일 시트를 해석하는 것 외에도 이 명세에서 정의된 모든 기능을 올바르게 파싱하고 문서를 적절히 렌더링함으로써 지원해야 합니다. 단, 디바이스 한계로 인해 UA가 문서를 올바르게 렌더링하지 못하는 경우 UA가 비적합하다고 볼 수 없습니다. (예: UA가 단색 모니터에서 색상을 렌더링하지 않아도 됨)

저작 도구가 이 명세에 적합하려면, 이 모듈에서 정의된 문법에 맞는 스타일 시트를 작성해야 하며, 이 모듈에서 설명된 모든 적합성 요구사항을 충족해야 합니다.

부분 구현(Partial implementations)

저자가 향후 호환 가능한 구문 파싱 규칙을 활용해 대체 값을 지정할 수 있도록, CSS 렌더러는 반드시 지원 가능한 수준이 없는 at-rule, 속성, 속성 값, 키워드, 기타 구문 구조를 무효로 취급(및 적절하게 무시)해야 합니다. 특히 UA는 지원하지 않는 구성 값만 무시하고, 지원되는 값은 적용하는 식으로 다중 값 속성 선언에서 개별 값을 선택적으로 무시하면 안 됩니다. 값이 무효(지원하지 않는 값은 반드시 무효)로 간주되면, CSS에서는 전체 선언을 무시해야 합니다.

불안정 및 독점 기능의 구현(Implementations of Unstable and Proprietary Features)

향후 안정적인 CSS 기능과 충돌을 피하기 위해, CSSWG는 모범 사례를 따라 불안정 기능 및 독점 확장을 구현할 것을 권장합니다.

비실험적 구현(Non-experimental implementations)

명세가 후보 권고 단계에 도달하면, 실험적이지 않은 구현이 가능하며, 구현자는 명세에 따라 올바르게 구현되었음을 입증할 수 있는 CR 수준의 기능에 대해 접두어 없는 구현을 릴리스해야 합니다.

CSS의 구현간 상호운용성을 확립하고 유지하기 위해, CSS 작업 그룹은 비실험적 렌더러가 어떤 CSS 기능의 접두어 없는 구현을 릴리스하기 전에 구현 보고서(필요 시 테스트 케이스 포함)를 W3C에 제출할 것을 요청합니다. W3C에 제출된 테스트 케이스는 CSS 작업 그룹의 검토 및 수정을 받을 수 있습니다.

테스트 케이스 및 구현 보고서 제출 방법에 대한 추가 정보는 CSS 작업 그룹 웹사이트 http://www.w3.org/Style/CSS/Test/에서 확인할 수 있습니다. 문의는 public-css-testsuite@w3.org 메일링 리스트로 하면 됩니다.

CR 종료 기준(CR exit criteria)

이 명세가 제안 권고(Proposed Recommendation)로 진전되기 위해서는, 각 기능에 대해 최소 두 개의 독립적이고 상호운용 가능한 구현이 있어야 합니다. 각 기능은 서로 다른 제품군에서 구현되어도 되며, 모든 기능이 단일 제품에서 구현되어야 할 필요는 없습니다. 이 기준의 목적상, 다음 용어를 정의합니다:

독립적(Independent)
각 구현은 서로 다른 당사자가 개발해야 하며, 다른 적합 구현에서 사용된 코드를 공유, 재사용, 파생할 수 없습니다. 이 명세 구현에 영향이 없는 코드 부분은 예외입니다.
상호운용(Interoperable)
공식 CSS 테스트 스위트의 해당 테스트 케이스(들)를 통과하거나, 구현이 웹 브라우저가 아닐 경우 동등한 테스트를 통과해야 합니다. 모든 관련 테스트는 해당 UA가 상호운용성을 주장하려면 동등한 테스트를 반드시 만들어야 합니다. 상호운용성 목적상, 동등한 테스트를 통과하는 추가 UA도 반드시 있어야 합니다. 동등한 테스트는 동료 검토(peer review)를 위해 공개되어야 합니다.
구현(Implementation)
UA는 다음을 만족해야 함:
  1. 명세를 구현함.
  2. 일반 대중에게 제공됨. 구현은 출시 제품 또는 기타 공개 버전(예: 베타 버전, 프리뷰 릴리스, "nightly build")일 수 있음. 출시되지 않은 제품 릴리스는 해당 기능을 최소 한 달간 구현하여 안정성을 입증해야 함.
  3. 실험적이지 않음(즉, 테스트 케이스를 통과하기 위해 특별히 설계된 버전이 아니고, 앞으로 정상적으로 사용할 목적으로 제작됨).

이 명세는 최소 6개월간 후보 권고 상태를 유지합니다.

색인

이 명세에서 정의된 용어

참조에 의해 정의된 용어

참고 문헌

규범적 참고 문헌

[CSS-ALIGN-3]
Elika Etemad; Tab Atkins Jr.. CSS Box Alignment Module Level 3. 2020년 4월 21일. WD. URL: https://www.w3.org/TR/css-align-3/
[CSS-BOX-4]
Elika Etemad. CSS Box Model Module Level 4. 2020년 4월 21일. WD. URL: https://www.w3.org/TR/css-box-4/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 2021년 1월 19일. WD. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-DISPLAY-3]
Tab Atkins Jr.; Elika Etemad. CSS Display Module Level 3. 2020년 12월 18일. CR. URL: https://www.w3.org/TR/css-display-3/
[CSS-LOGICAL-1]
Rossen Atanassov; Elika Etemad. CSS Logical Properties and Values Level 1. 2018년 8월 27일. WD. URL: https://www.w3.org/TR/css-logical-1/
[CSS-OVERFLOW-3]
David Baron; Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. 2020년 6월 3일. WD. URL: https://www.w3.org/TR/css-overflow-3/
[CSS-POSITION-3]
Elika Etemad; et al. CSS Positioned Layout Module Level 3. 2020년 5월 19일. WD. URL: https://www.w3.org/TR/css-position-3/
[CSS-PSEUDO-4]
Daniel Glazman; Elika Etemad; Alan Stearns. CSS Pseudo-Elements Module Level 4. 2020년 12월 31일. WD. URL: https://www.w3.org/TR/css-pseudo-4/
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. 2019년 6월 6일. CR. URL: https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2020년 11월 11일. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. 2019년 7월 30일. CR. URL: https://www.w3.org/TR/css-writing-modes-4/
[CSS2]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 2011년 6월 7일. REC. URL: https://www.w3.org/TR/CSS21/
[CSSOM-VIEW-1]
Simon Pieters. CSSOM View Module. 2016년 3월 17일. WD. URL: https://www.w3.org/TR/cssom-view-1/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997년 3월. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. Selectors Level 4. 2018년 11월 21일. WD. URL: https://www.w3.org/TR/selectors-4/

속성 색인

이름 초기값 적용 대상 상속 %값 애니메이션 타입 정형 순서 계산된 값
scroll-margin <length>{1,4} 0 모든 요소 no 해당 없음 계산된 값 타입 기준 문법에 따름 각 측면별 절대 길이
scroll-margin-block <length>{1,2} 0 모든 요소 no 해당 없음 계산된 값 타입 기준 문법에 따름 개별 속성 참조
scroll-margin-block-end <length> 0 모든 요소 no 해당 없음 계산된 값 타입 기준 문법에 따름 절대 길이
scroll-margin-block-start <length> 0 모든 요소 no 해당 없음 계산된 값 타입 기준 문법에 따름 절대 길이
scroll-margin-bottom <length> 0 모든 요소 no 해당 없음 계산된 값 타입 기준 문법에 따름 절대 길이
scroll-margin-inline <length>{1,2} 0 모든 요소 no 해당 없음 계산된 값 타입 기준 문법에 따름 개별 속성 참조
scroll-margin-inline-end <length> 0 모든 요소 no 해당 없음 계산된 값 타입 기준 문법에 따름 절대 길이
scroll-margin-inline-start <length> 0 모든 요소 no 해당 없음 계산된 값 타입 기준 문법에 따름 절대 길이
scroll-margin-left <length> 0 모든 요소 no 해당 없음 계산된 값 타입 기준 문법에 따름 절대 길이
scroll-margin-right <length> 0 모든 요소 no 해당 없음 계산된 값 타입 기준 문법에 따름 절대 길이
scroll-margin-top <length> 0 모든 요소 no 해당 없음 계산된 값 타입 기준 문법에 따름 절대 길이
scroll-padding [ auto | <length-percentage> ]{1,4} auto 스크롤 컨테이너 no 스크롤 컨테이너의 스크롤포트의 해당 차원 기준 계산된 값 타입 기준 문법에 따름 각 측면별 auto 키워드 또는 계산된 <length-percentage> 값
scroll-padding-block [ auto | <length-percentage> ]{1,2} auto 스크롤 컨테이너 no 스크롤 컨테이너의 스크롤포트 기준 계산된 값 기준 문법에 따름 개별 속성 참조
scroll-padding-block-end auto | <length-percentage> auto 스크롤 컨테이너 no 스크롤 컨테이너의 스크롤포트 기준 계산된 값 타입 기준 문법에 따름 auto 키워드 또는 계산된 <length-percentage> 값
scroll-padding-block-start auto | <length-percentage> auto 스크롤 컨테이너 no 스크롤 컨테이너의 스크롤포트 기준 계산된 값 타입 기준 문법에 따름 auto 키워드 또는 계산된 <length-percentage> 값
scroll-padding-bottom auto | <length-percentage> auto 스크롤 컨테이너 no 스크롤 컨테이너의 스크롤포트 기준 계산된 값 타입 기준 문법에 따름 auto 키워드 또는 계산된 <length-percentage> 값
scroll-padding-inline [ auto | <length-percentage> ]{1,2} auto 스크롤 컨테이너 no 스크롤 컨테이너의 스크롤포트 기준 계산된 값 기준 문법에 따름 개별 속성 참조
scroll-padding-inline-end auto | <length-percentage> auto 스크롤 컨테이너 no 스크롤 컨테이너의 스크롤포트 기준 계산된 값 타입 기준 문법에 따름 auto 키워드 또는 계산된 <length-percentage> 값
scroll-padding-inline-start auto | <length-percentage> auto 스크롤 컨테이너 no 스크롤 컨테이너의 스크롤포트 기준 계산된 값 타입 기준 문법에 따름 auto 키워드 또는 계산된 <length-percentage> 값
scroll-padding-left auto | <length-percentage> auto 스크롤 컨테이너 no 스크롤 컨테이너의 스크롤포트 기준 계산된 값 타입 기준 문법에 따름 auto 키워드 또는 계산된 <length-percentage> 값
scroll-padding-right auto | <length-percentage> auto 스크롤 컨테이너 no 스크롤 컨테이너의 스크롤포트 기준 계산된 값 타입 기준 문법에 따름 auto 키워드 또는 계산된 <length-percentage> 값
scroll-padding-top auto | <length-percentage> auto 스크롤 컨테이너 no 스크롤 컨테이너의 스크롤포트 기준 계산된 값 타입 기준 문법에 따름 auto 키워드 또는 계산된 <length-percentage> 값
scroll-snap-align [ none | start | end | center ]{1,2} none 모든 요소 no 해당 없음 불연속(discrete) 문법에 따름 두 개의 키워드
scroll-snap-stop normal | always normal 모든 요소 no 해당 없음 불연속(discrete) 문법에 따름 지정된 키워드
scroll-snap-type none | [ x | y | block | inline | both ] [ mandatory | proximity ]? none 모든 요소 no 해당 없음 불연속(discrete) 문법에 따름 지정된 키워드