1. 소개
이 명세는 [CSS-OVERFLOW-4]를 확장합니다. 현재는 변경사항(diff) 명세로, 소수의 새로운 기능만 정의하며, 오버플로우 관련 나머지 기능은 [CSS-OVERFLOW-4]를 참고하세요.
- 스크롤 내비게이션 제어
-
이 섹션에서는 스크롤러 내의 요소와 스크롤 마커를 연결하거나 (::scroll-marker 의사 요소로 자동 생성, 자동 사용자 동작 및 접근성 라벨 포함) 활성화하여 해당 요소로 스크롤할 수 있고, :target-current 의사 클래스 통해 스크롤러의 상대적 스크롤 진행률을 반영하는 기능을 정의합니다.
또한 ::scroll-button() 의사 요소를 정의하며, 이를 활성화하면 연결된 스크롤러가 지정된 방향으로 "페이지" 단위로 스크롤됩니다.
- 오버플로우 리디렉션
-
이 섹션에서는 오버플로우를 새롭게 생성된 단편화 컨테이너로 리디렉션하여 처리하는 매우 실험적이고 탐구적인 모델을 정의합니다.
2. 오버플로우 개념과 용어
최종 시에는 레벨 3 내용을 복사하세요.
2.1. 스크롤 오버플로우
스크롤 오버플로우 개념에 다음 내용이 추가됩니다:
모든 스크롤 컨테이너는 현재 스크롤 대상을 유지합니다.
초기값은 null
이며,
사용자에 의해 해당 스크롤 컨테이너에서 스크롤 작업이 수행되거나,
대상이 없는 스크립트 기반 작업,
또는 대상이 문서에서 제거될 때 null
로 초기화됩니다.
스크롤 컨테이너에서 대상 Element 또는 PseudoElement로 스크롤 작업이 발생하면,
현재 스크롤 대상이 해당
Element 또는 PseudoElement로 설정됩니다.
현재 스크롤 대상 설정은 대상을 뷰로 스크롤하는 방법에서 정의되어야 합니다.
현재 스크롤 대상을 스크롤 앵커링의 앵커 우선 후보로 사용해야 합니다.
3. 스크롤 내비게이션 제어
3.1. 스크롤 마커
스크롤 마커는 스크롤 대상을 가진 모든 요소 또는 의사 요소입니다.
요소 또는 의사 요소의 스크롤 대상은
Element
로, 스크롤 마커에 의해 지정됩니다.
어떤 요소가 스크롤 마커인지, 그리고 각 스크롤
대상이 무엇인지 여부는 호스트 언어에서 정의됩니다.
HTML <a> 요소와
SVG <a> 요소는 스크롤 마커이며,
해당 스크롤 대상은 지정된 부분입니다.
이와 같은 내비게이션 링크는 현재도 만들 수 있지만,
현재 보고 있는 콘텐츠에 대한 사용자 피드백이 부족하고,
인터랙션 모델이 많은 최신 접근성 UI 컴포넌트의 기대와 일치하지 않습니다.
이 명세는 스크롤 마커 그룹을 생성하는 메커니즘과, ::scroll-marker 의사 요소를 자동 생성하는 메커니즘을 추가합니다. 각 그룹 내에서 활성 마커는 현재 스크롤 위치를 반영하며, 사용자가 어떤 섹션에 있는지 나타내도록 스타일링할 수 있습니다.
활용 예시로는 관련 콘텐츠로 연결되는 목차, 스크롤 캐러셀 페이지의 마커, 스크롤 가능한 탭 패널 등이 있습니다.
3.1.1. 스크롤 마커 그룹화
focusgroup 속성을 가진 요소는 이 요소를 가장 가까운 상위 스크롤 마커 그룹 컨테이너로 하는 모든 스크롤 마커 요소를 포함하는 스크롤 마커 그룹을 정의합니다.
스크롤 진행 추적을 위한 마커 그룹화는 focusgroup 포커스 동작 참여와 분리되어야 합니다.
::scroll-marker-group 의사 요소는 해당 스크롤 마커 그룹 컨테이너로, 포함된 ::scroll-marker 의사 요소들이 함께 스크롤 마커 그룹을 형성합니다.
3.1.2. scroll-marker-group 속성
이름: | scroll-marker-group |
---|---|
값: | none | before | after |
초기값: | none |
적용 대상: | 스크롤 컨테이너 |
상속 여부: | 아님 |
퍼센트값: | 해당 없음 |
계산값: | 지정된 값 |
표준 순서: | 문법에 따름 |
애니메이션 타입: | 불연속 |
scroll-marker-group 속성은 스크롤 컨테이너에 '::scroll-marker-group' 의사 요소를 생성할지 여부와, 그 위치(스크롤 컨테이너 기준 위치)를 지정합니다.
- none
- 스크롤 컨테이너는 '::scroll-marker-group' 의사 요소를 생성하지 않습니다.
- before
- 스크롤 컨테이너는 ::scroll-marker-group 의사 요소를 생성하며, 해당 박스는 생성 요소 바로 앞 형제 박스입니다.
- after
- 스크롤 컨테이너는 ::scroll-marker-group 의사 요소를 생성하며, 해당 박스는 생성 요소 바로 뒤 형제 박스입니다.
3.1.3. ::scroll-marker-group 의사 요소
::scroll-marker-group 완전 스타일 가능 의사 요소는 스크롤 컨테이너 요소에서 scroll-marker-group 계산값이 none이 아닐 때 생성됩니다.
::scroll-marker-group는 생성 요소의 형제 박스로 생성되며, scroll-marker-group: before인 경우 바로 앞, scroll-marker-group: after인 경우 바로 뒤에 위치합니다.
아래의 기본 UA 스타일시트 추가를 권장합니다. ::scroll-marker 의사 요소 생성이 사이트 레이아웃에 영향을 주지 않도록 하기 위함입니다.
/* ::scroll-marker 의사 요소 생성은 * 해당 의사 요소 외 레이아웃에 영향을 주지 않아야 합니다. */ ::scroll-marker-group{ contain : size !important; }
scroll-marker-group은 암묵적으로 단일 포커스 가능한 컴포넌트처럼 동작하며, focusgroup을 형성합니다.
3.1.4. ::scroll-marker 의사 요소
::before 및 ::after와 유사하게, 모든 요소는 ::scroll-marker 의사 요소를 가질 수 있으며, 이는 가장 가까운 상위 ::scroll-marker-group의 스크롤 컨테이너로 수집되고, 활성화 시 해당 요소로 스크롤합니다.
해당 ::scroll-marker 의사 요소의 계산된 content 값이 none이 아니고, 가장 가까운 상위 스크롤 컨테이너 스크롤 컨테이너가 scroll-marker-group 계산값이 none이 아닐 때, 해당 의사 요소는 가장 가까운 상위 ::scroll-marker-group 의사 요소의 생성 박스의 자식 박스로 생성됩니다. 이러한 박스들은 자신의 트리 순서에 따라 생성 요소에 추가됩니다.
이 의사 요소들은 자신의 스크롤 대상을 생성 요소로 지정합니다.
tabindex
"-1"로 동작하여,
그룹 내에서 화살표 키로, 또는 현재 활성 상태이거나 그룹 내 첫 번째 마커일 때 Tab 키로 포커스할 수 있습니다.
이를 통해 그룹에 보장된 탭 정지점(tab
stop)을 제공합니다.
3.1.5. 활성 스크롤 마커 선택: :target-current 의사 클래스
각 스크롤 마커 그룹 내에서는 단 하나의 스크롤 마커만이 활성 상태로 결정됩니다. 이렇게 "활성" 상태인 스크롤 마커는 :target-current 의사 클래스와 일치합니다.
스크롤 작업은 특정 위치로 애니메이션될 수 있으며 (예: 스크롤바 화살표 클릭, 방향키 입력, "behavior: smooth" 프로그래밍 스크롤) 또는 사용자의 입력을 직접 추적할 수도 있습니다 (예: 터치 스크롤, 스크롤바 드래그). 어떤 경우든, 사용자 에이전트는 스크롤러가 도달할 '최종 스크롤 위치'를 선택합니다. 이로써 관련 마커가 즉시 활성화되도록 보장합니다.
이 '최종 스크롤 위치'는 각 스크롤 마커 그룹에서 활성 마커를 결정하는 데 사용됩니다. 마커 자체가 콘텐츠의 시작 부분(예: 헤더)만 나타낼 수 있기 때문에, 활성 마커는 현재 위치에 있거나 그 위치를 지난 첫 번째 마커로 간주합니다.
하나 이상의 스크롤 마커 그룹에 참여하는 스크롤 컨테이너가 스크롤되거나, 레이아웃이 최종 스크롤 위치를 변경할 때마다 사용자 에이전트는 대상 스크롤 위치에 따라 각 스크롤 마커 그룹에 대해 활성 마커를 결정하고 갱신해야 합니다.
-
scroller를 group 내 모든 스크롤 마커 요소의 가장 가까운 공통 상위 스크롤 컨테이너로 설정합니다.
-
active를 scroller로 설정합니다.
-
active가 group에서 지정된 스크롤 대상 요소를 포함하는 스크롤 컨테이너인 동안:
-
scroller를 active로 설정합니다.
-
targets를 다음으로 설정합니다: scroller가 가장 가까운 상위인 스크롤 대상 요소들과, scroller가 가장 가까운 상위인 스크롤 마커 그룹의 스크롤 컨테이너에 포함된 스크롤 대상 요소들을 포함합니다.
-
- 만약 scroller에 null이 아닌 현재 스크롤 대상이 있다면
-
active를 현재 스크롤 대상에서 역 트리 순서로 탐색해 처음 만나는 targets의 항목으로, 없으면 트리 순서의 첫 번째 항목으로 설정합니다.
- 그 외의 경우,
-
-
primary를 컨테이너의 writing-mode 기준 블록 방향의 주요 스크롤 축으로 설정합니다.
-
secondary를 primary와 수직인 스크롤 축으로 설정합니다.
-
position을 진행 중인 스크롤 작업을 고려한 '최종 스크롤 위치'로 설정합니다.
-
primary 축부터 secondary 축 순서로 각각에 대해:
-
scrollport size를 scroller의 해당 축에서의 클라이언트 크기로 설정합니다.
-
targets의 각 target에 대해, 해당 축에서 스크롤 위치 계산 후, 이 값들을 target position으로 저장합니다.
-
scroll size를 스크롤 가능한 오버플로우 영역의 해당 축 길이로 설정합니다.
-
scroll range를
scroll size - scrollport size
로 설정합니다. -
scroll range가 0보다 크면 도달 불가능한 타겟 위치를 재분배합니다:
-
distribute range를
min(1/8 * scrollport size, scroll range / 2)
로 설정합니다. -
before targets는 target position이
distribute range
보다 작은 모든 targets입니다. -
minimum position은 before targets의 최소 target position입니다.
-
before targets의 각 target의 target position을
(target position - minimum position) / (distribute range - minimum position) * distribute range
로 갱신합니다. -
after targets는 target position이
scroll range - distribute range
보다 큰 모든 targets입니다. -
maximum position은 after targets의 최대 target position입니다.
-
after targets의 각 target의 target position을
(target position - (scroll range - distribute range)) / (maximum position - (scroll range - distribute range)) * distribute range + (scroll range - distribute range)
로 갱신합니다.
-
-
selected position을 해당 축에서 position보다 작거나 같은 가장 큰 target position으로, 또는 target position이 position - scrollport size / 2보다 작고 target position이 position + scrollport size / 2보다 작은 가장 가까운 작은 값으로 설정합니다.
-
- 해당 위치가 없다면,
-
첫 번째 selected position으로 설정합니다.
-
active를 selected position과 일치하는 targets 모두로 설정합니다.
-
-
active에 여러 후보가 있다면 첫 번째 항목을 선택합니다.
-
-
-
selected marker를 active에 연결된 스크롤 마커로 설정합니다. active에 연결된 스크롤 마커가 여러 개라면, 트리 순서상 가장 먼저인 마커를 selected marker로 설정합니다.
-
selected marker를 반환합니다.
-
active marker의 활성 상태를 true로 설정합니다.
-
-
active marker가 group의 마지막으로 포커스된 요소였다면,
-
active marker에 포커스합니다.
-
-
group의 마지막으로 포커스된 요소를 active marker로 설정합니다.
-
group 내 다른 모든 스크롤 마커 요소의 활성 상태를 false로 설정합니다.
3.1.6. 활성화 동작
-
element를 해당 컨트롤의 스크롤 대상으로 설정합니다.
-
block을 "
start
"로 설정합니다. -
inline을 "
start
"로 설정합니다. -
- 활성화가 호출에 의해 트리거된 경우
-
-
하이퍼링크를 따라가며 URL을 갱신하되, 마커 요소에 포커스를 유지합니다.
참고: 사용자가 탭으로 이동하면 포커스 동작이 관련 콘텐츠로 탭이 이동하도록 보장합니다.
-
3.1.7. 포커스 동작
스크롤 마커가 활성화되면, 다음 tabindex 순서의 포커스 내비게이션은 스크롤 대상이 포커스 가능하면 해당 요소에 포커스를 맞추고, 그렇지 않으면 스크롤 대상에서 포커스된 것처럼 다음 포커스 가능한 요소를 찾습니다.
3.2. 스크롤 버튼
::scroll-button( <scroll-button-direction> ) 의사 요소는 스크롤 컨테이너에서 계산된 content 값이 none이 아닐 때 생성됩니다. 이들은 생성 요소의 바로 앞 형제 박스처럼 생성되며, content에 지정된 내용으로 박스를 만듭니다. 생성 요소의 ::scroll-marker-group 의사 요소 뒤에 존재합니다 (scroll-marker-group: before와 함께 사용할 때).
네 개의 서로 다른 ::scroll-button() 의사 요소가 스크롤 컨테이너에 존재할 수 있으며, 각각 플로우-상대적 방향과 연결됩니다. 생성 요소의 writing mode를 기준으로, 순서대로 block-start, inline-start, block-end, inline-end입니다. ::scroll-button() 의사 요소는 기본적으로 포커스 및 활성화가 가능하며, 활성화 시 생성 요소를 해당 방향으로 "페이지" 단위만큼 스크롤합니다. (일반적으로 scrollport 크기의 약 85% 정도입니다.) PgUp/PgDn 키와 유사하게 의도된 방향과 종료 위치를 가집니다.
[CSSOM-VIEW-1]에 "페이지 단위 스크롤" 알고리즘이 추가될 예정이며, 그 시점에 이 명세가 해당 알고리즘을 참조할 수 있습니다. 이슈 #10914의 결론을 참고하세요.
버튼의 순서가 최적인가? 이는 CSS의 논리적 방향의 일반적인 순서와 일치하지만, 수동으로 만든 유사 버튼들은 일반적으로 수직/수평을 각각 묶거나 (block-start/block-end 후 inline-start/inline-end), 혹은 수직이 수평을 "감싸는" 방식(block-start/inline-start/inline-end/block-end)으로 배치합니다.
네 가지 ::scroll-button() 의사 요소들은 선택자의 인자값에 따라 개별적으로 선택됩니다. 가능한 <scroll-button-direction> 값은 다음과 같습니다:
- up
- down
- left
- right
- down
-
해당 물리적 방향에 맞는 ::scroll-button()을 선택합니다.
- block-start
- block-end
- inline-start
- inline-end
- block-end
-
지정한 ::scroll-button() 의사 요소를 선택합니다.
- prev
-
block-start 또는 inline-start ::scroll-button() 중에서, 생성 요소의 축에 "스크롤 가능한 페이지"가 더 많은 쪽을 선택합니다: 생성 요소의 스크롤 가능 오버플로우 높이를 scrollport 높이로 나눈 값, 또는 너비로 계산한 값입니다.
두 축이 동일하다면, block-start ::scroll-button()을 선택합니다.
예를 들어, 생성 요소가 800px 너비, 500px 높이이고, 스크롤 가능 오버플로우 영역이 1200px 너비, 1000px 높이인 경우, 수평 스크롤은 1.5 "페이지"(1200/800), 수직 스크롤은 2 "페이지"(1000/500)입니다. (영어일 경우) ::scroll-button(prev) 선택자는 block-start 버튼을 선택합니다.
- next
-
prev와 동일하지만, block-end 또는 inline-end ::scroll-button()을 선택합니다.
여러 버튼을 한 번에 스타일링하기 쉽도록 multi-button 키워드를 추가할 필요가 있을까요? 특히 all이 유용할 것 같고, horizontal/vertical/block/inline 등도 가능성 있습니다.
::scroll-button()들은 완전 스타일링 가능한 의사 요소입니다. 적용 가능한 속성에 제한이 없습니다.
:disabled 의사 클래스는 ::scroll-button()에 적용할 수 있습니다. 버튼이 연결된 방향으로 생성 요소를 스크롤할 수 없을 때 해당 버튼과 일치합니다.
UA 스타일시트에서는 ::scroll-button()을
button
요소와 동일하게 스타일링해야 하며,
비활성(disabled) 스타일도 포함해야 합니다.
::scroll-button()이 버튼의 완전한 UA 스타일(appearance:button)을 써야 할지, 아니면 비네이티브 렌더링(appearance:none)을 써야 할지? 전자의 경우 appearance와의 상호작용을 정의해야 합니다.
3.3. 포커스 내비게이션 순서
위의 기능들은 여러 포커스 가능한 의사 요소를 생성합니다. 이 의사 요소들은 요소 트리 내에 위치가 정의되어 있지만, 포커스 내비게이션(즉 "탭 순서")에는 최적이 아닙니다.
대신, 스크롤 컨테이너와 이 섹션에서 정의된 다양한 의사 요소 간 포커스 내비게이션은 다음 순서로 진행됩니다:
-
::scroll-marker-group 의사 요소들 (스크롤 컨테이너가 scroll-marker-group: before로 설정된 경우).
참고: ::scroll-marker 의사 요소들은 스크롤 컨테이너 하위 요소에서 생성되어 이 ::scroll-marker-group 밑으로 재배치되고, "포커스 그룹"으로 함께 내비게이션됩니다.
-
::scroll-button() 의사 요소들, 정의된 순서대로.
-
스크롤 컨테이너 자체와 그 내용물, 원래 포커스 순서대로.
-
::scroll-marker-group 의사 요소들 (스크롤 컨테이너가 scroll-marker-group: after로 설정된 경우).
부록 A: 오버플로우 리디렉션
이 섹션은 매우 실험적입니다. continue 속성의 기능 확장을 바탕으로 추가적인 사용 사례 해결을 위한 최신 시도를 기록합니다. 아직 컨센서스는 없으며, 논의를 독려하기 위해 제시된 것이며 비실험적 구현은 권장되지 않습니다.
CSS 레벨 1 [CSS1]에서는 지정된 크기의 요소에 더 많은 콘텐츠를 넣는 것이 일반적으로 저작 오류였습니다. 이 경우 콘텐츠가 요소 경계를 벗어나게 되어, 다른 요소와 겹칠 수 있습니다.
CSS 레벨 2 [CSS2]에서는 overflow 속성이 도입되어, 오버플로우를 스크롤로 처리하거나, 저작 오류가 아니게 되었고, 오버플로우를 클리핑으로 처리하도록 지정할 수도 있게 되었습니다. 이는 콘텐츠를 보여주지 않으려는 저자의 의도에 부합합니다. 추가적으로 CSS Overflow Module Level 3 [CSS-OVERFLOW-3]에서 더 다듬어졌습니다.
하지만, 많은 콘텐츠를 보여주는 방법이 스크롤만 있는 것은 아니며, 최적의 방법도 아닐 수 있습니다. 대용량 저작물의 일반적인 형식으로 두루마리가 책(코덱스)으로 대체된 이유도 그 장점 때문입니다.
이 명세는 웹 페이지의 요소가 오버플로우를 스크롤 대신 페이지네이션으로 처리하도록 지정하는 메커니즘을 소개합니다.
이 명세는 오버플로우 개념도 한 단계 확장합니다. 저자가 콘텐츠가 한 영역에만 흐르도록 지정하는 대신, 여러 단편(fragment) 각각에 크기와 스타일을 지정하여, 요소의 콘텐츠가 하나에서 다음으로 흐르도록, 필요한 만큼 단편을 사용해 오버플로우 없이 배치할 수 있도록 합니다.
이 두 경우 모두, 구현에서는 블록 진행 방향으로 콘텐츠를 나누어야 합니다. CSS Fragmentation Module [CSS-BREAK-3]에 설명된 대로 처리해야 합니다.
오버플로우 채널링: continue 속성
continue 속성은 저자가 요소 내에 들어가지 않는 콘텐츠를 ( [CSS-BREAK-3] 의미의) 단편화(fragmentation)하도록 요청할 수 있게 하며, 남은 콘텐츠가 어디로 계속될지 대안을 제공합니다.
이 속성은 전통적 페이지네이션을 설명하며, 더 확장된 기능도 제공합니다.
이름: | continue |
---|---|
새 값: | overflow | paginate | fragments |
초기값: | auto |
적용 대상: | 블록 컨테이너 [CSS2], 플렉스 컨테이너 [CSS3-FLEXBOX], 그리고 그리드 컨테이너 [CSS3-GRID-LAYOUT] |
상속: | 아님 |
퍼센트값: | N/A |
계산값: | 아래 참고 |
애니메이션 타입: | 불연속 |
이 속성과 값의 이름은 임시입니다. 처음에는 "fragmentation: auto | none | break | clone | page" (https://lists.w3.org/Archives/Public/www-style/2015Jan/0357.html) 로 제안되었으며, 어떤 명칭이 더 나은지에 대해서는 아직 합의가 없습니다.
이 속성은 region-fragment를 일반화하고 대체하기 위한 것입니다. 명세에서 충분히 안정화되면 region-fragment를 regions 명세에서 제거해야 합니다.
참고: continue: fragments는 기존 명세 버전의 "overflow:fragments"를 대체하며, continue: paginate는 "overflow: paged-x | paged-y | paged-x-controls | paged-y-controls"를 대체합니다.
- auto
-
auto는 해당 요소가 CSS Region이고 region chain의 마지막이 아닐 때만 계산값으로 나타날 수 있습니다.
들어가지 않는 콘텐츠는 체인의 다음 region으로 이동합니다.
그 외 모든 경우, auto는 다른 값 중 하나로 계산됩니다.
CSS Overflow 4 § 5.3 Fragmentation of Overflow: the continue property에서는 지정값이 계산값인데, 이 정의와 다릅니다. 어떤 모델이 더 나은가요?
- overflow
- 들어가지 않는 콘텐츠는 overflow 속성에 따라 오버플로우됩니다.
- paginate
-
들어가지 않는 콘텐츠는 페이지네이션됩니다.
이는 'overflow: scroll'이 스크롤 가능한 뷰를 만드는 것처럼,
요소 내부에서 페이지네이션 뷰를 만듭니다.
페이징 오버플로우 참고
참고: 인쇄는 루트에서 "continue: paginate"와 동일하게 동작합니다.
- fragments
-
들어가지 않는 콘텐츠는 요소를 복제하여 계속 레이아웃합니다.
단편화 오버플로우 참고.
주어진 요소 또는 의사 요소의 continue 계산값은 다음과 같이 결정됩니다:
-
layout containment([CSS-CONTAIN-1] 참고)이 있는 요소나 의사 요소에서, 지정값이 auto 또는 fragments이면 계산값은 overflow입니다.
-
그 외, 지정값이 auto라면
-
CSS Region이면서 region chain의 마지막이 아닐 때, 계산값은 auto
-
페이지에서는 계산값은 paginate
-
fragment box에서는 계산값은 fragments
-
그 외에는 계산값이 overflow
-
-
그 외, 지정값이 fragments라면
-
페이지에서는 계산값은 paginate
-
그 외에는 계산값이 지정값입니다.
-
-
그 외 모든 경우, 계산값은 지정값입니다.
멀티컬럼에서 열을 선택할 수 있는 의사 요소를 도입한다면, auto가 해당 요소에서 auto로 계산됨을 명시하거나, 새로운 값을 도입해 auto가 그 값으로 계산되게 해야 합니다 (하지만 그 값이 열이 아닌 것엔 뭘로 계산되어야 할까요?).
참고: 이 속성에 대한 논의 배경은 다음 스레드를 참고하세요: overflow, overflow-x, overflow-y, overflow-style 논의와 fragmentation 속성 제안
페이지네이션 오버플로우
이 섹션에서는 paginate 값을 continue 속성에서 소개하고 정의합니다.
페이지를 @page 규칙으로 스타일링할 수 있어야 합니다. 중첩된 페이지에서는 어떻게 동작하나요?
@media ( overflow-block: paged), ( overflow-block: optional-paged) {
:root {
continue : paginate;
}
}
전통적인 페이지네이션(예: 인쇄 시)은 :root가 page box에 포함되어 있다고 가정합니다. page box가 :root의 의사 요소 자식이 아니라면, fragment box와 유사한 방법으로 해결할 수 있을까요? 또는 page box 안에 fragment box(:root 복제)를 두고, 그게 :root 안에 들어가게 할 수도 있을까요?
page box 모델이 일반 css 박스의 자식일 때 어떻게 동작하나요?
[CSS3GCPM]의 초기 제안과 오페라의 구현에서는 paginate 대신 4가지 값("paged-x | paged-y | paged-x-controls | paged-y-controls")을 사용했습니다. 이 속성에 해당 값들도 포함해야 할까요, 아니면 별도의 속성으로 처리하는 게 좋을까요? (예: "pagination-layout: auto | horizontal | vertical", "pagination-controls: auto | none")
한 번에 N개의 페이지를 보여줄 수 있을까요? "pagination-layout: horizontal 2;" 같은 값으로 표현할 수 있을까요?
Brad Kemper는 페이지네이션과 fragment overflow를 결합하는 모델(여러 페이지 표시 포함)을 제안했습니다. https://lists.w3.org/Archives/Public/www-style/2015Mar/0241.html
현재 페이지네이션 오버플로우 구현은 continue 속성 대신 [CSS3GCPM] 초안 및 [CSS3-MARQUEE] 제안에서처럼 overflow/overflow-x/overflow-y 속성을 사용합니다.
단편화된 오버플로우
이 섹션은 continue 속성의 fragments 값을 소개하고 정의합니다.
요소의 continue 계산값이 fragments일 때, 구현에서는 해당 요소에 대해 박스를 만드는 대신 fragment box 시퀀스를 생성해야 합니다. (continue: fragments인 요소가 단 하나의 fragment box만 생성할 수도 있습니다. 하지만 요소의 continue 계산값이 fragments가 아니면, 해당 박스는 fragment box가 아닙니다.) 모든 fragment box는 단편화 컨테이너이며, 해당 컨테이너가 단편화되어야 할 오버플로우가 발생하면 이전 fragment box의 다음 형제로 fragment box가 추가로 생성됩니다. 또는 요소의 다음 형제처럼 생성되는 것인가? 다른 박스 수준의 보정과의 상호작용을 정확히 정해야 함. 또한 fragment box가 [css-multicol-1] 정의에 따라 다중 컬럼 박스인 경우 여기서는 multi-column container를 정의함, 오버플로우 컬럼을 생성해야 할 콘텐츠는 대신 추가 fragment box로 흐릅니다. 그러나 fragment box 자체도 (페이지, 컬럼, 또는 다른 fragment box 등 외부 단편화 컨텍스트에 의해) 단편화될 수 있습니다; 이러한 단편화는 여러 fragment box가 아니라 동일한 fragment box의 여러 단편을 만듭니다. (fragment box는 인덱스로 스타일링될 수 있으므로 페이지에 걸쳐 fragment box가 분할되어도 인덱스와 콘텐츠의 연결이 유지됩니다.) 강제 분할이 외부 단편화 컨텍스트로 분할된다면 단일 fragment box의 새 단편이 생성되는가, 아니면 새 fragment box가 생성되는가? 여기서 fragment box보다 덜 혼란스러운 용어를 찾아야 할까?
요소가 다른 종류의 단편화 컨텍스트에서 분할된 조각을 스타일링하고 싶을 때는? 이 규칙들은 ::nth-fragment() 사용을 막으므로, 이름은 가장 논리적이지만 해당 기능에는 쓸 수 없습니다.
|
이 예제에서는 div
안의 텍스트가 일련의 카드로 분할됩니다. 이 카드들은 모두 동일한 스타일을 가집니다. 충분한 콘텐츠가 한 카드를 넘치면 또 하나의 카드가 생성됩니다. 두 번째
카드는 첫 번째 카드의 다음 형제처럼 생성됩니다. |
|
max-lines 속성을
사용하면 저자가 기사의 처음 몇 줄에 더 큰 폰트를 적용할 수 있습니다. 없으면 텍스트가 무엇이고
폰트가 어떤 것인지 플랫폼의 폰트 렌더링이 어떤 것인지 모르면 더 어렵습니다). |
continue: fragments가 일부 테이블 파트 등에는 적용되지 않도록 명확히 해야 합니다. 어떤 요소에 적용되지 않는지 정확히 결정해야 합니다.
이 명세는 어떤 종류의 단편화 컨텍스트가 생성되는지 명확히 해야 하며, break-* 속성의 어떤 값이 이 컨텍스트에서 분할을 일으키는지 밝혀야 합니다. break-*: region이 적용되길 원할 수 있습니다.
이 명세는 단편 레이아웃이 단편의 고유 크기를 사용하여 공간을 바꿀 수 있는 경우([CSS3-GRID-LAYOUT] 등) 적용되는 처리 모델이 필요합니다. [CSS-REGIONS-1]에서 이미 일부 작업이 있었으며, 그 명세의 작업과 편집자가 본 명세에 영향을 주어야 합니다.
단편 스타일링
::nth-fragment() 의사 요소
::nth-fragment() 의사 요소는 요소가 생성한 일부 fragment box를 나타내는 의사 요소입니다. 이 의사 요소의 인자는 [SELECT]에서 정의한 :nth-child() 의사 클래스와 동일한 문법을 사용하며, 의미도 동일하지만 숫자가 요소의 형제 대신 해당 요소가 생성한 fragment box 기준이라는 점만 다릅니다.
참고: 시작이 아닌 끝에서부터 카운트하여 단편을 지정하는 셀렉터는 일부러 제공하지 않습니다. 그런 셀렉터는 단편 개수 결정을 방해합니다.
향후 논의에 따라 ::nth-fragment(an+b) 문법을 ::fragment:nth(an+b)로 대체할 수 있습니다.
단편 스타일링
continue:fragments에만 적용할지, continue:paginate에도 적용할지? (적용된다면, continue:paginate에는 더 엄격한 속성 제한이 필요할 것임.)
::nth-fragment() 의사 요소가 없는 규칙이 없을 때, 각 fragment box의 계산 스타일은 해당 fragment box가 생성된 요소의 계산 스타일입니다. 하지만 fragment box의 스타일은 셀렉터 subject에 ::nth-fragment() 의사 요소가 포함된 규칙의 영향도 받습니다. (1-based 번호의 fragment box가 ::nth-fragment()와 일치하고, 셀렉터(의사 요소 제외)가 해당 요소와 일치하는 경우)
fragment box의 스타일을 결정할 때, fragment 의사 요소와 일치하는 규칙은 요소와 일치하는 규칙과 함께 캐스케이드되며, fragment 의사 요소는 의사 클래스의 특이성을 추가해 특이성 계산에 반영됩니다. 이 부분을 캐스케이드 명세에도 명확히 해야 하나요?
|
이
예제에서 div의 텍스트는 일련의 컬럼으로 분할됩니다. 저자는 아마도 텍스트가 두 컬럼을
채우길 의도했지만 세 컬럼이 채워진다면 세 번째 컬럼도 생성됩니다. 별도의 fragment
스타일이 없으면 세 번째 컬럼에는 특별한 스타일이 적용되지 않습니다. |
::nth-fragment() 의사 요소를 continue 속성으로 스타일링하면 효과가 있습니다; fragment box가 continue의 계산값이 fragments가 아니면 해당 fragment box가 마지막 단편이 됩니다. 하지만 첫 번째 fragment에 continue를 오버라이드해도 fragment box가 존재하지 않게 되지는 않으며, fragment box의 존재 여부는 요소의 overflow 계산값에 따라 결정됩니다.
::nth-fragment() 의사 요소를 content 속성으로 스타일링해도 효과가 없습니다; fragment box의 content 계산값은 요소의 content 계산값과 동일하게 유지됩니다.
display: none을 fragment box에 지정하면 해당 인덱스의 fragment box가 생성되지 않습니다. 단, 이후 fragment box에 ::nth-fragment() 의사 요소를 적용하는 인덱스 계산에는 여전히 생성된 것처럼 취급됩니다. 하지만 실제로 생성되지 않으면 콘텐츠를 포함하지 않습니다.
다른 display, position, float 값들을 지정하는 것은 허용되지만, inner display type을 바꿀 수는 없습니다. (continue는 블록 컨테이너, 플렉스 컨테이너, 그리드 컨테이너에만 적용됨.) 정확한 동작 방식을 명세해야 함
다른 의사 요소와 마찬가지로, ::nth-fragment() 의사 요소 선언은 해당 의사 요소가 없는 규칙의 선언을 오버라이드합니다. 선언 간 우선순위는 일반적인 캐스케이드 규칙([CSS2] 참고)에 따릅니다.
::nth-fragment() 의사 요소에 지정한 스타일은 해당 fragment box 내의 콘텐츠에도 상속 효과를 미칩니다. 즉, fragment box 내부의 콘텐츠는 요소가 아닌 fragment box(즉, 의사 요소)의 스타일을 상속합니다. 따라서 하나의 요소가 여러 fragment box로 분할된 경우 각 부분에 서로 다른 스타일이 적용될 수 있습니다.
이 상속 규칙을 이용하면 inherit 명시적 사용이나 ::first-letter에 적용되지 않는 속성의 기본 상속으로 직접 지정할 수 없는 스타일을 간접적으로 지정할 수 있습니다. 이는 문제일 수 있습니다. 단편 내부 스타일링에 적용되는 제한은 상속에도 동일하게 적용되어야 합니다.
|
font-size 속성을fragment에 지정하면 fragment의 자손에게 상속됩니다.
즉, 상속 속성을 fragment에서 신뢰성 있게 사용할 수 있음을 보여줍니다. |
단편 내부 스타일링
이것이 continue:fragments에만 적용되어야 하는지, 아니면 continue:paginate에도 적용되어야 하는지?
::nth-fragment() 의사 요소는 fragment box 내부의 콘텐츠를 스타일링하는 데에도 사용할 수 있습니다. ::first-line 및 ::first-letter 의사 요소와 달리, ::nth-fragment() 의사 요소는 셀렉터의 subject 이외의 부분에도 적용할 수 있습니다: 특히, subject의 조상에도 일치시킬 수 있습니다. 하지만 이러한 셀렉터를 가진 규칙에서 적용되는 CSS 속성은 ::first-letter 의사 요소에 적용되는 속성만입니다.
좀 더 정확히 말하면, 셀렉터의 subject 이외의 부분에 ::nth-fragment() 의사 요소가 붙은 규칙의 선언은, 다음 조건을 만족할 때 단편(또는 그 의사 요소)에 적용됩니다:
-
선언이 ::first-letter 의사 요소에 적용되는 속성일 것,
-
해당 선언이 ::nth-fragment() 의사 요소를 제거했을 때 그 단편(또는 그 의사 요소)에 적용될 것이며, 각 단순 셀렉터 시퀀스와 일치하는 요소 간의 특정 연관이 있을 것, 그리고
-
제거된 각 ::nth-fragment() 의사 요소에 대해, 그 단편은 해당 의사 요소가 붙은 셀렉터와 연관된 요소의 fragment box 내에 존재하며, 그 인덱스가 의사 요소와 일치해야 함.
|
부록 C: 개인정보 보호 고려사항
이 명세는 새로운 개인정보 보호 고려사항을 도입하지 않습니다.
부록 D: 보안 고려사항
이 명세는 새로운 보안 고려사항을 도입하지 않습니다.
레벨 4 이후 변경사항
감사의 글
특히 다음 분들의 피드백에 감사드립니다: Rossen Atanassov, Bert Bos, Tantek Çelik, John Daggett, fantasai, Daniel Glazman, Vincent Hardy, Håkon Wium Lie, Peter Linss, Robert O’Callahan, Florian Rivoal, Alan Stearns, Steve Zilles, 그리고 www-style 커뮤니티의 모든 분들.