시각적 서식 모델
CSS 시각적 서식 모델 (visual formatting model)은 문서를 처리하여 그것을 시각적 매체에 표시하는 알고리즘입니다. 이 모델은 CSS의 기본 개념입니다.
시각적 서식 모델은 문서의 각 요소를 변환하여, CSS 상자 모델에 부합하는 0, 1 또는 여러 상자를 생성합니다. 각 상자의 레이아웃은 다음과 같이 정의됩니다:
- 상자의 면적: 정확히 정의하거나 제약을 받거나, 아에 정의하지 않습니다.
- 상자의 유형: 인라인, 인라인수준, 원자 인라인수준, 블록.
- 위치잡기 기법: 일반 대열 소속, 부동체, 또는 절대 위치잡기.
- 트리 구조에 속한 다른 요소 무리: 그것의 자녀와 이웃.
- viewport 크기와 위치.
- 컨테이너에 속한 이미지의 고유한 면적.
- 다른 외부 정보
동 모델은 컨테이너 블록의 모서리 기준과 비례하여 상자를 렌더링합니다. 보통, 하나의 상자는 자기 자손들을 위한 컨테이너 블록을 수립합니다. 그러나 상자는 자신의 상위 컨테이너 블록에 구속되지 않습니다. 상자 레이아웃이 상위 컨테이너 블록을 벗어나면 대열이탈 (overflow)했다고 말합니다..
상자 생성
상자 생성은 해당 문서의 요소로부터 상자를 생성하는 CSS 시각적 서식 모델의 일부입니다. 생성된 상자는 다양한 유형으로, 이 유형은 시각적 서식이 이뤄지는 방식에 영향을 미칩니다. 생성되는 상자 유형은 display
CSS 속성의 값 여하에 따라 달라집니다.
블록수준 요소와 블록 상자
어떤 요소를 블록수준이라고 말하려면 계산된 display
CSS 속성값이 block
, list-item
, 또는 table
일 때입니다. 블록수준 요소는 사실상 하나의 블록으로 취급되어 시각적으로 서식되며, 수직적으로 겹겹이 포개집니다.
각각의 블록수준 상자는 블록 서식 상황 (en-US)에 참여합니다. 각 블록수준 요소는 적어도 하나의 블록수준 상자를 생성하며 이를 일컬어 수석 블록수준 상자< (principal block-level box) 라고 합니다. 일부 요소 무리는 목록항목 요소와 같이 목록 항목을 안내하는 글머리표와 서로 다른 타이포그래픽 요소를 처리하기 위한 상자를 추가적으로 생성하듯 더 많은 상자 무리를 생성할 수 있습니다. 대다수는 수석 블록 수준 상자만을 생성합니다.
수석 블록수준 상자는 자손이 생성한 상자 및 콘텐츠를 포함합니다. 상자는 위치잡기 기법에도 관여하고 있습니다.
블록 수준 상자는 역시 블록 콘테이너 상자도 될 수 있습니다. 블록 컨테이너 상자는 다른 블록수준 상자만을 포함하고 인라인 서식 상황 (en-US)을 생성하므로 인라인 상자 무리만을 포함합니다.
중요한 점은 블록수준 상자와 블록 컨테이너 상자의 개념은 별개라는 점에 유의해야 한다는 것입니다. 첫째, 상자가 자기 부모와 형제자매과 함께하는 행동 방식을 설명합니다. 둘째, 상자가 자기 자손과는 어떻게 상호작용하는지 설명합니다. 테이블과 같은 블록 수준의 상자 무리는 블록 컨테이너 상자가 아닙니다. 마찬가지로 비객원< (non-replaced) 인라인 블록과 비객원 테이블 셀과 같은 일부 블록 컨테이너 상자는 블록 수준 상자가 아닙니다.
또한, 블록 컨테이너 상자이며 동시에 블록수준 상자를 일컬어 우리는 블록 상자< (block boxes) 라고 부릅니다.
무명 블록 상자
경우에 따라서는 시각적 서식 알고리즘은 보충 상자를 추가할 알고리즘도 필요합니다
CSS 선택기는 해당 상자에 이름을 부여하거나 스타일링을 할 수 없기 때문에 이를 일컬어무명 상자라고 합니다.
선택기는 무명 상자와 협력하지 않기 때문에 스타일시트를 통해 스타일링이 적용될 수 없습니다. 즉, 상속할 수 있는 모든 CSS 속성은 inherit
값을 갖고 상속할 수 없는 CSS 속성은 initial
값을 가집니다.
상자를 포함하는 블록은 인라인수준 상자 또는 블록수준 상자만을 포함합니다. 그러나 문서는 두 가지 모두를 혼합해 포함합니다. 그 경우 무명 블록 상자는 인접 인라인수준 상자 주변에 생성됩니다.
예제
아래와 같은 (<div>
와 <p>
에 기본값 스타일링이 적용된 HTML 코드가 display: block
속성을 갖고 있다면:
<div>약간의 인라인 텍스트 <p>뒤를 잇는 단락 하나</p> 그 뒤를 잇는 인라인 텍스트.</div>
두 개의 무명 블록 상자가 만들어집니다: 하나는 단락 이전 텍스트(약간의 인라인 텍스트
) 나머지 하나는 단락 이후 텍스트(그 뒤를 잇는 인라인 텍스트
). 이는 다음과 같은 블록 구조를 구축합니다:
결과는:
약간의 인라인 텍스트 뒤를 잇는 단락 하나 그 뒤를 잇는 인라인 텍스트.
<p>
요소인 상자와 달리 웹 개발자는 두 개의 무명 상자 스타일을 제어할 수 없습니다. 상속 가능한 속성은 (마치 텍스트의 색상을 정의하기 위한 color
와 같이) <div>
의 속성 값에서 값을 취하고, 나머지는 초기(initial
)값으로 설정합니다. 예를 들어, 무명 상자는 background-color
를 갖지 않을 것이라, 항상 해당 속성의 초기(initial
)값을 가지며 투명합니다. 따라서 <div>
의 배경이 보여집니다. 특정 배경색은 <p>
상자에 적용할 수 있습니다. 마찬가지로 두 무명 상자는 항상 같은 색을 텍스트에 사용합니다.
무명 블록 상자를 만드는 또 다른 사례는 하나 또는 여러 개의 블록 상자를 포함하는 인라인 상자입니다. 이 경우 블록 상자가 들어있는 상자는 두 개의 인라인 상자로 쪼개집니다. 하나는 블록 상자 이전에, 다른 하나는 뒤에 옵니다. 블록 상자 이전의 모든 인라인 상자는 무명 블록 상자로 포섭되며, 블록 상자 뒤에 있는 인라인 상자도 마찬가지입니다. 따라서 블록 상자는 인라인 요소를 포함하는 두 개의 무명 블록 상자의 형제가 됩니다.
중간에 인라인 콘텐츠가 없이 여러 블록 상자가 있는 경우 무명 블록 상자가 해당 상자 집합 이전과 이후에 생성됩니다.
예제
아래 HTML 코드를 보면 <p>
는 display: inline
속성을 갖고 있고 <span>
는 display:block
속성을 갖고 있습니다:
<p>일부 <em>인라인</em> 텍스트 <span>그 뒤를 잇는 단락</span> 그 뒤를 잇는 추가 인라인 텍스트.</p>
두 개의 무명 블록 상자가 생성되었습니다. 스팬 요소 이전의 텍스트(일부 인라인 텍스트
) 하나와 그 뒤의 텍스트(그 뒤를 잇는 추가 인라인 텍스트
) 하나가 있는데 이로써 다음과 같은 블록 구조가 주어졌습니다:
이 것의 결과는:
약간의 인라인 텍스트 뒤를 잇는 단락 하나 그 뒤를 잇는 인라인 텍스트.
인라인수준 요소와 인라인 상자
어떤 요소가 인라인수준이라고 말하려면 자신의 계산된 display
CSS 속성 값이 inline
, inline-block
또는 inline-table
일 때입니다. 시각적으로는 이것은 콘텐츠로 이뤄진 블록 무리를 구성하지 않고 다른 인라인수준 콘텐츠와 함께 라인의 형태로 배포됩니다. 일반적으로 강조 또는 이미지와 같이 서로 다른 서식을 가진 단락의 콘텐츠는 인라인수준 요소로 만들어집니다.
경고: 이 도식은 구식 용어를 사용합니다: 아래 참조 사항을 보세요. 그것 이외에도 오른쪽의 노란색 타원은 정의에 따르면 왼쪽의 타원형과 동일하거나 그보다 크기 때문에(수학적 상위집합일 수 있어) 그림이 틀렀습니다, 왜냐하면 해당 CSS 스펙을 보면 "인라인수준 요소는 인라인 서식 상황에 참여하는 상자인 인라인수준 상자를 생성한다"라고 쓰여있기 때문입니다. CSS 2.2, 9.2.2장 참조
인라인 수준 요소는 인라인 서식 상황에 참여하는 상자로 정의되는 인라인수준 상자를 생성합니다. 인라인 상자는 상자와 인라인 수준 상자 모두가 해당합니다. 다만 이들 상자의 콘텐츠는 인라인 서식 상황에 참여해야 합니다. 예를 들어, display: inline
속성을 가진 모든 비객원 상자의 경우가 인라인입니다. 인라인 서식 상황에 참여하지 않는 인라인수준 상자를 원자 인라인수준 상자 (atomic inline-level boxes)라고 합니다. 객원 인라인수준 요소 또는 계산된 display
값이 inline-block
인 요소에 의해 생성된 해당 상자 무리는 인라인 상자에서 가능했던 것처럼 여러 상자로 쪼개지지 않습니다.
참고: 처음에는 원자 인라인수준 상자를 원자 인라인 상자라고 불렀습니다. 그 명명은 불행한 일입니다. 인라인 상자가 아니기 때문입니다. 이건 CSS 규격 상에 오타로 시정된 겁니다. 그렇긴 하지만, 문장 속에서 원자 인라인 상자를 마주칠 때마다 무리없이 원자 인라인 수준 상자로 읽을 수 있습니다. 그냥 이름 변경에 불과하기 때문입니다.
참고: 원자 일라인 상자는 인라인 서식 상황 속에서 여러 라인에 걸쳐 분할될 수 없습니다.
<style>
span {
display:inline; /* default value*/
}
</style>
<div style="width:20em;">
스팬 요소에 포함된 택스트는 <span> 몇 개의 라인으로 분할 될 수
있습니다. 왜냐면 </span> 그것이 인라인 상자이기 때문입니다.
</div>
이 것의 결과는: The text in the span can be split into several lines as it is an inline box.
<style>
span {
display:inline-block;
}
</style>
<div style="width:20em;">
스팬 요소에 포함된 텍스트는 <span>몇 라인으로 분할 될 수
없 습니다. 왜냐면 </span> 그것이 인라인 블록이기 때문입니다.
</div>
이 것의 결과는:스팬 요소에 포함된 텍스트는 분할될 수 없습니다. 왜냐면 인라인 블록 상자이기 때문입니다.
무명 인라인 상자
블록상자처럼 CSS 엔진에 의해 자동적으로 인라인상자가 생성되는 경우가 몇 개 있습니다. 이들 인라인 상자는 무명으로, 선택기가 이름을 특정할 수 없습니다. 무명 인라인 상자의 속성은, 상속 가능한 것은 상속된 값을, 그 이외는 initial
값을 가집니다.
무명의 인라인 상자가 만들어지는 흔한 경우는 인라인 서식 상황을 만드는 블록상자의 직계 자식 요소로 파악되는 텍스트가 있는 경우입니다. 이 경우, 동 텍스트는 최대한 큰 무명 인라인 상자에 넣을 수 있습니다. 또한, CSS의 white-space
속성으로 지정된 동작에 의해 제거되는 공백의 콘텐츠는 결국 공백이 될 것이기 때문에 무명 인라인 상자를 생성하지 않습니다.
참고: 예제 TBD
다른 유형의 상자
라인 상자
라인 상자는 텍스트 라인을 표현하기 위해 인라인 서식 상황에 의해 생성되는 상자입니다. 블록 상자 내부의 라인 상자는 상자의 한쪽 테두리로부터 반대측의 테두리까지 넓어집니다. 부동체 (en-US)가 있을 경우 라인 상자 구역은 왼쪽 부동체의 맨우측 테두리에서 시작해 우측 부동체의 맨좌측 테두리에서 끝납니다.
이들 상자는 기술적인 것으로, 보통 웹 저술가가 이것에 대해 고민할 필요는 없습니다.
내부진행 상자
display: run-in
을 사용하도록 정의되는 내부진행 상자 (Run-in boxes)는 후속 상자의 유형 여하에 따라 블록 상자이거나 인라인 상자입니다. 그들은 가능할 경우 자신의 첫 단락 내부에 진행하는 글 제목을 생성하는 데 사용될 수 있습니다.
참고: 내부진행 상자는 CSS 2.1 규격에서 제외되었다. 상호운용 실현 가능성을 불충분하게 명시했기 때문입니다. 그들이 CSS 3 (CSS 3)에선 다시 등장할 수도 있지만, 현재로선 실험 상태로 간주합니다. 그들을 완성품에선 사용하지 말아야 합니다.
모델유인 상자
인라인 및 블록 서식 상황 외에도 CSS는 요소에 적용할 수 있는 몇 가지 추가 콘텐츠 모델을 지정할 수 있습니다. 특정 레이아웃을 설명하는 데 사용되는 이러한 추가 모델은 추가 상자 유형을 정의할 수 있습니다.
- 테이블 콘텐츠 모델 (en-US)은 테이블 래퍼 상자와 테이블 상자를 생성할 수 있을뿐만 아니라 캡션 상자같은 특정 상자도 생성할 수 있습니다.
- The 다단 콘텐츠 모델 (en-US) 은 컨테이너 상자와 컨텐츠 사이에 열 상자 (column boxes) 를 생성할 수 있습니다.
- 실험적인 격자 또는 가변상자 콘텐츠 모델, 또는 추가적인 유형의 상자를 생성할 수 있습니다.
위치잡기 기법
상자를 생성하고 나면 CSS 엔진은 그것들을 레이아웃에 위치시켜야 합니다. 그렇게 하려면 다음과 같은 알고리즘 중의 하나를 사용합니다.
- 일반 대열 (normal flow) - 하나씩 차례대로 상자를 위치시킵니다.
- 부동체 (floats) 알고리즘 - 일반 대열에서 상자를 빼내어 상위 컨테이너 상자 옆에 놓습니다.
- 절대 위치잡기 기법 - 자신의 상위 컨테이너 요소가 수립한 절대 좌표 시스템 내부에 상자를 위치시킵니다. 절대적으로 위치잡기한 요소는 다른 요소를 덮을 수 있습니다.
일반 대열
예제
참고: 일반 대열 속에서는 블록 서식 상황에 포함된 상자는 수직으로 하나씩 차례대로 배치됩니다.
일반 대열 속에서는 인라인 서식 상황에 포함된 상자는 수평으로 하나씩 차례대로 배치됩니다.
참고: 일반 대열에는 두 가지 하위 사례가 있습니다. 정적 위치잡기와 상대 위치잡기:
- 정적 위치잡기에서는
position
속성이static
값일 경우에 발동됩니다. 상자 무리는 일반 대열 레이아웃에 정의된 정확한 위치에 그려집니다. - 상대 위치잡기에서는
position
속성이relative
값일 경우 발동합니다. 상자는 CSS 속성 무리인top
(en-US),bottom
(en-US)과left
(en-US),right
(en-US)에 의해 정의된 간격띄우기 값을 기준으로 그려집니다.
부동체
부동 위치잡기 기법 (float positioning scheme)에서는 특정 상자(부동 상자 또는 단순 부동체라고 일컬음)를 현재 라인의 시작 또는 끝에 위치시킵니다. 이는 텍스트(그리고 더 일반적으로 일반 대열 내의 모든 것)은 부동 상자의 가장자리를 따라 대열을 맞추는 속성으로 귀결됩니다. 다만 CSS clear
속성에 의해 다른 예기가 나올 경우는 예외입니다.
상자에 대해 부동 위치잡기 기법을 선택하려면 해당 상대에 대해 CSS float
속성을 none
이외의 값으로 설정하거나 position
속성에 static
이나 relative
가 아닌 값으로 설정할 때 이뤄진다. 만일 float
가 left
로 설정되면 부동체는 라인 상자의 시작 부분에 위치합니다. 만일 right
으로 설정되면 동 부동체는 라인 상자의 끝에 위치합니다. 어떤 경우든 라인 상자는 부동체에 들어맞게 축소됩니다.
절대 위치잡기
절대 위치잡기 기법 (absolute positioning scheme)에 포함된 상자는 대열에서 제거되어 대열과는 어떤 상호작용도 하지 않습니다. 그들은 top
(en-US)과 bottom
(en-US), left
(en-US)와 right
(en-US)를 사용해서 상위 컨테이너 블록 기준으로 비례해서 위치잡기합니다.
하나의 요소를 절대 위치잡기하려면 position
이 absolute
또는 fixed
로 설정하면 됩니다.
고정 위치잡기한 요소의 경우 상위 컨테이너 블록이 뷰포트입니다. 동 요소의 위치는 뷰포트 내부에서 절대적 위치가 됩니다. 스크롤링은 동 요소의 위치를 변경시키지 않습니다.