1. 소개
이 섹션은 규범적이지 않습니다.
페이지 매체(예: 종이, 투명 필름, 사진 앨범 페이지, 인쇄 출력 시뮬레이션처럼 컴퓨터 화면에 표시되는 페이지)에서는 연속 매체와 달리, 문서의 콘텐츠가 하나 이상의 개별 표시 면으로 분할됩니다. 내용이 어색하게 끊어지는 것(예: 텍스트 한 줄의 중간에서 끊기는 것)을 방지하기 위해, 레이아웃 엔진은 페이지 단절에 걸리는 콘텐츠를 조정할 수 있어야 합니다. 이 과정을 페이징이라고 합니다.
CSS에서는 페이지 매체뿐만 아니라, regions [CSS3-REGIONS], 다단 레이아웃 [CSS3COL]과 같은 특정 레이아웃 기능도 유사하게 단편화된 환경을 만듭니다. 여러 컨테이너에 콘텐츠를 분할하는 일반 용어는 단편화입니다. 이 모듈은 페이지나 열과 같은 단편화 컨테이너(프래그멘테이너)에서 콘텐츠가 어떻게 분할되는지와, 이러한 분할을 작성자가 제어하는 방법을 설명합니다.
1.1. 모듈 상호작용
이 모듈은 [CSS21] 섹션 13.3 및 [CSS3PAGE]에서 정의된 페이징 제어를 대체하고 확장합니다.
1.2. 값
이 명세서는 CSS 속성 정의 규칙을 [CSS21]에서 따릅니다. 이 명세에서 정의되지 않은 값 타입은 CSS Values & Units [CSS-VALUES-3]에서 정의됩니다. 다른 CSS 모듈이 이러한 값 타입의 정의를 확장할 수 있습니다.
각 속성 정의에 나열된 속성별 값 이외에도, 이 명세에서 정의된 모든 속성은 CSS 전체 키워드를 속성 값으로 사용할 수 있습니다. 가독성을 위해 이 값들은 명시적으로 반복하지 않았습니다.
2. 단편화 모델과 용어
- 단편화 컨테이너 (프래그멘테이너)
- 페이지 박스, 열 박스, 영역 박스 등 단편화된 흐름의 일부(또는 전체)를 포함하는 박스입니다. 프래그멘테이너는 미리 정의되어 있거나 필요에 따라 생성될 수 있습니다. 블록 방향에서 분할 가능한 내용이 프래그멘테이너를 넘칠 경우, 해당 내용은 단편화 컨텍스트의 다음 컨테이너로 분할됩니다.
- 단편화 컨텍스트
- 프래그멘테이너로 이루어진 순서화된 시리즈로, 다단 컨테이너, 여러 CSS regions의 체인, 또는 페이지 매체 디스플레이에 의해 생성될 수 있습니다. 하나의 단편화 컨텍스트는 모든 프래그멘테이너에서 블록 흐름 방향이 하나만 존재할 수 있습니다. (단편화 루트의 자식들은 다른 블록 흐름 방향을 가질 수 있지만, 단편화는 단편화 루트에 적용된 블록 흐름 방향에 따라 진행됩니다.)
- 단편화된 흐름
- 단편화 컨텍스트에서 레이아웃되는 콘텐츠입니다. 단편화된 흐름은 (익명일 수 있는) 박스의 콘텐츠로 구성되며, 이 박스를 단편화 루트라고 합니다.
- 단편화 방향
- 단편화 컨텍스트의 블록 흐름 방향, 즉 콘텐츠가 단편화되는 방향입니다. (이 CSS 레벨에서는 콘텐츠가 한 차원에서만 단편화됩니다.)
- 단편화
- 콘텐츠 흐름을 프래그멘테이너로 분할하는 과정으로, 이 프래그멘테이너들은 하나의 단편화 컨텍스트를 이룹니다.
- 박스 단편 또는 단편
- 박스의 일부로, 정확히 하나의 프래그멘테이너에 속합니다. 연속 흐름의 박스는 항상 하나의 단편만을 갖습니다. 단편화된 흐름의 박스는 하나 이상의 단편으로 구성됩니다. 각 단편은 박스의 테두리, 패딩, 마진의 일부를 가지며, 자체 패딩 영역, 테두리 영역, 마진 영역을 가집니다. (단편화에 의해 이것들이 어떻게 영향을 받는지는 box-decoration-break를 참고하세요.)
- 남은 프래그멘테이너 범위
- 블록 축에서 프래그멘테이너에 대해 사용 가능한 남은 공간으로, 즉 프래그멘테이너의 이전 콘텐츠 끝과 프래그멘테이너의 경계 사이를 의미합니다.
각 단편화 단절(이하 단절) 은 현재 프래그멘테이너에서 단편화 박스의 레이아웃을 끝내고, 남은 콘텐츠를 다음 프래그멘테이너에 레이아웃하며, 경우에 따라 연기된 콘텐츠를 담기 위해 새로운 프래그멘테이너를 생성하게 됩니다.
인라인 콘텐츠를 줄로 나누는 것도 또 다른 형태의 단편화이며, 인라인 박스를 인라인 박스에서 라인 박스로 분할할 때 박스 단편을 생성합니다. 그러나 인라인 단절은 여기서 다루지 않습니다; [CSS21]/[CSS3TEXT]를 참고하세요.
박스는 텍스트의 bidi 재정렬(양방향 알고리즘)로 인해 여러 단편으로 나뉠 수도 있습니다 (양방향 재정렬 알고리즘 적용은 CSS Writing Modes 참고) 또는 상위 display type 박스 분할, 예를 들면 block-in-inline 분할(CSS2§9.2 참고) 또는 column-spanner-in-block 분할 (CSS 다단 레이아웃 참고). 이런 경우 박스 단편으로 나뉘는 것은 레이아웃(콘텐츠의 크기/위치)에 의존하지 않습니다.
2.1. 병렬 단편화 흐름
여러 포매팅 컨텍스트가 나란히 레이아웃될 때, 단편화는 각 포매팅 컨텍스트에서 독립적으로 수행됩니다. 예를 들어, 요소가 플로팅되어 있으면, float 내부에서 강제 단절이 발생해도 float 외부의 콘텐츠에는 영향을 주지 않습니다 (단, float의 높이가 증가할 수는 있습니다). UA는 조정할 수 있습니다(필수는 아니지만) 병렬 비강제 단절의 배치를 시각적으로 옆에 있는 콘텐츠와 균형을 맞추기 위해 병렬 포매팅 컨텍스트에서 조정할 수 있지만, 반드시 강제 단절과 일치시키기 위해 그렇게 해서는 안 됩니다.
다음은 병렬 흐름의 예시로, 각 콘텐츠가 독립적으로 단편화됩니다:
- float의 콘텐츠 vs. float 외부를 감싸는 콘텐츠
- float의 콘텐츠 vs. 인접한 float의 콘텐츠
- 하나의 테이블 행에 있는 각 테이블 셀의 콘텐츠
- 하나의 그리드 행에 있는 각 그리드 아이템의 콘텐츠
- 플렉스 레이아웃 행에 있는 각 플렉스 아이템의 콘텐츠
- 같은 포함 블록의 단편화 컨텍스트 범위를 덮는 절대 위치 지정 요소들 각각의 콘텐츠
고정 크기 박스의 콘텐츠 에지를 넘치는 콘텐츠는 고정 크기 박스 이후의 콘텐츠와 병렬로 간주되며, 일반적인 단편화 규칙을 따릅니다. 넘치는 콘텐츠는 단편화 루트 박스의 크기에 영향을 주지는 않지만, 단편화된 흐름의 길이를 증가시키며, 필요에 따라 추가 프래그멘테이너로 넘치거나 생성됩니다.
2.2. 중첩 단편화 흐름
프래그멘테이너 F를 분할하면, 프래그멘테이너가 두 개의 프래그멘테이너(F1 및 F2)로 나뉩니다. 단 하나의 차이점은, 프래그멘테이너 F의 콘텐츠와 관련해서, 두 조각 F1과 F2 사이의 단절 유형이 분할한 단편화 컨텍스트에 의해 생성된 단절 유형이라는 점입니다, 즉 원래 F의 단편화 컨텍스트가 생성하는 단절이 아닙니다.
3. 단절 제어
아래 섹션에서는 단편화된 흐름에서 단절이 어떻게 제어되는지 설명합니다. 두 박스 사이의 페이지/열/영역 단절 기회는 포함 블록의 break-inside 속성, 앞 요소의 break-after 속성, 그리고 뒤 요소의 break-before 속성의 영향을 받습니다. 줄 박스 사이의 페이지/열/영역 단절 기회는 포함 블록의 break-inside, widows, orphans 속성의 영향을 받습니다. 단편화 단절은 이러한 속성 값에 따라 허용, 강제, 또는 권장하지 않을 수 있습니다. 강제 단절은 해당 단절 지점에서 동작하는 모든 단절 제한을 무시합니다. 강제 페이지 단절의 경우, 작성자는 다음 콘텐츠가 어느 페이지(왼쪽 또는 오른쪽)에서 재개될지도 지정할 수 있습니다.
이러한 속성이 단편화에 어떻게 영향을 주는지에 대한 정확한 규칙은 단절 규칙 섹션을 참조하세요.
3.1. 박스 사이의 단절: break-before 및 break-after 속성
이름: | break-before, break-after |
---|---|
값: | auto | avoid | avoid-page | page | left | right | recto | verso | avoid-column | column | avoid-region | region |
초깃값: | auto |
적용 대상: | 블록 레벨 박스, 그리드 아이템, 플렉스 아이템, 테이블 행 그룹, 테이블 행(상세 내용은 본문 참고) |
상속: | 아니오 |
백분율: | 해당 없음 |
미디어: | 시각적 |
계산된 값: | 지정된 키워드 |
정식 순서: | 문법에 따름 |
애니메이션 유형: | 불연속적 |
이 속성들은 생성된 박스의 앞/뒤 페이지·열·영역 단절 동작을 지정합니다. 강제 단절 값 left, right, recto, verso, page, column, region 값은 흐름에 강제 단절을 생성하며, 단절 회피 값 avoid, avoid-page, avoid-column, avoid-region 값은 콘텐츠가 함께 유지되어야 함을 나타냅니다.
break-before와 break-after의 값은 아래 하위 섹션에서 정의되어 있습니다. 사용자 에이전트는 이 속성을 단편화 루트의 정상 흐름에 있는 박스에 적용해야 합니다. 사용자 에이전트는 또한 루트 단편화 요소의 정상 흐름에 포함 블록이 있는 플로트 박스에도 이 속성을 적용해야 합니다. 사용자 에이전트는 다른 박스에도 이 속성을 적용할 수 있습니다. 사용자 에이전트는 절대 위치 지정된 박스에는 이 속성을 적용해서는 안 됩니다.
일반 단절 값
이 값들은 흐름을 포함하는 단편화 컨텍스트의 유형과 상관없이 효과가 있습니다.
- auto
- 주요 박스 앞/뒤에서 단절을 강제하거나 금지하지 않습니다.
- avoid
- 주요 박스 앞/뒤에서 단절을 피합니다.
페이지 단절 값
이 값들은 페이징된 컨텍스트에서만 효과가 있습니다. 흐름이 페이징되지 않은 경우 효과가 없습니다.
- avoid-page
- 주요 박스 앞/뒤에서 페이지 단절을 피합니다.
- page
- 주요 박스 앞/뒤에서 항상 페이지 단절을 강제합니다.
- left
- 주요 박스 앞/뒤에 한 번 또는 두 번 페이지 단절을 발생시켜 다음 페이지가 왼쪽 페이지로 포맷되도록 합니다.
- right
- 주요 박스 앞/뒤에 한 번 또는 두 번 페이지 단절을 발생시켜 다음 페이지가 오른쪽 페이지로 포맷되도록 합니다.
- recto
- 주요 박스 앞/뒤에 한 번 또는 두 번 페이지 단절을 발생시켜 다음 페이지가 왼쪽 또는 오른쪽 페이지(페이지 펼침에서 두 번째 페이지)에 포맷되도록 합니다.
- verso
- 주요 박스 앞/뒤에 한 번 또는 두 번 페이지 단절을 발생시켜 다음 페이지가 왼쪽 또는 오른쪽 페이지(페이지 펼침에서 첫 번째 페이지)에 포맷되도록 합니다.
열 단절 값
이 값들은 다단 컨텍스트에서만 효과가 있습니다. 흐름이 다단 컨텍스트 내에 있지 않은 경우 효과가 없습니다.
- avoid-column
- 주요 박스 앞/뒤에서 열 단절을 피합니다.
- column
- 주요 박스 앞/뒤에서 항상 열 단절을 강제합니다.
영역 단절 값
이 값들은 다영역 컨텍스트에서만 효과가 있습니다. 흐름이 여러 영역에 걸쳐 연결되어 있지 않으면 효과가 없습니다.
- avoid-region
- 주요 박스 앞/뒤에서 영역 단절을 피합니다.
- region
- 주요 박스 앞/뒤에서 항상 영역 단절을 강제합니다.
3.1.1. 자식→부모 단절 전파
단절은 형제 사이에서만 허용되며, 박스와 그 컨테이너 사이에서는 허용되지 않습니다 (가능한 단절 지점 참고), 부모의 시작/끝에 있는 자식에게 적용된 단절 값은 부모로 전파되어 그곳에서 효과를 발휘할 수 있습니다.
구체적으로—
단절 전파는 계산된 값에 영향을 주지 않습니다; 이는 레이아웃을 위해 요소의 계산된 값을 해석하는 과정의 일부입니다.
3.2. 박스 내부의 단절: break-inside 속성
이름: | break-inside |
---|---|
값: | auto | avoid | avoid-page | avoid-column | avoid-region |
초깃값: | auto |
적용 대상: | 인라인 레벨 박스, 내부 루비 박스, 테이블 열 박스, 테이블 열 그룹 박스, 절대 위치 지정 박스를 제외한 모든 요소 |
상속: | 아니오 |
백분율: | 해당 없음 |
미디어: | 시각적 |
계산된 값: | 지정된 키워드 |
정식 순서: | 문법에 따름 |
애니메이션 유형: | 불연속적 |
이 속성은 요소의 주요 박스 내에서 페이지/열/영역 단절 동작을 지정합니다. 값은 아래 의미를 가집니다:
- auto
- 박스 내부에서 추가적인 단절 제약을 부여하지 않습니다.
- avoid
- 박스 내부에서 단절을 피합니다.
- avoid-page
- 박스 내부에서 페이지 단절을 피합니다.
- avoid-column
- 박스 내부에서 열 단절을 피합니다.
- avoid-region
- 박스 내부에서 영역 단절을 피합니다.
3.3. 줄 사이의 단절: orphans, widows
이름: | orphans, widows |
---|---|
값: | <integer> |
초깃값: | 2 |
적용 대상: | 인라인 포매팅 컨텍스트를 생성하는 블록 컨테이너 |
상속: | 예 |
백분율: | 해당 없음 |
미디어: | 시각적 |
계산된 값: | 지정된 정수 |
정식 순서: | 문법에 따름 |
애니메이션 유형: | 계산된 값 유형에 따름 |
orphans 속성은 단편화 단절 이전에 블록 컨테이너 내에 남겨져야 하는 최소 줄 박스 수를 지정합니다. widows 속성은 단절 이후에 블록 컨테이너 내에 남겨져야 하는 최소 줄 박스 수를 지정합니다. 이들이 단편화 단절을 제어하는 방법에 대한 예시는 아래에 나와 있습니다.
orphans와 widows의 값으로는 양의 정수만 허용됩니다. 음수 값과 0은 유효하지 않으며 선언은 무시되어야 합니다.
블록에 widows 또는 orphans 값보다 줄이 적으면, 모든 줄을 함께 유지해야 합니다.
3.4. 페이지 단절 별칭: page-break-before, page-break-after, page-break-inside 속성
CSS Level 2와의 호환을 위해 [CSS21]을 준수하는 UA는 page-break-before, page-break-after, page-break-inside 속성을 break-before, break-after, break-inside에 별칭 처리해야 하며, page-break-* 속성을 레거시 단축형으로 간주해 break-* 속성으로 다음과 같이 값 매핑 처리해야 합니다:
단축형 (page-break-*) 값 | 긴형 (break-*) 값 |
---|---|
auto | left | right | avoid | auto | left | right | avoid |
always | page |
4. 단절 규칙
단편화된 흐름은 여러 프래그멘테이너에서 가능한 단절 지점에서 나뉠 수 있습니다. 강제 단절의 경우, UA는 해당 지점에서 반드시 흐름을 분할해야 합니다. 비강제 단절의 경우, UA는 허용된 여러 단절 중에서 선택해야 합니다.
진행 보장을 위해, 프래그멘테이너는 사용된 크기에 상관없이 최소 블록 크기 1px을 가진다고 간주합니다.
4.1. 가능한 단절 지점
단편화는 블록 흐름 방향에서 박스를 분할합니다. 블록-인라인 흐름에서 단절은 다음 위치에서 발생할 수 있습니다:
- A 클래스
-
다음 유형의 형제 박스 사이:
- 블록-병렬 단편화
- 형제의 포함 블록의 블록 흐름 방향이 단편화 컨텍스트와 평행할 때: in-flow 블록 레벨 박스, float와 바로 인접한 in-flow 또는 float 박스, 테이블 행 그룹 박스, 테이블 행 박스, 다단 열 행 박스.
- 블록-수직 단편화
- 형제의 포함 블록의 블록 흐름 방향이 단편화 컨텍스트와 수직일 때: 테이블 열 그룹 박스, 테이블 열 박스, 다단 열 박스.
- B 클래스
- 블록 컨테이너 박스 내부의 줄 박스 사이.
- C 클래스
- 블록 컨테이너 박스의 콘텐츠 에지와 자식 콘텐츠의 바깥쪽 에지(블록 레벨 자식의 마진 에지 또는 인라인 레벨 자식의 줄 박스 에지) 사이에 (0이 아닌) 간격이 있을 경우.
이러한 단절 지점 클래스들 간에는 본질적인 우선순위가 없습니다. 하지만 개별 단절 지점들은 단절 제어를 통해 우선순위가 조정될 수 있습니다.
다른 레이아웃 모델이 위 클래스에 단절 지점을 추가할 수 있습니다. 예를 들어, [CSS-FLEXBOX-1]은 플렉스 포매팅 컨텍스트 내에서 A, C 클래스에 특정 지점을 추가합니다.
일부 콘텐츠는 단편화할 수 없습니다. 예를 들어 많은 교체 요소 [CSS21](이미지나 비디오 등), 스크롤 가능한 요소, 한 줄의 텍스트 콘텐츠 등이 이에 해당합니다. 이런 콘텐츠는 단일체(monolithic)로 간주되며, 가능한 단절 지점이 없습니다. 이런 박스 내에서 강제 단절이 발생해도 박스가 분할되지 않으므로, 해당 박스의 단편화 컨텍스트에서도 무시되어야 합니다.
일반적으로 단편화할 수 없는 콘텐츠 외에도, UA는 overflow가 auto 또는 scroll로 설정된 요소, overflow: hidden이며 auto가 아닌 논리적 높이(명시적 최대 논리 높이 없음)가 있는 요소도 단일체로 간주할 수 있습니다.
줄 박스에는 가능한 단절 지점이 없으므로, inline-block 및 inline-table 박스 (그리고 독립 포매팅 컨텍스트를 생성하는 기타 인라인 레벨 display type)도 단일체로 간주할 수 있습니다: 즉, 한 줄 박스가 너무 커서 프래그멘테이너에 자체적으로 들어갈 수 없고 UA가 줄 박스를 분할하기로 선택한 경우, 이러한 박스를 단편화하거나 단일체로 취급할 수 있습니다.
4.2. 단절 유형
CSS에는 프래그멘테이너 유형에 따라 정의되는 다양한 단절 유형이 있습니다:
- 페이지 단절
- 두 페이지 박스 사이의 단절. [CSS3PAGE]
- 스프레드 단절
- 서로 마주보는 페이지에 속하지 않는 두 페이지 박스 사이의 단절. 스프레드 단절은 항상 페이지 단절이기도 합니다. [CSS3PAGE]
- 열 단절
- 두 열 박스 사이의 단절. 열 박스가 다른 페이지에 있다면 단절은 페이지 단절이기도 하며, 열 박스가 다른 영역에 있다면 단절은 영역 단절이기도 합니다. [CSS3COL]
- 영역 단절
- 두 영역 사이의 단절. 영역 박스가 다른 페이지에 있다면 단절은 페이지 단절이기도 합니다. [CSS3-REGIONS]
다섯 번째 단절 유형은 줄 단절로, 두 줄 박스 사이의 단절입니다. 이 명세에서는 다루지 않으며, [CSS21] [CSS3TEXT]를 참고하세요.
4.3. 강제 단절
강제 단절은 스타일시트 작성자가 명시적으로 지정한 단절입니다. 강제 단절은 A 클래스 단절 지점에서 발생하며, 이전 형제 박스에 지정되거나 전파된 break-after 속성들과, 이후 형제 박스에 지정되거나 전파된 break-before 속성 중, 강제 단절 값이 하나라도 있으면 발생합니다. (따라서 강제 단절 값은 해당 지점에 적용되는 단절 회피 값을 무시합니다.)
하나의 단절 지점에 여러 강제 단절 값이 적용되면, 모든 단절 유형이 존중되도록 결합합니다. left, right, recto, verso가 결합될 경우, 흐름에서 가장 나중에 지정된 요소의 값이 우선합니다.
강제 페이지 단절은 마진 위쪽의 마지막 줄 박스와 아래쪽의 첫 줄 박스의 page 값이 다를 경우 A 클래스 단절 지점에서도 반드시 발생해야 합니다. [CSS3PAGE]
강제 단절이 발생하면, 이어지는 콘텐츠는 해당 단절 유형에 맞는 다음 프래그멘테이너로 들어가야 하며, 지정된 단절 유형이 모두 만족될 때까지 필요한 만큼 많은 단편화 컨텍스트를 관통합니다. 강제 단절이 일치하는 유형의 단편화 컨텍스트 내에 있지 않으면, 강제 단절은 효과가 없습니다.
4.4. 비강제 단절
단절 제어가 단절을 강제할 수 있을 뿐 아니라, 단절을 억제할 수도 있습니다. 비강제 단절은 UA가 프래그멘테이너가 오버플로우되지 않도록 자동으로 삽입하는 단절입니다. 다음 규칙은 가능한 단절 지점에서 비강제 단절이 허용되는지 제어합니다:
- 규칙 1
- 단편화된 흐름은 A 클래스 단절 지점에서 해당 단절 지점에 적용 가능한 모든 break-after 및 break-before 값이 허용해야만 분할될 수 있습니다. 즉, 하나라도 강제 단절이면 분할되고, 금지하는 값이 없으면 분할됩니다 (avoid 또는 avoid-page/avoid-column/avoid-region 등, 단절 유형에 따라 결정).
- 규칙 2
- 그러나 모두 auto이고 모든 요소의 공통 조상이 break-inside 값이 avoid라면 여기서는 분할할 수 없습니다.
- 규칙 3
- B 클래스 단절 지점에서는 단절과 시작 사이의 줄 박스 개수가 orphans 값 이상이고, 단절과 끝 사이의 줄 박스 개수가 widows 값 이상일 때만 분할할 수 있습니다.
- 규칙 4
- 추가로, B 또는 C 클래스 단절 지점에서 분할하려면 모든 조상의 break-inside 속성이 auto여야 합니다.
위 규칙만으로 프래그멘테이너가 오버플로우되지 않도록 충분한 단절 지점을 확보할 수 없다면, 규칙 3을 제거해 더 많은 단절 지점을 확보합니다.
그래도 충분하지 않으면, 규칙 1, 2, 4까지 제거해 추가 단절 지점을 찾습니다. 이때 UA는 해당 지점에 적용된 avoid 값을 새 단절 지점의 적합성 평가에 사용할 수 있지만, 이 명세는 정확한 알고리즘을 제시하지 않습니다.
그래도 충분하지 않으면 복제된 마진/테두리/패딩의 블록 끝 부분이 잘립니다; 더 공간이 필요하면 복제된 마진/테두리/패딩이 블록 끝 부분에서 잘립니다.
마지막으로, 프래그멘테이너 맨 위에 가능한 단절 지점이 없고 모든 콘텐츠가 들어가지 않는 경우, UA는 콘텐츠가 프래그멘테이너의 끝에 손실되지 않도록 아무 곳에서나 분할할 수 있습니다. 이런 경우 UA는 단일체 요소의 그래픽 표현을 잘라서 단편화할 수도 있습니다. 하지만 UA는 반드시 페이지 맨 위에서 단절해서는 안 되며, 각 프래그멘테이너에 최소한 일부 콘텐츠를 배치해 모든 프래그멘테이너에 0이 아닌 콘텐츠가 들어가도록 하여, 콘텐츠 진행을 보장해야 합니다.
4.5. 비강제 단절 최적화
CSS3는 단편화된 흐름이 반드시 허용된 단절 지점에서 분할되어 단편화 컨텍스트의 프래그멘테이너가 오버플로우되지 않도록 해야 한다고 요구하지만, 실제로 콘텐츠가 특정 허용된 단절에서 분할되는지는 정의하지 않습니다. 하지만 사용자 에이전트는 다음 가이드라인을 따를 것이 권장됩니다(때로는 모순될 수도 있음):
- 단절 횟수를 가능한 적게 유지하세요.
- 강제 단절로 끝나지 않는 모든 프래그멘테이너가 균등하게 콘텐츠로 채워진 것처럼 보이게 하세요.
- 교체 요소 내부에서 단절을 피하세요.
예를 들면 스타일시트에 orphans : 4, widows : 2이 있고, 현재 페이지 하단에 20줄(줄 박스) 공간이 있으며, 다음 블록이 정상 흐름에서 배치된다고 가정해봅시다:
- 블록에 20줄 이하의 줄 박스가 있으면, 현재 페이지에 배치해야 합니다.
- 블록에 21줄 또는 22줄이 있으면, 두 번째 단편은 widows 제약을 위반하지 않아야 하므로, 두 번째 단편에는 최소 두 줄 박스가 포함되어야 하며, 첫 번째 단편에는 최소 네 줄 박스가 포함되어야 합니다.
- 블록에 23줄 이상이 있으면, 첫 번째 단편에 20줄, 두 번째 단편에 남은 줄을 포함해야 합니다. 하지만 블록의 어느 단편이라도 현재 페이지에 배치된다면, 해당 단편에는 최소 네 줄 박스, 두 번째 단편에는 최소 두 줄 박스가 포함되어야 합니다.
이제 orphans가 10, widows가 20, 현재 페이지 하단에 8줄의 공간이 있다고 가정해봅시다:
- 블록에 8줄 이하가 있으면, 현재 페이지에 배치해야 합니다.
- 블록에 9줄 이상이 있으면, 반드시 분할되어서는 안 됩니다 (그렇게 하면 orphans 제약을 위반하므로), 전체 블록을 다음 페이지로 옮겨야 합니다.
또한 CSS는 한 가지 요구 사항을 둡니다: 크기가 0인 박스 단편은 공간을 차지하지 않으므로, 단편화 단절 이전에 프래그멘테이너에 들어갈 수 있다면 반드시 그 쪽에 나타나야 합니다.
참고: 크기가 0인 박스 단편은 바로 앞 콘텐츠가 프래그멘테이너를 오버플로우할 경우 다음 프래그멘테이너로 밀려갑니다.
5. 단절을 위한 박스 모델
이 섹션에서 사용된 크기 관련 용어는 [CSS3-SIZING]에서 정의되어 있습니다.
5.1. 다양한 크기의 프래그멘테이너로 분할
흐름이 다양한 크기의 프래그멘테이너로 분할될 때, 레이아웃 적응을 위해 다음 규칙을 따릅니다:
- 레이아웃은 각 프래그멘테이너 단위로 수행되며, 각 프래그멘테이너는 이전 프래그멘테이너의 단절점에서 진행을 이어가지만, 자신의 크기를 기준으로 전체 요소가 해당 크기 프래그멘테이너들에 분할된 것처럼 크기와 위치를 재계산합니다. 진행은 사용/남은 프래그멘테이너 범위의 백분율(절대 길이 아님) 및 사용/남은 콘텐츠 양으로 측정합니다. 단, 단일체 요소를 레이아웃할 때는 UA가 프래그멘테이너 전체에 걸쳐 일관된 인라인 크기와 결정된 블록 크기를 유지할 수도 있습니다.
- 고유 크기는 전체 요소에 대해 계산되고 유지됩니다. 고유 크기 결정을 위해 처음 포함 블록의 크기가 필요하다면, 단편화 컨텍스트를 정의하는 첫 번째 프래그멘테이너의 크기를 사용합니다.
-
이전 프래그멘테이너에서 시작된 박스의 단편은 추가 제약으로, 프래그멘테이너의 block-start 에지 위에 놓이면 안 됩니다.
이로 인해 박스의 연속 단편이 프래그멘테이너의 block-start 에지에서 멀어지면 box-decoration-break: clone이 지정된 경우,
해당 단편은 박스의 패딩/테두리 외에도 마진으로 감싸집니다.
다양한 크기의 프래그멘테이너에서 분할되는 예시.
단편화 과정에서 요소의 문서 순서는 변하지 않으므로, 단편들은 연속 매체에 적용되는 동일한 규칙에 따라 처리됩니다. 특히 float의 순서는 모든 단편에서 유지되며 CSS 2.1 9.5에 정의된 규칙을 따릅니다.
아래는 이 규칙들의 몇 가지 시사점(참고용)입니다:
- stretch-fit 또는 백분율 기반 크기로 레이아웃 제약을 만족하는 박스(테이블 포함)는 페이지마다 인라인 크기가 달라질 수 있습니다.
- min-content, max-content 또는 절대 길이 크기로 레이아웃 제약을 만족하는 박스(테이블 포함)는 페이지마다 인라인 크기가 유지됩니다.
- 블록 레벨 연속 단편은 예를 들어 블록 포매팅 컨텍스트를 생성하고 float 옆에 배치될 때, 두 요소 모두 좁아져서 나란히 배치될 수 없으면 페이지 상단 아래에 위치할 수 있습니다.
- 한 페이지에서 float 바로 뒤에 있는 요소가 다음 페이지에서 float 연속 단편 위에 오게 될 수 있습니다. 예를 들어, float이 더 이상 옆에 있는 이전 float과 나란히 배치될 수 없어서 아래로 밀려난 경우입니다.
- 왼쪽 float은 이전 오른쪽 float의 남은 단편보다 먼저 페이지에 나타날 수 있습니다. 만약 오른쪽 float이 이전 페이지에 들어가지 않는다면 그렇습니다. 하지만 또 다른 오른쪽 float은 이전 오른쪽 float의 남은 단편이 배치될 때까지 아래로 밀려납니다.
백분율 기반 진행을 보여주는 예시: 절대 위치 지정 요소가 top: calc(150% + 30px)이고 height: calc(100% - 10px)일 때, 페이징 컨텍스트(첫 페이지 높이 400px, 두 번째 페이지 200px, 세 번째 페이지 600px)에 배치하면 레이아웃 진행은 다음과 같습니다:
- 먼저 top 위치가 첫 페이지 높이에 대해 해석됩니다. 결과는 630px입니다. 첫 페이지 높이가 400px뿐이므로, 레이아웃은 두 번째 페이지로 넘어가며 진행률 400/630 = 63.49%를 기록하고 36.51%가 남습니다.
- 두 번째 페이지에서 top 위치를 두 번째 페이지 높이에 대해 다시 해석합니다. 결과는 330px입니다. 남은 36.51% 진행률은 120.5px로 해석되어, 요소의 상단 에지가 두 번째 페이지 아래쪽에서 120.5px에 배치됩니다.
- 이제 높이는 두 번째 페이지에 대해 해석되어 190px이 됩니다. 페이지에 남은 공간이 79.5px이므로, 레이아웃은 세 번째 페이지로 넘어가며 진행률 79.5/190 = 41.84%를 기록하고, 58.16%가 남습니다.
- 세 번째 페이지에서 높이는 590px이 됩니다. 남은 58.16% 진행률은 343.1px로 해석되어, 이 페이지에 맞게 배치되고 요소가 완료됩니다.
5.2. 단절 시 인접 마진
비강제 단절이 블록 레벨 박스 앞 또는 뒤에서 발생하면, 단절에 인접한 모든 마진은 0으로 잘립니다. 강제 단절이 발생하면, 단절 앞의 인접 마진만 잘리고 단절 뒤의 마진은 유지됩니다. 복제된 마진은 항상 블록 레벨 박스에서 0으로 잘립니다.
참고: CSS Fragmentation Level 4에서는 단절에서 마진 잘림 제어가 도입될 예정입니다.
5.3. 박스 분할
박스가 분할되면, 콘텐츠 박스는 남은 프래그멘테이너 범위를 채우도록 확장됩니다 (box-decoration-break: clone에 의해 적용된 마진/테두리/패딩 공간을 남기고), 그 후 다음 프래그멘테이너에서 콘텐츠가 이어집니다. (단편화 단절이 콘텐츠를 다음 프래그멘테이너로 넘기면, 박스 콘텐츠의 블록 크기가 효과적으로 증가합니다.)
박스 분할로 인해 추가된 블록 크기 (즉, 단절점에서 프래그멘테이너 에지까지의 거리)는 박스의 블록 크기에 지정된 한도에 진행률로 반영됩니다.
남은 프래그멘테이너 범위를 채우는 예시.
5.4. 단편화된 테두리와 배경: box-decoration-break 속성
이름: | box-decoration-break |
---|---|
값: | slice | clone |
초깃값: | slice |
적용 대상: | 모든 요소 |
상속: | 아니오 |
백분율: | 해당 없음 |
미디어: | 시각적 |
계산된 값: | 지정된 키워드 |
정식 순서: | 문법에 따름 |
애니메이션 유형: | 불연속적 |
박스가 (페이지/열/영역/줄) 단절로 분할될 때, box-decoration-break 속성이 제어합니다
- 박스 단편의 분할된 에지에 박스의 마진, 테두리, 패딩, 기타 장식이 감싸지는지 여부
- 배경 위치 지정 영역 [CSS3BG] (및 마스크 위치 지정 영역 [CSS-MASKING-1], 도형 reference box [CSS-SHAPES-1] 등) 이 박스 단편에서 어떻게 파생되거나 복제되고, 요소의 배경이 그 안에서 어떻게 그려지는지
값의 의미는 다음과 같습니다:
- clone
-
각 박스 단편은 테두리, 패딩, 마진으로 독립적으로 감싸집니다.
border-radius, border-image, box-shadow가 있다면,
각 단편에 독립적으로 적용됩니다.
배경은 요소의 각 단편에서 독립적으로 그려집니다.
반복 없는 배경 이미지는 요소의 각 단편에 한 번씩 렌더링됩니다.
참고: 복제된 마진은 블록 레벨 박스에서 잘림 처리됩니다.
- slice
-
요소가 단절 없이 렌더링된 다음 단절로 잘린 것처럼 동작합니다: 단절에서는 테두리와 패딩이 삽입되지 않으며, 단절된 에지에는 box-shadow가 그려지지 않습니다. 배경, border-radius, border-image는 박스 전체의 기하에 대해(분할되지 않은 것처럼) 적용됩니다.
box-decoration-break의 두 가지 동작 예시: 왼쪽은 slice 값, 오른쪽은 clone 값.
UA는 box-decoration-break를 bidi에 의해 강제된 단절(양방향 재정렬로 인해 인라인이 비연속 단편으로 분할될 때)이나 display-type에 의해 강제된 단절(상위 display type [예: 블록 레벨 박스 / 열 스패너]가 인라인 박스나 블록 컨테이너 같은 호환되지 않는 조상을 분할할 때)에도 적용해야 합니다. 그렇지 않으면 이런 단절은 slice로 처리해야 합니다. 양방향 재정렬 알고리즘 적용(CSS Writing Modes), CSS2§9.2 블록 레벨 요소 및 블록 박스, CSS 다단 레이아웃 §6 열 스팬 참고.
인라인 요소의 경우 단편의 어느 쪽이 분할된 에지로 간주되는지는 부모 요소의 인라인 진행 방향에 의해 결정됩니다. 예를 들어, 부모에 direction: rtl이 있는 인라인 요소가 두 줄로 분할되면, 첫 번째 줄의 단편에서 왼쪽 에지가 분할 에지가 됩니다. (특히 요소 자신의 direction이나 포함 블록의 direction은 사용되지 않음에 유의하세요.) [CSS3-WRITING-MODES] 참고.
5.4.1. slice 값을 위한 박스 결합
box-decoration-break: slice의 경우, 배경(및 border-image) 는 모든 박스 단편을 시각적 순서로 다시 조립한 합성 박스에 적용된 것처럼 그려집니다. 이 이론적 조립은 요소가 레이아웃된 후(정렬, bidi 재정렬, 페이지 분할 등 포함) 발생합니다. 합성 박스를 조립하려면...
- 줄에 걸쳐 분할된 박스의 경우
- 먼저, 같은 줄에 있는 단편을 시각적 순서로 연결합니다. 그 다음, 이후 줄에 있는 단편들은 요소의 인라인 기본 방향에 따라 정렬되고, 요소의 주요 기준선에 맞춥니다. 예를 들어, 왼쪽-오른쪽(ltr) 포함 블록에서는(direction이 ltr일 때) 첫 단편은 첫 줄의 가장 왼쪽에 위치하며, 이후 줄의 단편들은 오른쪽으로 배치됩니다. 오른쪽-왼쪽(rtl) 포함 블록에서는 첫 단편이 첫 줄의 가장 오른쪽에 위치하고, 이후 단편들은 왼쪽으로 배치됩니다.
- 열에 걸쳐 분할된 박스의 경우
- 단편들은 다단 컨테이너의 블록 흐름 방향에 따라 열 박스들이 붙은 것처럼 연결됩니다.
- 페이지에 걸쳐 분할된 박스의 경우
- 단편들은 루트 요소의 블록 흐름 방향에 따라 페이지 콘텐츠 영역이 붙은 것처럼 연결됩니다.
- 영역에 걸쳐 분할된 박스의 경우
- 단편들은 주요 작성 모드와 region chain의 블록 흐름 방향에 따라 영역 콘텐츠 영역을 붙인 것처럼 연결됩니다.
박스 단편의 너비(수평 결합 시 높이)가 서로 다르면, 각 단편은 자신의 너비(높이)가 전체 요소의 너비(높이)인 것처럼 배경의 일부를 그립니다. 단, 이미지의 사용 높이(너비)가 박스의 너비(높이)에서 파생될 경우, 가장 넓은 단편의 너비로 계산되어 고정 크기로 유지됩니다. 이는 오른쪽 정렬 이미지는 오른쪽 에지에, 왼쪽 정렬 이미지는 왼쪽 에지에, 가운데 정렬 이미지는 가운데에, 늘림(stretch) 이미지는 배경 영역을 제대로 덮도록 하면서 단편 간 연속성을 보장합니다.
5.5. 변환, 위치 지정 및 페이지네이션
단편화는 레이아웃과 상호작용하므로, 상대 위치 지정 [CSS21], 변환 [CSS3-TRANSFORMS], 및 기타 그래픽 효과 이전에 발생합니다. 이러한 효과는 각 단편마다 적용됩니다: 예를 들어, 회전이 단편화된 박스에 적용되면 각 단편마다 회전 원점을 계산하고 독립적으로 그 단편을 원점 기준으로 회전시킵니다. (오버플로우 전용 단편의 원점은 해당 콘텐츠가 프래그멘테이너 시작에 마진/테두리/패딩 0인 빈 박스를 오버플로우한 것처럼 결정됩니다.) 단, 인쇄 시 데이터 손실을 줄이기 위해 페이지 박스의 분리와 이동은 최종적으로 발생해야 합니다; 따라서 페이지를 넘는 변환 단편은 페이지 단절에서 잘려 인쇄되며 원래 페이지에 의해 잘리지 않고 전체가 인쇄되어야 합니다.
고정 높이 박스가 2.5페이지에 걸쳐 있고, 오버플로우 콘텐츠가 총 4페이지에 걸쳐 있습니다. 각 단편의 변환 원점은 테두리 박스의 중앙이며, 테두리 박스가 없는 단편은 오버플로우 시작 지점에 높이 0 박스를 가정합니다.
절대 위치 지정은 레이아웃에 영향을 주므로 단편화와 상호작용합니다. 좌표계와 포함 블록에 속한 절대 위치 지정 박스는 포함 블록과 동일한 단편화 흐름에서 프래그멘테이너를 따라 분할됩니다.
UA는 단편화 단절을 넘는 박스의 block-start 에지 위치가 박스 콘텐츠 단편화 위치에 따라 달라지는 경우, 박스를 정확히 배치할 필요는 없습니다.
문서 전체를 메모리에 조작할 수 없는 UA는 이전에 렌더링된 페이지에 위치하게 되는 절대 위치 지정 요소를 정확히 배치할 필요는 없습니다.
변경 사항
2016년 1월 14일 후보 권고안 이후 주요 변경 사항은 다음과 같습니다:
-
page-break-* 속성의 별칭 메커니즘을 명확히 기술함.
(이슈 866)
page-break-* 속성을
shorthands레거시 단축형 으로 처리하여 break-* 속성에 적용 - 단절 전파가 계산된 값에 영향을 주지 않으며, flex, grid 등 다른 레이아웃 모드가 기본 전파 규칙을 조정함을 명확히 기술. 자식→부모 전파 시 out-of-flow 자식은 무시함. (이슈 2614) §3.1.1 자식→부모 단절 전파 참고.
-
widows와 orphans가 직접 줄 박스를 포함하지 않는 블록 컨테이너에는 효과가 없음을 명확히 기술.
(이슈 1823)
적용 대상: 블록 컨테이너 중 새로운 인라인 포매팅 컨텍스트를 생성하는 것
-
C 클래스 단절에 인접한 마진도
형제 사이(A 클래스)와 동일하게 잘림을 명확히 기술.
(이슈 3073)
비강제 단절이 발생할 때
between블록 레벨 박스 앞 또는 뒤에서es, 단절에 인접한 모든 마진은truncate to the 남은 프래그멘테이너 범위 before the break, and0으로 잘림.after the break. -
UA가 atomic inlines를 단일체로 처리하지 않기로 선택한 경우 의미를 명확히
기술.
(이슈 1111)
줄 박스에는 가능한 단절 지점이 없으므로, inline-block 및 inline-table 박스 (그리고 독립 포매팅 컨텍스트를 생성하는 기타 인라인 레벨 display type)도 단일체로 간주할 수 있음 즉, 한 줄 박스가 너무 커서 프래그멘테이너에 자체적으로 들어갈 수 없고 UA가 줄 박스를 분할하기로 선택한 경우, 해당 박스를 단편화하거나 단일체로 처리할 수 있음 .
-
크기 0 단편은 반드시 이전 프래그멘테이너에 남아야 한다는 요구사항 추가.
(이슈 1529)
또한 CSS는 한 가지 요구 사항을 둡니다: 크기가 0인 박스 단편 은 공간을 차지하지 않으므로, 단편화 단절 이전에 프래그멘테이너에 들어갈 수 있다면 반드시 그곳에 나타나야 합니다.
크기 0인 박스 단편은 바로 앞 콘텐츠가 프래그멘테이너를 오버플로우할 경우 다음 프래그멘테이너로 밀려갈 수 있습니다.
-
bidi 강제 단절 및 block-in-inline 단절이 단편을
생성하며,
이들의 서식은 box-decoration-break로 제어해야 함을 명확히 기술.
(이슈 1706)
박스는 텍스트의 bidi 재정렬로 인해 여러 단편으로 나뉠 수도 있고, (양방향 재정렬 알고리즘 적용은 CSS Writing Modes 참고) 또는 상위 display type 박스 분할, 예를 들면 block-in-inline 분할(CSS2§9.2 참고) 또는 column-spanner-in-block 분할 (CSS 다단 레이아웃 참고). 이런 경우 박스 단편으로 나뉘는 것은 레이아웃(크기/위치)에 의존하지 않습니다.
UA는
mayshould bidi 강제 단절(양방향 재정렬로 인해 인라인이 비연속 단편으로 분할될 때) 및 display-type 강제 단절(상위 display type [예: 블록 레벨 박스 / 열 스패너]가 인라인 박스나 블록 컨테이너 같은 호환되지 않는 조상을 분할할 때)에도 box-decoration-break 적용으로 서식을 제어해야 합니다. 그렇지 않으면 이런 단절은 slice로 처리해야 합니다. 양방향 재정렬 알고리즘 적용(CSS Writing Modes), CSS2§9.2 블록 레벨 요소 및 블록 박스, CSS 다단 레이아웃 §6 열 스팬 참고. - 사소한 문구 수정.
의견 처리 결과가 제공됩니다.
2015년 1월 29일 작업 초안 이후 주요 변경 사항은 다음과 같습니다:
- any 및 always 값을 break-*에서 제거함.
- widows와 orphans vs. break-* 제한의 우선순위를 바꿔, widows와 orphans가 더 낮은 우선순위를 갖도록 함.
- box-decoration-break: clone에 대해 마진도 복제(단, 블록 레이아웃에서는 잘림)하도록 정의.
- 새로운 단절 유형(Class A) 처리 위해 비강제 단절 규칙 수정(기존 규칙은 페이지 단절만 처리).
- 공간 부족 시 복제된 박스 장식(clone)을 생략 가능하도록 허용.
의견 처리 결과가 제공됩니다.
감사의 글
편집자들은 Mihai Balan, Michael Day, Alex Mogilevsky, Shinyu Murakami, Florian Rivoal, 그리고 Alan Stearns에게 이 모듈에 대한 기여에 대해 감사의 뜻을 전합니다. 특별히 이전 [CSS3PAGE] 편집자인 Jim Bigelow(HP), Melinda Grant(HP), Håkon Wium Lie(Opera), 그리고 Jacob Refstrup(HP)에게 이 명세에 공헌해 주신 점에 특별한 감사를 표합니다. 이 명세는 그들의 작업의 후속작입니다.