1. 작성 모드 소개
CSS 작성 모드 레벨 4는 라틴/인도계와 같은 좌에서 우, 히브리어나 아랍계와 같은 우에서 좌, 라틴과 아랍의 혼합과 같은 양방향, 그리고 아시아 문자와 같은 수직 등 다양한 국제적 작성 모드를 지원하기 위한 CSS 기능을 정의합니다.
CSS의 작성 모드는 writing-mode, direction, 그리고 text-orientation 속성에 의해 결정됩니다. 주로 인라인 기준 방향과 블록 흐름 방향으로 정의됩니다:
인라인 기준 방향은 한 줄에서 콘텐츠가 정렬되는 주요 방향을 의미하며, 줄의 "시작"과 "끝"이 어느 쪽인지를 정의합니다. direction 속성은 박스의 인라인 기준 방향을 지정하며, unicode-bidi 속성 및 텍스트 콘텐츠의 내재적 방향성과 함께 한 줄 내 인라인 수준 콘텐츠의 정렬을 결정합니다.
블록 흐름 방향은 블록 수준 박스가 쌓이는 방향, 그리고 블록 컨테이너 내에서 라인 박스가 쌓이는 방향을 의미합니다. writing-mode 속성이 블록 흐름 방향을 결정합니다.
타이포그래픽 모드는 수직 문자에 대해 수직 흐름에 특화된 타이포그래픽 규칙을 적용할지 여부를 결정합니다. 이 개념은 수직 문자의 수직 흐름과 회전된 수평 흐름을 구분합니다.
수평 작성 모드는 수평 줄의 텍스트(즉, 아래쪽 또는 위쪽 블록 흐름)를 가진 모드입니다. 수직 작성 모드는 수직 줄의 텍스트(즉, 왼쪽 또는 오른쪽 블록 흐름)를 가진 모드입니다.
이 용어들은 수직 블록 흐름(아래쪽 또는 위쪽 블록 흐름)과 수평 블록 흐름(왼쪽 또는 오른쪽 블록 흐름)과 혼동해서는 안 됩니다. 혼동을 피하기 위해 CSS 명세에서는 후자의 용어 사용을 피합니다.
문자 체계는 일반적으로 하나 또는 두 개의 고유 작성 모드를 가지고 있습니다. 예시는 다음과 같습니다:
- 라틴계 시스템은 일반적으로 좌에서 우 인라인 방향과 아래(상에서 하) 블록 흐름 방향으로 작성됩니다.
- 아랍계 시스템은 일반적으로 우에서 좌 인라인 방향과 아래(상에서 하) 블록 흐름 방향으로 작성됩니다.
- 몽골계 시스템은 일반적으로 상에서 하 인라인 방향과 오른쪽(좌에서 우) 블록 흐름 방향으로 작성됩니다.
- 한자계 시스템은 일반적으로 좌에서 우 인라인 방향과 아래(상에서 하) 블록 흐름 방향 또는 상에서 하 인라인 방향과 왼쪽(우에서 좌) 블록 흐름 방향으로 작성됩니다. 많은 잡지와 신문은 같은 페이지에서 이 두 작성 모드를 혼합하여 사용합니다.
작성 모드의 text-orientation 구성 요소는 글리프 방향을 제어합니다.
작성 모드와 수직 텍스트에 대해 더 깊은 소개는 Unicode Technical Note #22 [UTN22] (HTML 버전)을 참고하세요.
1.1. 모듈 상호작용
이 모듈은 unicode-bidi와 direction 기능을 [CSS2] 8.6, 9.10절을 바탕으로 대체 및 확장합니다. 이 기능들이 다른 텍스트 작업과 상호작용하여 줄을 설정하는 방식은 CSS Text 3 § Text Processing Order of Operations에서 설명합니다.
computed values는 writing-mode, direction, 그리고 text-orientation 속성에서(이 속성이 적용되지 않는 요소에도 [CSS-CASCADE-4]처럼) 넓게 다른 속성의 computed value에 영향을 줄 수 있습니다. 예를 들어 font-relative lengths의 계산이나 flow-relative properties의 계단식 적용 등에서 writing mode 또는 폰트 메트릭이 writing mode에 따라 달라질 수 있습니다.
1.2. 값 타입 및 용어
이 명세는 CSS 속성 정의 관례를 [CSS2]에서 따릅니다. 이 명세에서 정의되지 않은 값 타입은 CSS Values & Units [CSS-VALUES-3]에서 정의됩니다. 다른 CSS 모듈이 이러한 값 타입의 정의를 확장할 수 있습니다.
속성 정의에 명시된 고유 값 외에도, 이 명세에서 정의된 모든 속성은 CSS-wide keywords 키워드를 속성 값으로 사용할 수 있습니다. 가독성을 위해 명시적으로 반복하지 않았습니다.
이 명세에서 사용되는 기타 중요한 용어와 개념은 [CSS2] 및 [CSS-TEXT-3]에서 정의되어 있습니다.
2. 인라인 방향 및 양방향성
대부분의 문자 체계에서는 문자가 좌에서 우로 쓰이지만, 일부 문자 체계는 우에서 좌로 쓰입니다. 특히 아랍어나 히브리어로 작성된 문서 및 혼합 언어 환경에서는 하나의(화면에 표시된) 블록 내에 혼합된 방향성이 나타날 수 있습니다. 이 현상을 양방향성 또는 "bidi"라고 합니다.
양방향성
Unicode 표준(Unicode Standard Annex #9)은 양방향 텍스트의 올바른 정렬을 결정하기 위한 복잡한 알고리즘을 정의합니다. 이 알고리즘은 문자 속성을 기반으로 한 암시적 부분과, 임베딩 및 오버라이드를 위한 명시적 제어로 구성됩니다. CSS는 올바른 양방향 렌더링을 위해 이 알고리즘에 의존합니다.
CSS에는 direction과 unicode-bidi 두 가지 속성이 있으며, CSS 계층에서 임베딩, 분리(isolation), 오버라이드 제어를 제공합니다. 텍스트의 기본 방향성은 문서의 구조와 의미에 따라 다르므로, direction과 unicode-bidi 속성은 대부분의 경우 마크업의 bidi 정보를 대응하는 CSS 스타일에 매핑하는 용도로만 사용해야 합니다.
HTML 명세([HTML401], 8.2절 및 [HTML5], 10.3.5절)는 HTML 요소의 양방향성 동작을 정의합니다.
문서 언어가 bidi 제어를 위한 마크업 기능을 제공한다면, 작성자와 사용자는 그 기능을 우선 활용해야 하며 CSS 규칙으로 이를 오버라이드해서는 안 됩니다.
2.1. 방향 지정: direction 속성
이름: | direction |
---|---|
값: | ltr | rtl |
초기값: | ltr |
적용 대상: | 모든 요소 |
상속됨: | yes |
백분율: | 해당 없음 |
계산된 값: | 지정 값 |
정규 순서: | 해당 없음 |
애니메이션 타입: | 애니메이션 불가 |
HTML UA가 CSS 스타일링을 꺼버릴 수 있으므로, HTML 작성자에게는 HTML dir
속성과 <bdo> 요소를
사용하여 스타일 시트가 없어도 올바른 양방향 레이아웃이 되도록 할 것을 권장합니다. 작성자는 HTML 문서에서 direction을 사용하지 않아야 합니다.
이 속성은 박스가 설정하는 모든 bidi 문단, 임베딩, isolate, 오버라이드의 인라인 기준 방향 또는 방향성을 지정합니다. (unicode-bidi 참고.) 또한 table 열 레이아웃의 순서, 수평 overflow의 방향, 줄 내 텍스트의 기본 정렬, 박스의 인라인 기준 방향에 따라 달라지는 기타 레이아웃 효과에도 영향을 줍니다.
이 속성의 값 의미는 다음과 같습니다:
- ltr
- 이 값은 인라인 기준 방향(bidi 방향성)을 줄-왼쪽에서 줄-오른쪽으로 설정합니다.
- rtl
- 이 값은 인라인 기준 방향(bidi 방향성)을 줄-오른쪽에서 줄-왼쪽으로 설정합니다.
direction 속성은 unicode-bidi 값이 normal인 인라인 박스에 지정된 경우에는 양방향 재정렬에 영향을 주지 않습니다. 이 경우, 박스는 양방향 알고리즘에 대해 추가적인 임베딩 레벨을 열지 않기 때문입니다.
direction 속성은 테이블 열 박스에 지정된 경우, 열이 문서 트리에서 셀의 상위 요소가 아니기 때문에 열 내 셀에 상속되지 않습니다. 따라서 CSS는 [HTML401] 11.3.2.1절에서 설명하는 "dir" 속성 상속 규칙을 쉽게 구현할 수 없습니다.
2.2. 임베딩 및 오버라이드: unicode-bidi 속성
이름: | unicode-bidi |
---|---|
값: | normal | embed | isolate | bidi-override | isolate-override | plaintext |
초기값: | normal |
적용 대상: | 모든 요소(자세한 내용은 본문 참조) |
상속됨: | 아니오 |
백분율: | 해당 없음 |
계산된 값: | 지정 값 |
정규 순서: | 문법에 따름 |
애니메이션 타입: | 애니메이션 불가 |
HTML UA는 CSS 스타일을 끌 수 있으므로, HTML 작성자에게는 HTML dir
속성, <bdo> 요소, 그리고
텍스트 수준 vs 그룹 수준 HTML 요소 타입의 적절한 구분을 활용하여 스타일 시트가 없어도 올바른 양방향 레이아웃을 보장할 것을 권장합니다. 작성자는
HTML 문서에서 unicode-bidi를 사용하지 않아야 합니다.
일반적으로(unicode-bidi가 normal일 때) 인라인 박스는 유니코드 bidi 알고리즘에서 투명하게 처리됩니다. 콘텐츠는 박스의 경계가 없는 것처럼 정렬됩니다. unicode-bidi 속성의 다른 값들은 인라인 박스가 알고리즘 내에서 영역을 만들고, 텍스트의 고유 방향성을 오버라이드합니다.
아래의 안내 표는 unicode-bidi의 박스 내부 및 외부 효과를 요약합니다:
외부 | |||
---|---|---|---|
강함 | 중립 | ||
내부 | 영역 | embed | isolate |
오버라이드 | bidi-override | isolate-override | |
plaintext | — | plaintext |
이 속성 값의 의미는 다음과 같습니다(규범적):
- normal
- 박스는 양방향 알고리즘에 대해 추가 임베딩 레벨을 열지 않습니다. 인라인 박스에서는 암시적 재정렬이 박스 경계를 넘어 작동합니다.
- embed
-
박스가 인라인인 경우, 이 값은 양방향 알고리즘에 대해 추가 임베딩 레벨을 열어 방향 임베딩을 만듭니다.
이 임베딩 레벨의 방향은 direction 속성으로 결정됩니다. 박스 내부에서는 암시적으로 재정렬됩니다.
인라인이 아닌 박스에는 아무런 효과가 없습니다.
- isolate
-
인라인 박스에서는 이 값이 bidi-isolate
효과를 냅니다.
방향 임베딩과 유사하며 임베딩 레벨이 증가하지만,
블록 경계나 강제 문단
나누기 없이 연속된 인라인 박스 시퀀스마다 isolated sequence로 취급됩니다:
- 시퀀스 내 콘텐츠는 박스의 direction 속성으로 지정된 기준 방향을 갖는 독립 문단처럼 정렬됩니다.
- 포함하는 양방향 문단에서, 시퀀스는 단일 객체 대체 문자(U+FFFC)로 취급됩니다.
인라인이 아닌 박스에는 아무런 효과가 없습니다.
- bidi-override
- 이 값은 박스의 즉각적인 인라인 콘텐츠에 방향 오버라이드를 적용합니다. 인라인인 경우, 박스는 양방향 알고리즘에서 방향 임베딩처럼 동작하지만, 내부 재정렬은 direction 속성에 따라 엄격하게 순서대로 이루어집니다. 양방향 알고리즘의 암시적 부분은 무시됩니다. 블록 컨테이너에서는 모든 콘텐츠를 감싸는 익명 인라인 박스에 오버라이드가 적용됩니다.
- isolate-override
- 이 값은 isolation 동작(isolate)과 directional override(bidi-override) 동작을 결합합니다: 주변 콘텐츠에는 isolate와 동일하게 동작하지만, 박스 내부에서는 bidi-override가 지정된 것처럼 콘텐츠가 정렬됩니다. 즉, 방향 오버라이드가 isolated sequence 안에 중첩됩니다.
- plaintext
-
이 값은 isolate와 동일하게 동작하지만, 유니코드 양방향 알고리즘에서는 박스의 bidi 문단(블록 컨테이너인 경우)이나 isolated sequence(인라인인 경우)의 기준 방향이 박스의 direction 속성이 아닌, 유니코드 양방향 알고리즘의 규칙 P2, P3 휴리스틱을 따릅니다.
유니코드 양방향 알고리즘 HL3 절 [UAX9]에 따라, normal이 아닌 값은 해당 유니코드 bidi 제어 코드를 인라인 요소의 시작과 끝에 텍스트 스트림에 삽입한 후, 문단을 유니코드 양방향 알고리즘에 전달하여 재정렬합니다. (§ 2.4.2 CSS–Unicode Bidi Control Translation, Text Reordering 참고.)
unicode-bidi 값 | direction 값 | |||
---|---|---|---|---|
ltr | rtl | |||
시작 | 끝 | 시작 | 끝 | |
normal | — | — | — | — |
embed | LRE (U+202A) | PDF (U+202C) | RLE (U+202B) | PDF (U+202C) |
isolate | LRI (U+2066) | PDI (U+2069) | RLI (U+2067) | PDI (U+2069) |
bidi-override* | LRO (U+202D) | PDF (U+202C) | RLO (U+202E) | PDF (U+202C) |
isolate-override* | FSI,LRO (U+2068,U+202D) | PDF,PDI (U+202C,U+2069) | FSI,RLO (U+2068,U+202E) | PDF,PDI (U+202C,U+2069) |
plaintext | FSI (U+2068) | PDI (U+2069) | FSI (U+2068) | PDI (U+2069) |
* LRO/RLO+PDF 쌍은 해당 루트 인라인 박스가 블록 컨테이너인 경우에도 unicode-bidi 값이 지정되었다면 적용됩니다. |
unicode-bidi 속성은 상속되지 않으므로, 블록 박스에 bidi-override나 plaintext를 지정해도 하위 블록에는 영향을 주지 않습니다. 따라서 이런 값은 블록과 인라인에 블록 수준 구조가 없는 경우에 사용하는 것이 좋습니다.
unicode-bidi는 direction 속성에 영향을 주지 않으며, plaintext의 경우에도 direction 기반 레이아웃 계산에는 영향을 주지 않습니다.
유니코드 알고리즘은 최대 125개의 임베딩 레벨 제한이 있으므로, unicode-bidi 값 중 normal이 아닌 값은 과도하게 사용하지 않도록 주의해야 합니다. 특히 inherit 값은 인라인 중첩이 깊을 때 매우 신중하게 사용해야 합니다. 하지만 일반적으로 블록으로 표시되는 요소에는 unicode-bidi: isolate를 지정하는 것이 좋으며, display가 inline으로 변경될 경우에도 요소가 함께 유지됩니다(아래 예시 참고).
2.3. 양방향 텍스트 예시
아래 예시는 양방향 텍스트가 포함된 XML 문서를 보여줍니다. 중요한 설계 원칙을 설명하는데, 문서 언어 설계자는 bidi를 언어(요소와 속성)와 스타일 시트 모두에서 고려해야 합니다. 스타일 시트는 bidi 규칙을 다른 스타일 규칙과 별도로 설계해야 하며, 문서 언어의 bidi 동작이 유지되도록 다른 스타일 시트에서 이러한 규칙을 오버라이드하지 않아야 합니다.
이 예시에서 소문자는 본질적으로 좌에서 우 문자, 대문자는 본질적으로 우에서 좌 문자를 나타냅니다. 텍스트 스트림은 아래 논리적 저장소 순서로 나타납니다.
<section dir=rtl> <para>HEBREW1 HEBREW2 english3 HEBREW4 HEBREW5</para> <para>HEBREW6 <emphasis>HEBREW7</emphasis> HEBREW8</para> </section> <section dir=ltr> <para>english9 english10 english11 HEBREW12 HEBREW13</para> <para>english14 english15 english16</para> <para>english17 <quote dir=rtl>HEBREW18 english19 HEBREW20</quote></para> </section>
이것은 임의의 XML이므로, 스타일 시트가 작성 방향을 설정합니다. 스타일 시트 예시는 다음과 같습니다:
/* 양방향 규칙 */ [dir=rtl] {direction: rtl; unicode-bidi: isolate; } [dir=ltr] {direction: ltr; unicode-bidi: isolate; } /* 표시 규칙 */ section, para {display: block;} emphasis {font-weight: bold;} quote {font-style: italic;}
줄 길이가 길면, 텍스트 서식은 다음과 같이 될 수 있습니다:
5WERBEH 4WERBEH english3 2WERBEH 1WERBEH 8WERBEH 7WERBEH 6WERBEH english9 english10 english11 13WERBEH 12WERBEH english14 english15 english16 english17 20WERBEH english19 18WERBEH
첫 번째 <section>
요소는 우에서 좌 기준 방향의 블록이고,
두 번째 <section>
요소는 좌에서 우 기준 방향의 블록입니다.
<para>
들은 부모로부터 기준 방향을 상속받는 블록입니다.
따라서 첫 두 <para>
는 오른쪽 위에서 시작해 읽고,
마지막 세 개는 왼쪽 위에서 시작해 읽습니다.
<emphasis>
요소는 인라인 수준이며,
unicode-bidi 값이 normal이므로(초기값),
텍스트의 순서에는 영향을 주지 않습니다.
<quote>
요소는 내부 방향성을 가진 isolated sequence를 만듭니다.
이로 인해 HEBREW18이 english19의 오른쪽에 위치하게 됩니다.
줄을 나눠야 한다면, 같은 텍스트의 서식은 다음과 같이 될 수 있습니다:
2WERBEH 1WERBEH -EH 4WERBEH english3 5WERB -EH 7WERBEH 6WERBEH 8WERB english9 english10 en- glish11 12WERBEH 13WERBEH english14 english15 english16 english17 18WERBEH 20WERBEH english19
HEBREW18을 english19보다 먼저 읽어야 하므로, english19 위 줄에 위치하게 됩니다. 이전 서식에서 긴 줄을 그냥 나누는 것만으로는 올바르게 동작하지 않습니다.
english19의 첫 음절이 이전 줄에 들어갈 수도 있지만, 우에서 좌 컨텍스트에서 좌에서 우 단어의 하이픈 분리, 그 반대도 일반적으로 줄 중간에 하이픈을 표시하지 않으려 억제됩니다.
2.4. 양방향 재정렬 알고리즘 적용
양방향 텍스트를 지원하는 사용자 에이전트는 블록 경계나 "bidi type B" 강제 문단 나누기로 중단되지 않는 인라인 수준 박스의 모든 시퀀스에 대해 유니코드 양방향 알고리즘을 적용해야 합니다. 이 시퀀스는 양방향 알고리즘에서 문단 단위를 형성합니다.
2.4.1. 양방향 문단 임베딩 레벨
CSS에서는 문단 임베딩 레벨을 (UAX9 HL1 절에 따라) 유니코드 알고리즘의 단계 P2, P3에서 제시된 휴리스틱이 아니라, 문단을 포함하는 블록의 direction 속성에 따라 설정해야 합니다.
단, 예외가 하나 있습니다: 문단을 포함하는 블록의 계산된 unicode-bidi 값이 plaintext일 경우, [UAX9]에서 설명된 대로 유니코드 휴리스틱(P2, P3)이 HL1 오버라이드 없이 사용됩니다.
2.4.2. CSS–Unicode 양방향 제어 변환, 텍스트 재정렬
각 양방향 문단 내 문자들의 최종 순서는 위에서 설명한 unicode-bidi에 따라 양방향 제어 코드가 추가되고, 마크업이 제거된 후, 결과 문자 시퀀스가 스타일링된 텍스트와 동일한 줄 나누기를 생성하는 일반 텍스트용 유니코드 양방향 알고리즘 구현에 전달된 것과 동일합니다.
원본 텍스트에 포함된 양방향 제어 코드는 여전히 적용되며, 문서 트리 구조와 일치하지 않을 수 있습니다. 이는 인라인을 분할하거나 양방향 시작/종료 제어 쌍에 영향을 줄 수 있습니다.
2.4.3. 원자 인라인의 양방향 처리
이 과정에서 대체 요소가 display: inline일 경우, unicode-bidi 속성이 embed 또는 bidi-override가 아닌 한, 중립 문자로 처리됩니다. 해당 속성 값일 경우에는 요소에 지정된 direction 방향의 강한 문자로 처리됩니다. (이는 대체 요소가 인라인 텍스트 콘텐츠로 렌더링될 경우, 주변 텍스트에 미치는 양방향 효과가 대체 렌더링과 일치하도록 하기 위함입니다.)
그 외의 모든 원자 인라인 수준 박스는 항상 중립 문자로 처리됩니다.
2.4.4. 임베딩 및 아이솔레이트 내의 문단 나누기
인라인 박스가 양방향 문단 경계(예: 블록이나 강제 문단 나누기로 분할되는 경우)에서 나뉘면, 박스 끝에 할당된 HL3 양방향 제어 코드가 중단 전에도 추가되고, 박스 시작에 할당된 코드가 중단 후에도 추가됩니다. (즉, 박스가 시작한 임베딩 레벨, 아이솔레이트, 오버라이드는 문단 나누기에서 닫히고, 반대쪽에서 다시 열립니다.)
예를 들어, <BR/>이 강제 문단 나누기인 경우, 양방향 정렬은 다음 두 경우에 대해 동일합니다:
<para>...<i1><i2>...<BR/>...</i2></i1>...</para>
그리고
<para>...<i1><i2>...</i2></i1><BR/><i1><i2>...</i2></i1>...</para>
인라인 요소 <i1> 및 <i2>에 대해 모든 unicode-bidi 값에 대해 동일합니다.
이 동작은 박스 트리에 적용된 CSS 선언 양방향 제어에 대해 CSS가 적용하며, 유니코드의 양방향 포맷팅 제어에는 적용되지 않습니다. 유니코드 제어는 양방향 문단 끝에서 그 효과가 종료되도록 정의됩니다.
2.4.5. 재정렬에 의한 박스 단편화
양방향 재정렬은 논리적으로 연속적인 텍스트를 분할하고 재배열할 수 있으므로, 양방향 텍스트는 해당 텍스트를 포함하는 인라인 박스를 분할하여 그 단편들이 한 줄 내에서 재배열되게 만들 수 있습니다.
2.4.5.1. 재정렬에 의한 박스 단편화 조건
양방향 재정렬로 인해 인라인 박스가 중간의 콘텐츠로 분할될 경우, 인라인 박스는 여러 박스 단편으로 나뉜 것으로 간주합니다. [CSS-BREAK-3] 박스는 무한히 긴 줄에서 중간 콘텐츠로 인해 분할될 경우 단편화된 것으로 간주합니다. 줄 나누기로 인해 두 박스 단편이 한 줄에 인접하더라도 마찬가지입니다. 이런 경우, 두 박스 단편에 속한 텍스트의 가장 가까운 공통 조상(텍스트 서식의 일부 측면, 예: 트래킹 및 정렬에 영향을 줌, [CSS-TEXT-3] 참고)은 두 박스 단편의 가장 가까운 공통 조상으로 간주하며, 인라인 박스 그 자체는 아닙니다. 단, 인라인 박스가 양방향 재정렬로 인해 중간 콘텐츠가 없으면 여러 박스 단편으로 분할된 것으로 간주하지 않습니다. (이 규칙들은 인라인 박스의 무결성을 최대한 유지하면서, 줄 바꿈 변화에도 양방향 단편화의 안정성을 보장합니다.)
<em>
의 인라인 박스가
<em>
외부 콘텐츠에 의해 두 박스 단편으로 분할됩니다.
소스 코드(논리 순서):
<p>here is <em>some MIXED</em> TEXT.</p>
넓은 컨테이닝 블록에서의 렌더링(시각적 순서), 외부 콘텐츠로 인해 두 개의 인라인 박스 단편이 분리됨:
here is some TXET DEXIM.
좁은 컨테이닝 블록에서의 렌더링(시각적 순서), 두 인라인 박스 단편이 인접하여 배치됨:
here is some DEXIM TXET.
<em>
의 인라인 박스가 무한히 긴 컨테이닝
블록에서도 분할되지 않습니다:
소스 코드(논리 순서):
<p>here is <em dir=rtl>some MIXED</em> TEXT.</p>
넓은 컨테이닝 블록에서의 렌더링(시각적 순서), 단편 하나만 생성됨:
here is some DEXIM TXET.
좁은 컨테이닝 블록에서의 렌더링(시각적 순서), 단편 하나만 생성됨:
here is some DEXIM TXET.
2.4.5.2. 재정렬에 의한 박스 단편의 박스 모델
각 줄 박스별로, UA는 각 인라인 박스의 단편들을 시각적 순서(논리 순서가 아님)로 마진, 테두리, 패딩을 할당해야 합니다. 박스가 처음 등장하는 첫 줄 박스의 start 위치 단편에는 start 에지의 마진, 테두리, 패딩이 적용되고, 박스가 마지막으로 등장하는 마지막 줄 박스의 끝 단편에는 end 에지의 마진, 테두리, 패딩이 적용됩니다. 예를 들어, horizontal-tb 작성 모드에서는:
- 부모의 direction 속성이 ltr인 경우, 박스가 처음 등장하는 첫 줄 박스의 가장 왼쪽 단편에는 왼쪽 마진, 테두리, 패딩이 적용되고, 박스가 마지막으로 등장하는 마지막 줄 박스의 가장 오른쪽 단편에는 오른쪽 패딩, 테두리, 마진이 적용됩니다.
- 부모의 direction 속성이 rtl인 경우, 박스가 처음 등장하는 첫 줄 박스의 가장 오른쪽 단편에는 오른쪽 패딩, 테두리, 마진이 적용되고, 박스가 마지막으로 등장하는 마지막 줄 박스의 가장 왼쪽 단편에는 왼쪽 마진, 테두리, 패딩이 적용됩니다.
수직 작성 모드도 동일한 규칙을 적용합니다.
box-decoration-break 속성은 각 단편의 양쪽에 박스 데코레이션을 그리도록 이 동작을 오버라이드할 수 있습니다. [CSS-BREAK-3]
3. 수직 작성 모드
CSS2.1의 양방향 텍스트 지원 확장 외에도, 이 모듈은 CSS에서 수직 텍스트 레이아웃을 지원하는 데 필요한 규칙과 속성을 도입합니다.
3.1. 수직 작성 소개
이 하위 섹션은 규범적이지 않습니다.
주로 수평으로 레이아웃되는 라틴 문자를 사용하는 언어와 달리, 중국어와 일본어 등 아시아 언어는 수직으로도 레이아웃될 수 있습니다. 아래 일본어 예시는 동일한 텍스트가 수평과 수직으로 레이아웃된 모습을 보여줍니다. 수평의 경우, 텍스트는 왼쪽에서 오른쪽, 위에서 아래로 읽습니다. 수직의 경우, 텍스트는 위에서 아래, 오른쪽에서 왼쪽으로 읽습니다. 좌에서 우 수평의 왼쪽 여백 들여쓰기는, 위에서 아래 수직의 위쪽 여백 들여쓰기로 변환됩니다.
수직과 수평 일본어 비교: iBunko 애플리케이션(iOS)
중국어와 일본어의 줄은 오른쪽에서 왼쪽 또는 위에서 아래로 정렬되며, 몽골어와 만주어의 줄은 왼쪽에서 오른쪽으로 정렬됩니다.
수평에서 수직으로의 변화는 레이아웃뿐만 아니라 조판에도 영향을 줄 수 있습니다. 예를 들어, 구두점의 위치가 수평에서 수직으로 바뀌며, 경우에 따라 대체 글리프가 사용됩니다.
수직 텍스트에 라틴 문자 등 일반적으로 수평으로 표시되는 텍스트가 포함되는 경우 다양한 방식으로 표시될 수 있습니다. 예를 들어, 라틴 단어는 옆으로 회전하거나, 각 글자가 똑바로 서 있도록 배치할 수 있습니다:
수직 일본어에서 라틴어 예시: Daijirin Viewer 1.4(iOS)
날짜의 두 자리 숫자처럼 특별한 경우에는 텍스트가 하나의 세로 문자 박스에 압축되어 들어가기도 합니다:
Mac Fan, 2010년 12월, p.49
레이아웃은 종종 수직과 수평 요소가 혼합되어 있습니다:
수직과 수평 요소의 혼합
수직 텍스트 레이아웃도 양방향 텍스트 레이아웃을 처리해야 하며, 예를 들어 시계 방향으로 회전된 아랍어는 아래에서 위로 배치됩니다.
3.2. 블록 흐름 방향: writing-mode 속성
이름: | writing-mode |
---|---|
값: | horizontal-tb | vertical-rl | vertical-lr | sideways-rl | sideways-lr |
초기값: | horizontal-tb |
적용 대상: | table row 그룹, table column 그룹, table row, table column, ruby base container, ruby annotation container를 제외한 모든 요소 |
상속됨: | yes |
백분율: | 해당 없음 |
계산된 값: | 지정 값 |
정규 순서: | 해당 없음 |
애니메이션 타입: | 애니메이션 불가 |
이 속성은 텍스트 줄이 수평 또는 수직으로 배치되는지와 블록 진행 방향을 지정합니다. 가능한 값:
- horizontal-tb
- 상에서 하 블록 흐름 방향. 작성 모드와 타이포그래픽 모드 모두 수평.
- vertical-rl
- 오른쪽에서 왼쪽 블록 흐름 방향. 작성 모드와 타이포그래픽 모드 모두 수직.
- vertical-lr
- 왼쪽에서 오른쪽 블록 흐름 방향. 작성 모드와 타이포그래픽 모드 모두 수직.
- sideways-rl
- 오른쪽에서 왼쪽 블록 흐름 방향. 작성 모드는 수직, 타이포그래픽 모드는 수평.
- sideways-lr
- 왼쪽에서 오른쪽 블록 흐름 방향. 작성 모드는 수직, 타이포그래픽 모드는 수평.
writing-mode 속성은 블록 흐름 방향을 지정하며, 이는 블록 포맷팅 컨텍스트에서 블록 수준 박스의 정렬 방향, 인라인이 들어 있는 블록 컨테이너에서 줄 박스의 정렬 방향, 테이블에서 행의 정렬 방향 등을 결정합니다. 줄 박스의 쌓이는 방향을 결정함으로써, writing-mode 속성은 줄 박스의 방향(즉 작성 모드)이 수평인지 수직인지를 결정합니다. text-orientation 속성은 줄 박스 내에서 텍스트가 어떻게 배치되는지를 결정합니다.
대체 요소의 콘텐츠는 writing mode에 따라 회전하지 않습니다:
예를 들어 이미지 및 <iframe>
같은 외부 콘텐츠는 항상 똑바로 표시되며,
기본 오브젝트 크기 300px×150px도 방향이 바뀌지 않습니다.
하지만 텍스트를 포함한 대체 콘텐츠(MathML, 폼 요소 등)는 UA가 해당 콘텐츠에 대해 수직 writing mode를 지원할 경우,
대체 요소의 writing mode 및 줄 방향에 맞춰야 합니다.
아래 예시에서, 이미지(2)로 구분된 두 개의 블록 요소(1과 3)가 다양한 흐름 writing mode로 표시됩니다.
다음은 수평 writing mode(writing-mode: horizontal-tb
)의 다이어그램입니다:
다음은 동아시아에서 일반적으로 쓰이는 오른쪽에서 왼쪽 수직 writing mode(writing-mode: vertical-rl
)의 다이어그램입니다:
마지막으로, 만주어와 몽골어에서 사용되는 왼쪽에서 오른쪽 수직 writing mode(writing-mode: vertical-lr
)의 다이어그램입니다:
아래 예시에서는 몇몇 폼 컨트롤이 vertical-rl writing mode가 적용된 블록 내부에 렌더링됩니다. 폼 컨트롤도 writing mode에 맞춰 렌더링됩니다.
<style> form { writing-mode: vertical-rl; } </style> ... <form> <p><label>姓名 <input value="艾俐俐"></label> <p><label>语言 <select><option>English <option>français <option>فارسی <option>中文 <option>日本語</select></label> </form>
박스가 부모 박스(즉, display: contents가 아닌 가장 가까운 상위 요소)와 다른 writing-mode 값을 가지면:
- 박스가 계산된 display가 inline인 in-flow 박스가 되려 할 경우, display가 inline-block으로 계산됩니다.
- 박스가 block container인 경우, 독립적인 블록 포맷팅 컨텍스트를 생성합니다.
- 더 일반적으로, 지정된 내부 display 타입이 flow라면, 계산된 내부 display 타입이 flow-root가 됩니다. [CSS-DISPLAY-3]
다른 상속 CSS 속성과 마찬가지로, writing-mode 속성은 소스 문서에 인라인(링크가 아닌)으로 삽입된 SVG 요소에도 상속됩니다. 예를 들어, 수평 흐름만을 고려해 설계된 SVG 이미지를 수직 흐름 문서에 삽입할 경우 원치 않는 부작용이 발생할 수 있습니다.
작성자는 다음 규칙을 추가하여 이러한 현상을 방지할 수 있습니다:
3.2.1. 구식 SVG1.1 writing-mode 값
SVG1.1 [SVG11]는 다음과 같은 추가 값을 정의합니다: lr, lr-tb, rl, rl-tb, tb, tb-rl.
이 값들은 SVG1 문서를 제외한 모든 컨텍스트에서 구식이며, 따라서 비-SVG UA에서는 선택적입니다.
3.2.1.1. CSS 문법에서 SVG1.1 writing-mode 값 지원
이 값들을 CSS에서 지원하고자 하는 UA는 다음과 같이 계산해야 합니다:
지정 값 | 계산 값 |
---|---|
lr | horizontal-tb |
lr-tb | |
rl | |
rl-tb | |
tb | vertical-rl |
tb-rl |
SVG1.1 값들은 이전 CSS writing-mode 명세에도 포함되어 있었으나, 이 명세에 의해 폐기되었습니다. 해당 개정판의 tb-lr 추가 값은 vertical-lr로 대체되었습니다.
3.2.1.2. 프리젠테이션 속성에서 SVG1.1 writing-mode 값 지원
레거시 콘텐츠의 프리젠테이션 속성 지원 및 이전 클라이언트 호환 문서 작성을 위해, SVG UA는 기본 UA 스타일시트에 다음 규칙을 추가해야 합니다:
@namespace svg"http://www.w3.org/2000/svg" ; svg|*[writing-mode=lr], svg|*[writing-mode=lr-tb], svg|*[writing-mode=rl], svg|*[writing-mode=rl-tb] { writing-mode : horizontal-tb; } svg|*[writing-mode=tb], svg|*[writing-mode=tb-rl] { writing-mode : vertical-rl; }
svg|text { writing-mode: tb; writing-mode: vertical-rl; }
4. 인라인 수준 정렬
다양한 종류의 인라인 수준 콘텐츠가 한 줄에 함께 배치될 때, 콘텐츠의 기준선과 vertical-align 속성 설정이 줄 박스의 횡방향에서 어떻게 정렬되는지를 제어합니다. 이 절에서는 기준선이 무엇인지, 어떻게 찾는지, 그리고 vertical-align 속성과 함께 인라인 수준 콘텐츠의 정렬을 어떻게 결정하는지 다룹니다.
4.1. 기준선 소개
이 절은 규범적이지 않습니다.
기준선은 줄 박스의 인라인 축을 따라 텍스트의 개별 글리프가 정렬되는 선을 의미합니다. 기준선은 폰트에서 글리프 디자인을 안내하며(예를 들어 대부분의 알파벳 글리프 바닥이 알파벳 기준선에 맞춰짐), 조판 시 다양한 폰트나 폰트 크기의 글리프 정렬도 안내합니다.
두 가지 폰트 크기의 알파벳 텍스트와 기준선 및 em-box
작성 체계에 따라 선호하는 기준선 테이블이 다릅니다.
다양한 작성 체계에서 선호하는 기준선
잘 설계된 폰트에는 기준선 테이블이 포함되어 있으며, 폰트 디자인 좌표 공간 내에서 하나 이상의 기준선 위치를 나타냅니다.(디자인 좌표 공간은 폰트 크기에 따라 스케일됩니다.)
잘 설계된 혼합 문자 폰트에서는 글리프가 좌표 공간에 조판될 때 서로 조화롭게 배치됩니다. 기준선 테이블은 글리프 모양에 맞춰 구성되며, 각 기준선은 해당 문자 체계에 맞춰 배치됩니다.
기준선 테이블은 폰트의 속성이며, 다양한 기준선 위치는 폰트 내 모든 글리프에 적용됩니다.
수평과 수직 텍스트 정렬을 위해 서로 다른 기준선 테이블이 제공될 수 있습니다. UA는 수직 타이포그래픽 모드에서는 수직 테이블을, 그 외에는 수평 테이블을 사용해야 합니다.
4.2. 텍스트 기준선
이 명세에서는 다음 기준선만을 다룹니다:
- alphabetic
- 알파벳 기준선으로, 일반적으로 라틴 대문자 글리프의 바닥과 맞춥니다.
- central
- 중앙 기준선으로, 일반적으로 em 박스의 중앙을 관통합니다. 폰트에 이 기준선이 없으면, ascender(over)와 descender(under) 에지 중간으로 간주합니다.
수직 타이포그래픽 모드에서는 중앙 기준선이 text-orientation이 mixed 또는 upright일 때 우세 기준선이 됩니다. 그 외에는 알파벳 기준선이 사용됩니다.
향후 CSS 모듈에서는 기준선에 대해 더 자세히 다루고, 다른 우세 기준선 및 정렬 옵션을 선택할 수 있게 할 예정입니다.
4.3. 원자 인라인 기준선
원자 인라인(inline-block, inline-table, 또는 대체 인라인 요소 등)에 기준선이 없으면, UA는 다음과 같이 기준선 테이블을 합성합니다:
- alphabetic
- 알파벳 기준선은 under margin edge에 있다고 간주합니다.
- central
- 중앙 기준선은 박스의 under와 over margin edge 중간에 있다고 간주합니다.
vertical-align 속성은 [CSS2]에서 inline-table과 inline-block 박스의 기준선을 일부 예외와 함께 정의합니다.
4.4. 기준선 정렬
우세 기준선(타이포그래픽 모드에 따라 변경 가능)은 CSS에서 두 가지 경우에 정렬에 사용됩니다:
- 같은 인라인 박스 내에서 다른 폰트의 글리프 정렬. 각 폰트의 우세 기준선 위치를 맞춰 글리프를 정렬합니다.
-
자식 인라인 수준 박스를 부모에 정렬. vertical-align 값이 baseline일 때, 자식은
부모의 우세 기준선을 자식의 동일한 기준선에 맞춰 정렬합니다.(예: 부모의 우세 기준선이 알파벳 기준선이면, 자식의 알파벳 기준선을 부모의 알파벳 기준선에 맞춥니다. 자식의 우세 기준선이
다르더라도 동일함.)
sub, super, <length>, <percentage> 값은 baseline과 같이 기준선을
정렬하되, 자식이 vertical-align 값에 따라 오프셋만큼
이동합니다.
다음 샘플 마크업을 가정:
<p><span class="outer">Ap <span class="inner">ji</span></span></p>
그리고 다음 스타일 규칙:
span.inner { font-size: .75em; }
부모(
.outer
)와 자식(.inner
)의 기준선 테이블은 폰트 크기 차이로 일치하지 않습니다. 우세 기준선이 알파벳 기준선이므로, 자식 박스는 부모와 알파벳 기준선을 맞춰 정렬됩니다.위 예시에서
.inner
요소에 vertical-align: super를 지정하면, 동일한 기준선 정렬 규칙이 적용되지만, 기준선 정렬 외에 자식이 위 첨자 위치로 이동합니다.span.inner { vertical-align: super; font-size: .75em; }
5. 수직 텍스트 레이아웃 소개
각 문자 체계는 하나 이상의 고유 방향을 가지고 있습니다. 현대 문자 체계는 세 가지 방향 범주로 분류할 수 있습니다:
- 수평 전용
- 수직 방향이 없는 수평 고유 방향 문자. 예: 라틴, 아랍어, 히브리어, 데바나가리
- 수직 전용
- 수평 방향이 없는 수직 고유 방향 문자. 예: 몽골어, 파스파 문자
- 양방향(수직/수평)
- 수직과 수평 모두 고유 방향을 가진 문자. 예: 한자, 한글, 일본어 가나
수직 문자란 고유 수직 방향을 가진 문자(즉, 수직 전용 또는 양방향)를 의미합니다. 수평 문자란 고유 수평 방향을 가진 문자(즉, 수평 전용 또는 양방향)를 의미합니다. (문자의 고유 방향별 분류는 부록 A 참고.)
현대 타이포그래픽 시스템에서는 모든 글리프가 수평 방향을 가지며, 수평 텍스트 조판 시 사용됩니다. 수직 텍스트를 조판하려면 UA가 텍스트를 수평 방향에서 수직으로 변환해야 하며, 이 변환이 양방향 변환입니다. 변환 방식은 두 가지입니다:
- rotate
- 글리프를 수평에서 수직으로 회전
- translate
- 글리프를 수평에서 수직으로 이동
고유 수직 방향을 가진 문자는 고유 양방향 변환을 가지고 있으며, 수직 텍스트에서 올바르게 배치됩니다. 대부분의 CJK(중국어/일본어/한국어) 문자는 translate 방식(즉, 항상 똑바로 세움)이고, 몽골문자 등 다른 문자는 회전합니다.
고유 수직 방향이 없는 문자는 회전(옆으로 눕힘) 또는 translate(똑바로 세움) 모두 가능하며, 변환 방식은 텍스트 용도에 따라 스타일적으로 선택됩니다. text-orientation 속성의 mixed와 upright 값은 수평 전용 텍스트의 회전과 세움 방식을 지정합니다.
5.1. 텍스트 방향 지정: text-orientation 속성
이름: | text-orientation |
---|---|
값: | mixed | upright | sideways |
초기값: | mixed |
적용 대상: | table row 그룹, row, column 그룹, column을 제외한 모든 요소 |
상속됨: | yes |
백분율: | 해당 없음 |
계산된 값: | 지정 값 |
정규 순서: | 해당 없음 |
애니메이션 타입: | 애니메이션 불가 |
이 속성은 한 줄 내에서 텍스트의 방향을 지정합니다. 현재 값은 수직 타이포그래픽 모드에서만 효과가 있습니다. 수평 타이포그래픽 모드 박스에는 아무런 효과가 없습니다.
값의 의미는 다음과 같습니다:
- mixed
-
수직 writing mode에서는, 수평 전용 문자 체계의 타이포그래픽 문자 단위가 90° 시계 방향으로 회전해서 표시됩니다. 수직 문자 체계의 타이포그래픽 문자 단위는 고유 방향대로 표시됩니다. 자세한 내용은 수직 방향 참고.
이 값은 수직 문자 기반 텍스트 레이아웃에 일반적입니다.
- upright
-
수직 writing mode에서는, 수평 전용 문자 체계의 타이포그래픽 문자 단위가 똑바로 세운 채 표시됩니다. 수직 문자 체계의 타이포그래픽 문자 단위는 고유 방향대로 표시되고, 일반적으로 형태가 변하지 않습니다. 자세한 내용은 수직 방향 참고.
이 값은 used value가 direction ltr로 되며, 양방향 재정렬에서는 모든 문자를 강한 LTR로 처리합니다.
참고: used value는 computed value가 아니라, direction이 rtl일 때 후손(예: 수평 inline-block 등)에 올바르게 상속될 수 있도록 방향 오버라이드가 미적용된 곳에서는 정상적으로 상속됩니다.
- sideways
-
수직 writing mode에서는 모든 텍스트가 옆으로 눕혀 표시되어, 수평 레이아웃과 같지만 90° 시계 방향으로 회전됩니다.
이 속성 값을 변경하면 인라인 수준 정렬에 영향을 줄 수 있습니다. 자세한 내용은 텍스트 기준선 참고.
UA는 sideways-right 값을 필요할 경우 sideways로 계산해도 됩니다(호환성 유지 목적).
.vertical-upright-hebrew { writing-mode: vertical-rl; text-orientation: upright; unicode-bidi: bidi-override; direction: ltr; }
5.1.1. 수직 조판과 폰트 기능
vertical-rl 및 vertical-lr 모드에서 텍스트를 조판할 때, 텍스트는 아래 정의된 대로 "upright"(똑바로) 또는 "sideways"(옆으로 눕힘)로 조판됩니다:
- upright 조판
-
타이포그래픽 문자 단위는 수직 줄에서 각 문자별로 똑바로 세워, 수직 폰트 메트릭으로 조판됩니다.
UA는 폰트에 수직 메트릭이 없는 경우 이를 합성해야 합니다.
(이 명세에서는 그러한 메트릭을 합성하는 휴리스틱을 정의하지 않습니다.)
또한, 수직 조판에 사용하기 위한 폰트 기능(대체 글리프 및 기타 변환 등)을 사용해야 합니다.
(예: OpenType vert 기능을 활성화해야 함.)
뿐만 아니라, 수평 필기체 문자(예: 아랍어)는 똑바로 조판될 때 고립된 형태로 변형됩니다.
"upright"로 조판하더라도 일부 글리프는 회전되어야 합니다. 예를 들어, 대시와 닫는 구두점 등은 인라인 축을 기준으로 방향이 맞춰져야 합니다. OpenType에서는 일반적으로 글리프 치환으로 처리하지만, 모든 폰트가 관련 코드포인트에 대해 대체 글리프를 제공하는 것은 아닙니다. (동아시아 폰트는 동아시아 코드포인트용 대체 글리프를 제공하는 반면, 서양 폰트는 수직 조판 기능이 부족하고, 동아시아 폰트도 서양 코드포인트의 수직 치환을 제공하지 않는 경우가 많습니다.) Unicode에서는 어떤 문자가 옆으로 보여야 하는지 SVO 속성으로 이 데이터 파일에서 초안 데이터를 공개한 적 있지만, 현재 [UTR50] 개정판에서는 폐기되었습니다.
타이포그래픽 문자 단위 중 [UTR50]에서
Tr
또는Tu
로 분류된 경우, 수직 텍스트에서 똑바로 조판하기 위한 대체 글리프나 위치 지정이 필요합니다.Tr
문자의 경우, 폰트에 해당 수직 대체 글리프가 없다면, UA는 원한다면 [RFC6919](필수는 아님) 옆으로 눕혀 조판(typesetting them sideways 등)으로 합성할 수 있습니다. - sideways 조판
- 타이포그래픽 문자 단위가 한 덩어리로 90° 시계 방향으로 회전되어,
수평 메트릭 및 조합으로 조판됩니다. 수직 조판 기능은 사용되지 않습니다.
단, 폰트가 수직 줄에서 옆으로 눕혀 조판할 때 활성화되어야 하는 기능(예: 붓 획 각도 조정이나 정렬 등)을 갖고 있다면, 해당 기능을 사용합니다.
(예:
vrtr
OpenType 폰트 기능 등)
5.1.2. 혼합 수직 방향
[UTR50]에서는 혼합 방향 수직 텍스트의 기본 글리프 방향을 위한
Vertical_Orientation
속성을 정의합니다.
text-orientation이 mixed일 때,
UA는 각 타이포그래픽 문자 단위의 Vertical_Orientation
속성에 따라 방향을
결정해야 합니다: 그 값이 U
, Tu
또는 Tr
이면 똑바로 조판;
R
이면 90° 시계 방향으로 눕혀 조판합니다.
UTR50은 수직 컨텍스트에서 -90°로 회전되는 문자 체계는 처리하지 않으므로, mixed 방향에서는 제대로 조판되지 않습니다. 이러한 문자에는 sideways-lr을 사용하세요.
OpenType의 vrt2 기능(혼합 방향 조판용)은 CSS에서 사용되지 않습니다. 글리프 방향 결정은 폰트 디자이너에게 위임되지만, CSS는 [UTR50]에 따라 방향을 지정하며, 해당 글리프를 옆으로 눕히거나 똑바로 세워 조판합니다.
5.1.3. 구식: SVG1.1 glyph-orientation-vertical 속성
이름: | glyph-orientation-vertical |
---|---|
값: | auto | 0deg | 90deg | 0 | 90 |
초기값: | n/a |
적용 대상: | n/a |
상속됨: | na/ |
백분율: | n/a |
계산된 값: | n/a |
정규 순서: | n/a |
애니메이션 가능: | n/a |
일부 SVG UA는 구식 SVG glyph-orientation-vertical 속성이 포함된 문서를 처리해야 할 수 있습니다. 이 속성은 auto 키워드와 <angle>, <integer> 등 90° 배수 값을 허용하도록 정의되었습니다. 이 속성 지원은 선택적이지만, 지원하는 UA는 glyph-orientation-vertical을 text-orientation의 약어로 다음과 같이 매핑해야 합니다:
약어 glyph-orientation-vertical 값 | 풀네임 text-orientation 값 |
---|---|
auto | mixed |
0deg | upright |
0 | upright |
90deg | sideways |
90 | sideways |
UA는 glyph-orientation-vertical 속성의 그 외 값은 무시하고, 모두 무효로 처리해야 하며, glyph-orientation-horizontal 속성 전체도 무효로 처리해야 합니다.
참고: 180deg와 270deg 값, 라디안 및 그라디안 값, glyph-orientation-horizontal 속성은 CSS에 포함되지 않았으며, 사용 사례 또는 의존 콘텐츠가 없으므로 CSS 및 SVG에서 제외되었습니다.
6. 추상 박스 용어
CSS2.1 [CSS2]에서는 CSS의 박스 레이아웃 모델을 상세히 정의하지만, horizontal-tb 작성 모드에 대해서만 정의합니다. horizontal-tb 이외의 작성 모드에서도 레이아웃은 유사하지만, CSS2.1의 방향 및 치수 용어를 추상화하고 적절히 다시 매핑해야 합니다.
이 절에서는 다른 작성 모드의 박스 레이아웃 정의와 미래 명세에서 추상적으로 레이아웃 개념을 정의할 수 있도록, 추상 방향 및 치수 용어와 그 매핑을 정의합니다. (다음 절에서는 CSS2.1 레이아웃 계산에 적용하는 방법과 직교 흐름 처리 방법을 설명합니다.) 이 추상 매핑은 텍스트의 동작에서 유래했지만, 줄 박스가 없는 박스에도 적용됩니다: writing-mode 및 direction 속성 값에서 직접 계산됩니다.
CSS에서 방향 용어 세트는 세 가지가 있습니다:
- 물리적
- 페이지 기준으로 해석하며, 작성 모드와 무관합니다. 물리적 방향은 왼쪽, 오른쪽, 위, 아래입니다.
- 흐름 기준
- 콘텐츠 흐름 기준으로 해석합니다. 흐름 기준 방향은 start와 end, 또는 차원이 모호할 때 block-start, block-end, inline-start, inline-end입니다.
- 줄 기준
- 줄 박스 방향 기준으로 해석합니다. 줄 기준 방향은 line-left, line-right, line-over, line-under입니다.
물리적 치수는 너비와 높이이며, 각각 x축(수평 치수)과 y축(수직 치수)에 해당합니다. 추상 치수는 흐름 기준과 줄 기준 모두에서 동일하므로, 용어 세트는 하나뿐입니다.
참고: [CSS3-FLEXBOX]에서는 flex 레이아웃 설명에 flex 기준 용어를 정의합니다.
6.1. 추상 치수
- 블록 치수
- 줄 내 텍스트 흐름과 수직인 치수. 즉, 수평 작성 모드에서는 수직 치수, 수직 작성 모드에서는 수평 치수.
- 인라인 치수
- 줄 내 텍스트 흐름과 평행한 치수. 즉, 수평 작성 모드에서는 수평 치수, 수직 작성 모드에서는 수직 치수.
- 블록 축
- 블록 치수의 축. 즉, 수평 작성 모드에서는 y축, 수직 작성 모드에서는 x축.
- 인라인 축
- 인라인 치수의 축. 즉, 수평 작성 모드에서는 x축, 수직 작성 모드에서는 y축.
- 블록 크기
- 논리적 높이
- 블록 치수의 측정값: 수평 작성 모드에서는 물리적 높이(수직 치수)를 의미하고, 수직 작성 모드에서는 물리적 너비(수평 치수)를 의미합니다.
- 인라인 크기
- 논리적 너비
- 인라인 치수의 측정값: 수평 작성 모드에서는 물리적 너비(수평 치수), 수직 작성 모드에서는 물리적 높이(수직 치수)를 의미합니다.
6.2. 흐름 기준 방향
흐름 기준 방향, block-start, block-end, inline-start, inline-end는 페이지의 콘텐츠 흐름을 기준으로 정의됩니다. LTR horizontal-tb 작성 모드에서는 각각 위, 아래, 왼쪽, 오른쪽 방향에 해당합니다. 정의는 다음과 같습니다:
- block-start
- 블록 흐름 방향에서 더 먼저 오는 쪽이며, writing-mode 속성으로 결정됩니다: horizontal-tb에서는 물리적 top, vertical-rl에서는 오른쪽, vertical-lr에서는 왼쪽입니다.
- block-end
- block-start의 반대쪽입니다.
- inline-start
- 인라인 기준 방향에서 텍스트가 시작되는 쪽입니다. direction 값이 ltr인 박스에서는 line-left 쪽, direction 값이 rtl인 박스에서는 line-right 쪽입니다.
- inline-end
- start의 반대쪽입니다.
문맥적으로 모호하지 않거나 두 의미를 모두 포함하는 경우, start와 end 용어를 각각 block-start/inline-start 및 block-end/inline-end 대신 사용합니다.
박스의 block-start와 block-end 쪽은 writing-mode 속성만으로 결정되지만, inline-start와 inline-end 쪽은 writing-mode와 direction 속성 모두에 따라 결정됩니다.
6.3. 줄 기준 방향
줄 방향은 줄 박스의 논리적 “위”(ascender 쪽)가 어느 쪽인지 결정합니다. writing-mode 속성으로 결정됩니다. 일반적으로 줄 기준 “위”는 block-start 쪽에 해당하지만, 항상 그렇지는 않습니다: 몽골어 조판(즉 vertical-lr 작성 모드 기본값)에서는 줄 기준 “위”가 block-end 쪽에 해당합니다. 따라서 별도의 용어가 필요합니다.

위의 몽골문 중심 문서는 수직 줄이 왼쪽에서 오른쪽으로 쌓이고, 라틴 텍스트의 글리프 윗 부분이 오른쪽을 향함. 이는 몽골문(상에서 하 방향)의 인라인 방향과 동일하며, 동아시아 레이아웃(오른쪽에서 왼쪽으로 수직 줄 쌓기)과 같은 방향이지만, 글리프 윗부분은 줄 스택의 아래쪽을 향하게 됨(영문 단락에서는 거꾸로 됨). (몽골문 레이아웃 다이어그램 참고.)
줄 기준 “위”와 “아래”는 'vertical-align: top' 등과 매핑하기 위한 것이고, CSS는 text-align: left 등과 매핑하기 위한 줄 기준 “왼쪽”, “오른쪽” 용어도 필요합니다. 따라서 줄 기준 방향은 줄 방향을 기준으로 다음과 같이 정의됩니다:
- over 또는 line-over
- 명목상 줄 박스의 ascender 쪽 또는 “위”에 해당하는 쪽. (overline이 일반적으로 그려지는 쪽)
- under 또는 line-under
- over의 반대: 줄 기준 “아래” 또는 descender 쪽. (underline이 일반적으로 그려지는 쪽)
- line-left
- 줄 박스의 줄 기준 “왼쪽”에 해당하는 쪽. 명목상 LTR 텍스트가 시작되는 쪽.
- line-right
- 줄 박스의 줄 기준 “오른쪽”에 해당하는 쪽. 명목상 RTL 텍스트가 시작되는 쪽. (line-left의 반대)
물리/줄 기준 방향의 정확한 매핑은 아래 표 참고.

horizontal-tb에서의 줄 방향

vertical-rl, vertical-lr, sideways-rl에서의 줄 방향

sideways-lr에서의 줄 방향
똑바로 세운 글리프의 수직 기준선
기준선이 수직이므로, 위에서 설명한 mixed 또는 sideways 정의가 그대로 적용됩니다. 즉, line-over는 오른쪽, line-under는 왼쪽입니다.
이는 OpenType 등 폰트 시스템에서 수직 메트릭 ascender가 오른쪽, descender가 왼쪽에 정의되는 것과 일치합니다.
6.4. 추상-물리 매핑
다음 표는 추상-물리 매핑을 요약합니다(used direction과 writing-mode에 기반):
writing-mode | horizontal-tb | vertical-rl, sideways-rl | vertical-lr | sideways-lr | ||||
---|---|---|---|---|---|---|---|---|
direction | ltr | rtl | ltr | rtl | ltr | rtl | ltr | rtl |
block-size | height | width | ||||||
inline-size | width | height | ||||||
block-start | top | right | left | |||||
block-end | bottom | left | right | |||||
inline-start | left | right | top | bottom | top | bottom | bottom | top |
inline-end | right | left | bottom | top | bottom | top | top | bottom |
over | top | right | left | |||||
under | bottom | left | right | |||||
line-left | left | top | bottom | |||||
line-right | right | bottom | top |
참고: used direction은 계산된 writing-mode와 text-orientation에 따라 달라집니다: 수직 작성 모드에서는 text-orientation 값이 upright일 때 used direction이 ltr로 강제됩니다.
7. 추상 박스 레이아웃
7.1. 수직 작성 모드의 레이아웃 원칙
CSS 박스 레이아웃은 수직 작성 모드에서도 수평 작성 모드와 유사하게, 아래에 정리된 원칙을 따릅니다:
수평 작성 모드에서 수평 치수에 적용되는 레이아웃 계산 규칙(예: CSS2.1, 10.3절)은 수직 작성 모드에서는 수직 치수에 적용됩니다. 마찬가지로, 수평 작성 모드에서 수직 치수에 적용되는 레이아웃 계산 규칙(예: CSS2.1, 10.6절)은 수직 작성 모드에서는 수평 치수에 적용됩니다. 즉:
-
너비를 참조하는 레이아웃 규칙은 높이를, 높이를 참조하는 규칙은 너비를 대신 사용합니다.
-
*-left 및 *-right 박스 속성(border, margin, padding, 위치 오프셋 등)을 참조하는 레이아웃 규칙은 *-top 및 *-bottom을 대신 사용하며, 반대로도 적용됩니다. CSS2.1의 수평 작성 모드 규칙을 흐름 기준 방향을 이용해 수직 작성 모드 규칙으로 매핑합니다. 이 속성이 적용되는 박스의 쪽은 바뀌지 않고, 어떤 값이 어떤 레이아웃 계산에 입력되는지만 바뀝니다. 예를 들어 margin-left 속성은 여전히 왼쪽 마진에 영향을 주지만, vertical-rl 작성 모드에서는 margin-bottom 대신 마진 겹침에 참여합니다.
-
direction 속성에 따라 좌우를 선택하는 레이아웃 규칙(예: overflow, overconstraint 해소, text-align의 초기값, 테이블 열 순서)은 추상적으로 start와 end 쪽으로 추상화하여 적절히 적용됩니다.
예를 들어, 수직 작성 모드에서는 테이블 행이 수직, 테이블 열이 수평입니다. vertical-rl mixed rtl 테이블에서는, 첫 번째 열이 아래쪽(inline-start 쪽)에 오고, 첫 번째 행이 오른쪽(block-start 쪽)에 위치합니다. 테이블의 margin-right 및 margin-left는 각각 테이블 오른쪽(이전)과 왼쪽(다음) 마진과 겹치며, 테이블의 auto margin-top, margin-bottom 값이 있을 경우, 블록 흐름 내에서 수직 방향으로 중앙에 위치하게 됩니다.
vertical-rl RTL 작성 모드의 테이블
텍스트 정렬, 플로팅, 리스트 마커 위치 등처럼 주로 줄 박스의 좌우 또는 그 평행선 기준을 참조하며, 위/아래에 해당하는 개념이 없는 기능에는, line-left와 line-right 쪽을 각각 좌우 기준으로 참조합니다.
마찬가지로 밑줄, 윗줄, 기준선 정렬(vertical-align처럼 이름이 아쉬운 것들)은 주로 줄박스의 위/아래나 횡단 기준을 참조하며, 좌우에 해당하는 개념이 없으므로, line-over와 line-under 쪽을 각각 위/아래 기준으로 참조합니다.
이러한 매핑의 세부 사항은 아래에서 설명합니다.
7.2. 치수 매핑
다음 속성들은 논리적으로 아래와 같이 동작합니다:
- border-spacing 속성의 첫 번째, 두 번째 값은 각각 열 사이, 행 사이의 간격을 의미하며, 반드시 수평/수직 간격을 의미하는 것은 아닙니다. [CSS2]
- line-height 속성은 항상 논리적 높이를 의미합니다. [CSS2]
height, min-height, max-height 속성은 물리적 높이를 의미하고, width, min-width, max-width 속성은 물리적 너비를 의미합니다. 하지만 박스 치수와 위치 계산 규칙은 논리적으로 적용됩니다.
예를 들어 CSS2.1 10.3절의 계산 규칙은 인라인 치수 측정에 사용되며, inline size (물리적 너비 또는 높이일 수 있음)와 inline-start, inline-end 마진, 패딩, 테두리에 적용됩니다. 마찬가지로 CSS2.1 10.6절의 계산 규칙은 블록 치수에 사용되며, block size, block-start, block-end 마진, 패딩, 테두리에 적용됩니다. [CSS2]
결론적으로, margin과 padding 속성의 백분율은 CSS2.1에서는 항상 포함 블록의 너비 기준으로 계산되지만, CSS3에서는 포함 블록의 inline size 기준으로 계산됩니다.
7.3. 직교 흐름
박스가 포함 블록과 다른 writing-mode를 가지는 경우 두 가지가 있습니다:
- 두 작성 모드가 서로 평행일 때(예: vertical-rl, vertical-lr)
- 두 작성 모드가 서로 직교할 때(예: horizontal-tb, vertical-rl)
박스가 포함 블록과 직교하는 작성 모드를 가지면, 직교 흐름에 있다고 또는 직교 흐름을 생성한다고 합니다.
이 경우 CSS 레이아웃 계산은 박스의 크기 결정, 흐름 내 박스 위치 결정의 두 단계로 나뉩니다.
- 크기 결정 단계(박스의 너비와 높이 계산)에서는 박스와 포함 블록의 치수를 inline size와 block size로 매핑하여, 직교 흐름을 생성하는 박스의 작성 모드 기준으로 계산합니다.
- 위치 결정 단계(위치 오프셋, 마진, 테두리, 패딩 계산)에서는 박스와 포함 블록의 치수를 inline size, block size로 매핑하여, 직교 흐름을 생성하는 박스의 포함 블록 작성 모드 기준으로 계산합니다.
auto 마진은 포함 블록의 작성 모드에 맞게 해석되므로, 직교 흐름을 생성하는 박스도 크기 결정 후에는 auto 마진을 사용해 포함 블록 내에서 다른 블록 수준 박스처럼 정렬/중앙 배치가 가능합니다.
직교 흐름 예시
예를 들어, 수평 블록 안에 수직 블록이 들어가면, 자식 블록의 물리적 높이(자식의 inline size)를 계산할 때, 부모 블록의 물리적 높이를 자식의 포함 블록 inline size로 사용합니다. 비록 물리적 높이는 부모 블록의 block size이지, inline size는 아니어도 말입니다.
반면, 포함 블록이 수평 작성 모드이므로, 자식의 수직 마진은 마진 겹침에 참여하며, 이는 자식의 inline-axis에 해당하지만, 자식의 수평 auto 마진은 포함 블록을 채우도록 확장되며, 이는 자식의 block-axis에 해당합니다.
즉, inline-block, float, table-cell 등 박스에 shrink-to-fit 공식을 적용할 때, 자식이 직교 흐름을 생성하면, 자식의 크기 결정 단계가 먼저 실행되어, 자식의 사용된 block size가 부모의 inline-size shrink-to-fit 공식에 입력값이 됩니다.
7.3.1. 직교 흐름에서의 사용 가능한 공간
CSS에서는 포함 블록에 inline size는 확정되고, block size는 확정되지 않은 경우가 흔합니다. 이는 CSS2.1에서, 포함 블록에 auto 높이가 있을 때 자주 발생하며, 예: 너비는 10.3.3 계산에 따라 결정되지만, block size는 콘텐츠에 따라 결정됩니다. 이런 경우 사용 가능한 인라인 공간은 포함 블록의 inline size이고, 사용 가능한 블록 공간(보통 포함 블록의 block size)은 무한대입니다.
박스를 직교 흐름에 놓으면 반대 현상이 나타날 수 있습니다:
박스의 사용
가능한 블록 공간은 확정되지만,
사용 가능한 인라인 공간은 확정되지 않는 경우입니다.
이런 경우 포함 블록의 inline size의 백분율을
정의할 수 없으며,
inline axis 계산을 할 수 없습니다.
이런 경우에는,
사용 가능한 인라인 공간이 필요한 계산에서,
사용 가능한 인라인 공간 대신 사용할 추가 제약 조건(fallback)을 아래와 같이 사용합니다—
- 포함 블록의 내부 최대 크기(고정이면)에서 내부 최소 크기(고정이면)로 바닥(floor) 처리한 값
- 가장 가까운 조상 스크롤포트의 내부 크기가 고정이면 해당 값, 아니면 내부 최대 크기(고정이면)로 capped, 내부 최소 크기(고정이면)로 바닥 처리
- 초기 포함 블록의 크기
CSS 크기 용어와 개념에 대한 자세한 내용은 [CSS3-SIZING] 참고.
7.3.2. 직교 흐름에서 블록 컨테이너 자동 크기 조정
직교 흐름을 생성하는 박스가 블록 컨테이너 또는 다단(멀티컬럼) 컨테이너인 경우, 해당 박스의 inline size가 auto일 때:
-
사용된 column-width 계산:
-
column-count와 column-width가 모두 auto인 경우,
축소-적합(shrink-to-fit) 공식
min(max-content, max(min-content, constraint))
사용. 여기서:- min-content
- 박스의 min-content inline size
- max-content
- 박스의 max-content inline size
- constraint
- inline-axis 크기 (아래 중 가장 작은 값으로 stretch fit):
- column-count가 auto가 아니고, column-width가 auto인 경우, 위 공식에서 constraint 대신 constraint − (column-count − 1) × column-gap을 사용해 계산.
- column-count와 column-width가 모두 auto가 아닐 경우, 사용된 column-width는 계산된 column-width입니다. (이 방식은 오버플로우를 유발할 수 있으니 권장하지 않으며, column-width와 max-block-size를 함께 지정하는 것이 더 낫습니다.)
-
column-count와 column-width가 모두 auto인 경우,
축소-적합(shrink-to-fit) 공식
-
사용된 컬럼 길이(column length) 계산: 계산된 block size가 auto이고, column-count 또는 column-width 중 하나라도 auto로 지정된 경우,
박스의 block size(확정이면) 또는 stretch-fit block size(확정이면),
아니면 박스의 max-content block size 사용.
그 외에는 다단 컨테이너 크기 산정 일반 규칙을 따름.
이 공식에 min-content block size를 포함시켜, 예를 들어 큰 이미지는 박스를 넘지 않고 박스가 포함 블록을 넘치도록 해야 할까?
- 사용된 column-count 계산: 계산된 column-count가 auto인 경우, 사용된 column-count는 다단 레이아웃에 실제로 채워진 콘텐츠로 결정됨.
결과 다단 컨테이너의 사용된 inline size 계산:
- 콘텐츠가 다단 컨테이너 내에서 줄 바꿈도 단편화도 발생하지 않으면, 사용된 inline size는 박스 콘텐츠의 max-content inline size가 됨. 이 기준은 짧은 직교 흐름 콘텐츠에 대해 불필요한 빈 공간 없이 shrink-to-fit 동작을 제공합니다.
- 그 외에는 사용된 column-width, column-count, column-gap으로 산정.
박스의 사용된 block size는 여러 컬럼이 사용된 경우 사용된 컬럼 길이, 한 컬럼만 사용된 경우 콘텐츠의 max-content block size입니다. UA가 CSS 다단 레이아웃 [CSS3COL]을 지원하지 않으면, 박스의 block size를 사용 가능한 블록 공간이 무한대라고 가정해 산정해, 콘텐츠를 한 컬럼에만 레이아웃할 수 있습니다. (이 경우 콘텐츠가 포함 블록을 넘치면 잘리거나 접근 불가가 될 수 있습니다.)
자동으로 다단 흐름이 발생하는 기능은 위험 상태이며 CR 기간 중 제거될 수 있습니다.
7.3.3. 기타 직교 흐름 루트의 자동 크기 조정
줄 길이를 제한하기 위해, 블록 컨테이너는 위에서 정의된 특수 자동 크기 동작을 가지며, 사용 가능한 인라인 공간이 무한대일 때(보통 직교 흐름을 생성할 때) 적용됩니다.
그 외 레이아웃 모델은 단순히 무한 사용 가능한 인라인 공간에서 max-content size에 따라 레이아웃합니다. 하지만 이들은 블록 컨테이너를 포함하면 그 하위 블록 컨테이너에 무한 사용 가능한 인라인 공간을 전달해, 해당 블록 컨테이너에서 위 자동 크기 동작이 발생할 수 있습니다(스스로는 직교 흐름을 생성하지 않아도).
예를 들어, 테이블이나 flex 컨테이너가 직교 흐름을 생성할 때 주어진 사용 가능한 공간에서 레이아웃됩니다. 사용 가능한 인라인 공간이 무한대이면, 박스는 사실상 max-content size로 레이아웃됩니다. 하지만 그 테이블 셀이나 flex item 중 블록 컨테이너가 있다면, 해당 블록 컨테이너는 무한 사용 가능한 인라인 공간을 기준으로 레이아웃되어 위 자동 크기 동작이 적용됩니다.
7.3.4. 직교 흐름 단편화
이 절은 참고용입니다.
단편화(페이지 분할)에 관해서는 CSS2.1의 규칙이 수직 작성 모드와 직교 흐름에서도 그대로 적용됨: 줄 박스 내부에서는 끊김이 발생하지 않고, 줄 박스 사이에서만 발생. [CSS3COL]을 지원하는 UA는 컬럼 사이(폭 0일 수도 있음)에서 끊어질 수 있음.
콘텐츠가 루트 요소가 설정한 페이지네이션 스트림 밖으로 넘치면 UA가 해당 콘텐츠를 반드시 인쇄할 필요는 없음. 따라서 긴 텍스트를 다양한 작성 모드로 혼합하려면, 모든 콘텐츠가 문서의 페이지네이션 방향으로 흐르도록 CSS 컬럼을 사용할 것을 권장.
즉, 문서에 스크롤바가 두 개 필요하다면 모두 인쇄되지 않을 수 있습니다. 레이아웃을 고치세요(예: 컬럼 사용)해서 한 방향으로만 스크롤/페이지네이션되게 해야 인쇄가 보장됩니다. T자형 문서는 인쇄가 잘 되지 않습니다.
7.4. 흐름 기준 매핑
흐름 기준 방향은 박스의 포함 블록의 작성 모드 기준으로 산정되며, 박스의 속성(마진, 테두리, 패딩) 및 박스를 포함 블록 내에서 위치시키는 모든 속성(float, clear, top, bottom, left, right, caption-side)와 관련된 레이아웃 규칙을 추상화하는 데 사용됩니다. 인라인 수준 박스의 경우 부모 박스의 작성 모드를 사용합니다. (left/right/top/bottom 이름의 속성 및 값 자체는 여전히 물리적으로 매핑됨. 단, caption-side의 top/top-outside 및 bottom/bottom-outside 값은 각각 테이블의 block-start와 block-end 쪽에 매핑됨.)
예를 들어 박스의 인라인 치수가 over-constrained일 때 버려지는 마진은 포함 블록의 작성 모드 기준 end 마진입니다.
마진 겹침 규칙은 block-start 마진을 top 마진으로, block-end 마진을 bottom 마진으로 대체해서 그대로 적용됩니다. 마찬가지로 block-start 패딩과 테두리가 top 패딩/테두리로, block-end 패딩/테두리가 bottom 패딩/테두리로 대체됩니다. 즉, block-start와 block-end 마진만 겹침이 발생합니다.
흐름 기준 방향은 박스 자신의 작성 모드 기준으로 산정되어, 박스 콘텐츠 관련 레이아웃에 추상적으로 적용됩니다:
- text-align 속성의 초기값은 줄 박스의 start 에지에 정렬됨.
- text-indent 속성은 줄 박스의 start 에지에서 들여쓰기.
- 테이블의 열 순서는 테이블의 inline-start 쪽에서 시작, 행 순서는 block-start 쪽에서 시작.
7.5. 줄 기준 매핑
줄 기준 방향은 over, under, line-left, line-right입니다. LTR horizontal-tb 작성 모드에서는 각각 위, 아래, 왼쪽, 오른쪽 방향에 해당합니다.
line-right와 line-left 방향은 박스의 작성 모드를 기준으로 산정되며, 아래 속성의 left와 right 값을 해석하는 데 사용됩니다:
- text-align 속성 [CSS2]
line-right와 line-left 방향은 박스의 포함 블록 작성 모드를 기준으로 산정되며, 다음 속성의 left와 right 값을 해석하는 데 사용됩니다:
over와 under 방향은 박스의 작성 모드를 기준으로 산정되며, 줄박스의 "top"(over)과 "bottom"(under) 쪽 해석에 사용됩니다:
- vertical-align 속성에서, 줄박스의 "top"은 over 에지, "bottom"은 under 에지입니다. 양수 길이 및 백분율 값은 기준선을 line-over 에지 쪽으로 이동시킵니다. [CSS2]
- text-decoration 속성에서, 밑줄은 텍스트의 under 쪽에, 윗줄은 over 쪽에 그려집니다. [CSS2] CSS Text Decoration 모듈에서는 밑줄/윗줄 위치를 더 자세히 정의하며, 추가 제어 기능을 제공합니다. [CSS3-TEXT-DECOR]
7.6. 순수 물리적 매핑
아래 값들은 정의상 순수 물리적이며, 작성 모드 변화에 반응하지 않습니다:
- rect() 표기법(clip 속성) [CSS2]
- background 속성 [CSS2] [CSS3BG]
- border-image 속성 [CSS3BG]
- box-shadow와 text-shadow 속성의 오프셋
8. 주요 작성 모드
문서의 주요 작성 모드는 루트 요소의 used writing-mode, direction, text-orientation 값에 의해 결정됩니다. 예를 들어, 이 작성 모드는 스크롤 방향, 기본 페이지 진행 방향 등을 결정하는 데 사용됩니다.
HTML 문서 처리를 위한 특수 규칙으로,
루트 요소에
body
자식 요소가 있을 경우 [HTML],
루트 요소의 used value writing-mode와 direction 값은
루트의 값이 아니라 첫 번째 자식의 computed writing-mode, direction 값을 사용합니다.
UA는 text-orientation 값도 이 방식으로 전달할 수 있습니다.
단, 이는 루트 요소 자체의 writing-mode, direction, text-orientation의 computed 값에는 영향을 주지 않습니다.
참고: 전달은 computed 값이 아니라 used 값에 대해 이루어지며, 이는 상속, 논리적 속성 매핑 로직, 길이 값 계산 등 스타일 계산의 다른 측면에 영향을 주지 않기 위함입니다.
8.1. 초기 포함 블록으로의 전달
주요 작성 모드는 초기 포함 블록 및 뷰포트로 전달되어, 루트 요소의 레이아웃과 뷰포트의 스크롤 방향에 영향을 줍니다.
8.2. 페이지 흐름: 페이지 진행 방향
페이징 미디어에서 CSS는 모든 페이지를 왼쪽/오른쪽 페이지로 분류합니다. 페이지 진행 방향([CSS3PAGE] 참고)은 스프레드에서 왼쪽/오른쪽 페이지 중 어느 쪽이 흐름의 처음인지, 첫 페이지가 기본적으로 왼쪽/오른쪽 중 어느 쪽인지 결정하며, 주요 작성 모드에 따라 아래와 같이 달라집니다:
주요 작성 모드 | 페이지 진행 방향 |
---|---|
horizontal-tb 및 ltr | 왼쪽에서 오른쪽 |
horizontal-tb 및 rtl | 오른쪽에서 왼쪽 |
vertical-rl 또는 sideways-rl | 오른쪽에서 왼쪽 |
vertical-lr 또는 sideways-lr | 왼쪽에서 오른쪽 |
참고: 별도로 지정하지 않는 한, 문서의 첫 페이지는 스프레드의 두 번째 절반(예: 왼쪽에서 오른쪽 페이지 진행에서는 오른쪽 페이지)에서 시작합니다.
9. 글리프 조합
9.1. 수직 내 수평 조합: text-combine-upright 속성
이름: | text-combine-upright |
---|---|
값: | none | all | [ digits <integer>? ] |
초기값: | none |
적용 대상: | 대체되지 않은 인라인 요소 |
상속됨: | yes |
백분율: | 해당 없음 |
계산된 값: | 지정된 키워드 및 digits일 경우 정수 |
정규 순서: | 해당 없음 |
애니메이션 타입: | 애니메이션 불가 |
이 속성은 여러 타이포그래픽 문자 단위를 한 개의 타이포그래픽 문자 단위 공간에 합치는 조합을 지정합니다. 조합된 텍스트가 1em보다 넓으면 UA는 내용을 1em 내에 맞춰야 합니다(아래 참고). 결과 조합은 레이아웃과 장식 목적으로 하나의 똑바른 글리프로 처리됩니다. 이 속성은 수직 작성 모드에서만 효과가 있습니다. 값 의미:
- none
- 특별한 처리 없음.
- all
- 박스 내 연속 타이포그래픽 문자 단위 전체를 수직 줄박스 내 한 개 타이포그래픽 문자 단위 공간에 수평으로 조판 시도.
- digits <integer>?
- 각 최대 연속 ASCII 숫자(U+0030–U+0039) 시퀀스 중, 지정된 정수 이하의 숫자를 한 개 타이포그래픽 문자 단위 공간에 수평으로 조판 시도. 정수가 생략되면 2로 계산. 2~4 범위 밖 정수는 무효.
동아시아 문서에서는 text-combine-upright 효과가 날짜 구성이나 약어 등 라틴계 문자열을 표시할 때 자주 사용됩니다. 항상 줄 모드와 관계 없이 수평 작성 모드로 표시됩니다:
수직 내 수평(tate-chu-yoko) 예시
그림은 다음 규칙의 결과입니다
date { text-combine-upright: digits 2; }
및 아래 마크업:
<date>平成20년4월16일에</date>
일본에서는 이 효과를 tate-chu-yoko라고 합니다.
다음 예시는 text-combine-upright: digits 2를 전체 문서에 적용하면, 숫자 타입의 일부 구간이 아닌 경우 의도치 않은 결과가 나올 수 있음을 보여줍니다:
<p>저건 10,000엔이에요!</p>
잘못 적용된 tate-chu-yoko 예시
9.1.1. 텍스트 런 규칙
렌더링과 레이아웃 복잡도를 피하기 위해, text-combine-upright는 순수 텍스트(박스 경계로 끊기지 않은 연속 타이포그래픽 문자 단위)만 조합할 수 있습니다.
그러나 속성이 상속되므로, UA는 조합을 적용하는 박스의 내용이 박스 외부에서 시작/끝나는 조합 가능한 시퀀스의 일부가 아니도록 보장해야 합니다; 만약 그렇다면, 텍스트는 text-combine-upright가 none인 것처럼 정상적으로 레이아웃됩니다. 부분 시퀀스만 조합하는 것을 방지하기 위해: 조합 가능한 런의 경계가 인라인 박스 경계 때문이라면, UA는 런 바로 앞뒤의 문자를 검사하여, 만약 이 문자가 중간 박스 없이 하나의 조합 가능한 시퀀스를 이룬다면(길이 초과가 아니면), 해당 런은 조합하지 않아야 합니다.
위 문단은 위험군입니다. 구현자 의견 환영합니다.
예를 들어, 다음 규칙이 있을 때
tcy { text-combine-upright: digits 4; }
아래 마크업을 주면:
<tcy>12<span>34</span></tcy>
텍스트는 조합되지 않음: 12와 34는 동일한 text-combine-upright 값의 조상을 공유하고, 박스 경계로 인해 네 글자 조합 시퀀스가 끊기므로 조합되지 않음. 반대로 아래 경우:
12<tcy><span>34</span></tcy>12<tcy><span></span>34</tcy> 12<tcy>34<span></span></tcy>
34는 조합됨; 앞의 12가 34와 text-combine-upright 값을 공유하지 않으므로 34는 두 글자 조합 시퀀스 전체로 간주됨.
다음 규칙을 사용하면
tcy { text-combine-upright: all; }
결과는 동일: 첫 번째는 1234가 박스 경계로 끊긴 네 글자 조합 시퀀스이므로 조합되지 않고, 두 번째는 34가 두 글자 조합 시퀀스 전체이므로 조합됨.
text-combine-upright (all 또는 digits) 값은 어떤 타이포그래픽 문자 단위가 조합 가능한지, 조합 가능한 시퀀스의 최대 길이에만 영향을 줍니다. 그 외 동작에는 영향을 주지 않습니다.
9.1.2. 레이아웃 규칙
text-combine-upright: all을 적용하여 텍스트를 조합할 때, 조합된 텍스트의 글리프는 bidi-isolate되고 수평으로 조합됩니다 (letter-spacing 및 강제 줄 바꿈은 무시하지만, 지정된 폰트 설정은 사용함), inline-block 박스의 내용과 유사하며, 수평 작성 모드와 line-height가 1em인 상태와 비슷합니다. 조합된 텍스트의 시작/끝에 포함된 문서 공백은 반드시 처리 [CSS-TEXT-3]되어야 하며, 이는 해당 inline-block의 시작/끝과 동일하게 처리됩니다. 조합의 유효 크기는 1em 정사각형으로 간주하며, 정사각형 바깥의 부분은 레이아웃 계산에 포함되지 않습니다. UA는 글리프를 1em 정사각형 내에서 수평 및 수직으로 중앙 정렬해야 합니다.
결과 조합의 기준선은, 해당 정사각형이 부모 인라인 박스의 text-over와 text-under 기준선 사이에 중앙에 오도록 선택되어야 하며, 기준선 정렬 이동(vertical-align) 이전에 적용됩니다. 양방향 재정렬에서는, 이 조합은 타이포그래픽 문자 단위와 동일하게 text-orientation: upright으로 처리됩니다. 줄 바꿈 처리에서는, 조합 전후를 실제 내용이 있는 일반 인라인처럼 취급합니다. 그 외 텍스트 레이아웃(강조 마크, text-decoration, 간격 등)에서는 결과 조합을 U+FFFC 오브젝트 대체 문자 하나의 글리프로 처리합니다.
9.1.3. 압축 규칙
UA는 조합 텍스트의 전체 advance width가 1em 내에 들어가도록, 필요하면 텍스트를 압축해야 합니다.
(이는 글리프가 반드시 1em 내에 들어간다는 뜻은 아니며, 일부 글리프는 기하학적 경계를 넘어 그려집니다.)
OpenType 구현은 반드시 width-specific variants(OpenType hwid
/twid
/qwid
기능;
fwid
또는 pwid
등 기타 글리프 너비 기능은 포함하지 않음)를 사용하여,
조합 내 모든 타이포그래픽 문자 단위에 해당 변형이 있는 경우 압축해야 합니다.
그렇지 않으면 UA는 폰트가 지원하는 반폭, 3분폭, 4분폭 글리프 치환, 기타 수평 압축 폰트 기능, 기하학적 스케일링, 또는 이들의 조합 등 임의의 방법으로 텍스트를 압축할 수 있습니다.
예를 들어, 단순 OpenType 기반 구현은 아래와 같이 텍스트를 압축할 수 있습니다:
- 조합 텍스트가 n 타이포그래픽 문자 단위라면, 1/n 폭 글리프 활성화(OpenType
hwid
는 2글자 타이포그래픽 문자 단위,twid
는 3글자 타이포그래픽 문자 단위 등) (타이포그래픽 문자 단위 > 1일 때) (타이포그래픽 문자 단위 수 ≠ 유니코드 코드포인트 수!) - 결과가 1em보다 넓으면, 수평 스케일링하여 1em에 맞춤.
다른 OpenType 레이아웃 기능 활용 구현은, 먼저 일반 글리프로 조합해서 1em에 맞는지 확인 후, 필요시 반폭/3분폭 형태로 치환하고, 치환 가능한 글리프에 따라 스케일링 등을 조합해서 처리할 수 있습니다.
일부 폰트에서는 이데오그래픽 글리프가 1em보다 짧게 디자인되어, 1em 폭이지만 세로로는 1em 미만입니다. 이런 폰트를 고려하여 UA는 조합을 水(U+6C34) 글리프 advance height에 맞게 수직 스케일링할 수 있습니다. 이 경우 결과 조합은 1em이 아니라 水(U+6C34)의 advance height를 갖게 됩니다.
9.1.3.1. 전각 문자
텍스트를 1em으로 압축할 때 타이포그래픽 컬러를 유지하기 위해, 조합 텍스트가 둘 이상의 타이포그래픽 문자 단위로 이루어진 경우 모든 전각 타이포그래픽 문자 단위는 먼저 text-transform: full-width의 알고리즘을 역변환하여 반각으로 바꾼 뒤, 기타 압축을 적용해야 합니다. [CSS-TEXT-3]
예를 들어, 작성자가 수직 텍스트에 날짜에 text-transform과 text-combine-upright 모두를 적용할 수 있습니다.
date { text-combine-upright: digits 2; text-transform: full-width; }
이 스타일 규칙이 아래 날짜에 적용된다고 가정하면,
<date>2010년2월23일</date>
"2010"은 너무 길어(4글자) 조합되지 않고, "2"와 "23"에만 적용됨. "23"은 둘 이상의 타이포그래픽 문자 단위이므로 text-transform: full-width는 적용되지 않음. 하지만 "2"는 한 글자이므로 전각 "2"로 변환됨. "2010"은 조합되지 않으므로 각 숫자도 전각 "2010"으로 변환되어 똑바로 세워짐. 결과 예시:
2 0 1 0 년 2 월 23 일
글리프 선택에 영향을 주는 속성(font-variant, font-feature-settings 등, [CSS3-FONTS] 참조)은 조합 텍스트 런 내 문자 변형 선택에 영향을 줄 수 있으므로, text-combine-upright와 함께 사용할 때 주의해서 사용해야 합니다.
10. 프라이버시 및 보안 고려사항
이 명세는 새로운 프라이버시 누수나 "정확하게 구현"을 넘는 추가 보안 고려사항을 도입하지 않습니다.
변경 사항
2018년 5월 CSS Writing Modes Module Level 4 Candidate Recommendation 이후 변경 사항
- body 요소에서 주요 작성 모드를 초기 포함 블록/뷰포트로 전달하는 것이 루트 요소의 used value에도 영향을 주지만, computed 값에는 영향을 주지 않음을 명확히 함. 또한 text-orientation 전달도 선택적으로 허용. 이 변경은 3버전에도 적용됨. (이슈 3066)
-
text-combine-upright 조합 텍스트 시퀀스의 시작/끝 공백은
inline-block과 동일하게 처리된다는 점을 명확히 함.
(이슈 4139)
이 변경은 3버전에도 적용됨.
text-combine-upright: all로 텍스트를 조합할 때, 조합된 텍스트의 글리프는 bidi-isolate되고 수평으로 조합됨 (letter-spacing 및 강제 줄 바꿈은 무시하지만, 지정된 폰트 설정은 사용함), inline-block 박스의 내용과 유사하며, 수평 작성 모드와 line-height가 1em인 상태와 비슷함. 조합된 텍스트의 시작/끝에 포함된 문서 공백은 반드시 처리 [CSS-TEXT-3]되어야 하며, 이는 해당 inline-block의 시작/끝과 동일하게 처리됨.
레벨 4 신규 사항
이 모듈은 CSS Writing Modes Level 3 2015년 후보 권고안의 복사본입니다. 현재 CSS Writing Modes Level 3와의 차이는 3버전에서 구현 지연으로 연기된 기능 집합입니다:
- sideways-lr 및 sideways-rl 값을 writing-mode에 다시 도입하였습니다.
- digits 값을 text-combine-upright에 다시 도입하였습니다.
- 직교 흐름의 자동 다단 행동을 다시 도입하였습니다.
- bidi 재정렬로 인한 단편화 조건을 명확히 하였습니다. (Issue 1509)
감사의 글
L. David Baron, Brian Birtles, James Clark, John Daggett, Nami Fujii, Daisaku Hataoka, Martin Heijdra, Laurentiu Iancu, Richard Ishida, Jonathan Kew, Yasuo Kida, Tatsuo Kobayashi, Toshi Kobayashi, Ken Lunde, Shunsuke Matsuki, Nat McCully, Eric Muller, Paul Nelson, Kenzou Onozawa, Chris Pratley, Xidorn Quan, Florian Rivoal, Dwayne Robinson, Simon Sapin, Marcin Sawicki, Dirk Schulze, Hajime Shiozawa, Alan Stearns, Michel Suignard, Takao Suzuki, Gérard Talbot, Masataka Yakura, Taro Yamamoto, Steve Zilles
부록 A: 유니코드의 수직 문자
이 절은 참고용입니다.
이 부록은 Unicode 6.0 vertical-only 및 bi-orientational 문자 체계와 이들의 수평→수직 전환 방식을 나열합니다. 명시적으로 나열되지 않은 문자 체계는 horizontal-only로 간주됩니다. Unicode 문자 분류는 [UAX24]에 정의되어 있습니다.
코드 | 이름 | 변환(시계 방향) | 수직 고유 방향 |
---|---|---|---|
Bopo | 보포모포 | 0° | ttb |
Egyp | 이집트 상형문자 | 0° | ttb |
Hira | 히라가나 | 0° | ttb |
Kana | 가타카나 | 0° | ttb |
Hani | 한자 | 0° | ttb |
Hang | 한글 | 0° | ttb |
Merc | 메로에티 문자 | 0° | ttb |
Mero | 메로에티 상형문자 | 0° | ttb |
Mong | 몽골문자 | 90° | ttb |
Ogam | 오감 문자 | -90° | btt |
Orkh | 오르콘 문자 | -90° | ttb |
Phag | 파스파 문자 | 90° | ttb |
Yiii | 이 문자 | 0° | ttb |
예외: 이 명세에서는 모든 전각(F) 및 와이드(W) 문자는 수직 문자 체계에 속하고, 반각(H) 문자는 수평 문자 체계에 속한 것으로 처리합니다. [UAX11]
vertical-only 문자(몽골문자, 파스파 문자 등)의 경우, 유니코드 코드 차트의 글리프는 수직 방향으로 표시됩니다. 수평 텍스트에서는 이 방향에서 90° 반시계 방향으로 회전해 조판됩니다.
Unicode Technical Report 50 및 CSS Writing Modes의 현재 기능 제한으로 인해, 수직 mixed 조판은 오감 문자나 오르콘 문자를 자동으로 처리하지 못합니다. 이러한 문자에는 sideways-lr을 사용해 조판할 수 있습니다.