1. 소개
CSS는 문서의 렌더링을 지시하는 속성이라고 불리는 유한한 매개변수 집합을 정의합니다. 각각의 속성은 이름(예: color, font-size, 또는 border-style), 값의 공간 (예: <color>, <length-percentage>, [ solid | dashed | dotted | … ]), 그리고 문서의 렌더링에 대해 정의된 동작을 가집니다. 속성 값들은 속성 선언을 통해 문서의 다양한 부분에 할당되며, 해당 요소나 박스에 대해 (예: red, 12pt, dotted) 속성에 값을 할당합니다.
CSS의 근본적인 설계 원칙 중 하나는 계단식입니다. 이를 통해 여러 스타일 시트가 문서의 표현에 영향을 줄 수 있습니다. 서로 다른 선언이 같은 요소/속성 조합에 대해 값을 설정하려고 할 때, 그 충돌은 반드시 해결되어야 합니다.
반대로, 어떤 선언도 요소/속성 조합에 대해 값을 설정하지 않을 때의 문제가 있습니다. 이런 경우에는 상속이나 속성의 초기값을 참고하여 값을 찾게 됩니다.
계단식 및 기본값 처리 프로세스는 선언의 집합을 입력으로 받아, 각 요소의 각 속성에 대해 지정 값을 출력합니다.
문서 내 모든 요소의 모든 속성에 대해 지정 값을 찾는 규칙은 이 명세에서 설명합니다. 페이지 컨텍스트와 마진 박스에서 지정 값을 찾는 규칙은 [css-page-3]에 설명되어 있습니다.
1.1. 모듈 상호작용
이 절은 규범적입니다.
이 모듈은 [CSS2] 6장에서 정의된 속성값 할당, 계단식 처리, 상속에 대한 규칙을 대체 및 확장합니다.
다른 CSS 모듈들은 여기서 정의된 일부 구문과 기능의 정의를 확장할 수 있습니다. 예를 들어 Media Queries Level 4 명세는 이 모듈과 결합할 때 <media-query> 값 타입의 정의를 확장합니다.
이 명세의 목적상, 텍스트 노드는 해당 요소의 자식 요소로 취급되며, 모든 속성 집합을 가집니다. 선택자로 타겟팅될 수 없기 때문에 모든 계산값은 기본값 처리에 의해 할당됩니다.
2. 스타일 시트 가져오기: @import 규칙
@import 규칙은 사용자가 다른 스타일 시트에서 스타일 규칙을 가져올 수 있게 해줍니다. @import 규칙이 유효한 스타일시트를 참조하면, 사용자 에이전트는 해당 스타일시트의 내용을 @import 규칙이 위치한 곳에 직접 작성된 것처럼 처리해야 하며, 두 가지 예외가 있습니다:
-
특정 기능(예: @namespace 규칙)이 명시적으로 자신이 특정 스타일시트에만 적용되고 가져온 스타일시트에는 적용되지 않는다고 정의한 경우, 해당 기능은 가져온 스타일시트에 적용되지 않습니다.
-
기능이 스타일시트 내 두 개 이상의 구성 요소의 상대적 순서에 의존하는 경우 (예: @namespace 규칙은 @import 외에 다른 규칙이 앞에 오면 안 된다는 요구사항), 해당 규칙은 같은 스타일시트 내 구성 요소 사이에만 적용됩니다.
예를 들어, 가져온 스타일시트의 스타일 규칙 내 선언은 @import가 위치한 지점에 직접 작성된 것처럼 계단식에 영향을 줍니다.
모든 @import 규칙은 스타일시트 내 다른 유효한 at-규칙 및 스타일 규칙보다 앞에 와야 하며 (@charset 및 빈 @layer 정의는 무시함) 그리고 이전 @import 규칙과 그 사이에 다른 유효한 at-규칙 또는 스타일 규칙이 있어서는 안 되며, 그렇지 않으면 @import 규칙은 무효입니다. @import의 구문은 다음과 같습니다:
@import [ <url> | <string> ] [ layer | layer(<layer-name>) ]? [ supports( [ <supports-condition> | <declaration> ] ) ]? <media-query-list>? ;
여기서:
-
옵션인 layer 키워드 또는 layer() 함수는 스타일시트의 내용을 익명 계단식 레이어 또는 지정된 계단식 레이어에 할당합니다.
레이어는 스타일시트 가져오기에 실패하더라도 레이어 순서에 추가되며, 가져오기 조건의 영향을 받습니다(적절한 @layer 규칙이 해당 조건 그룹 규칙에 감싸져 선언된 것과 동일).
-
옵션인 [<supports-condition>|<declaration>] 및 <media-query-list> (통칭해서 가져오기 조건) 해당 규칙이 적용되는 조건을 나타냅니다.
@import url("narrow.css") supports(display: flex) handheld and (max-width: 400px);
@import url("tabs.css") layer(framework.component); @import url("override.css") layer();
<string>이 제공된 경우, 동일한 값의 <url>로 해석되어야 합니다.
@import "mystyle.css" ; @import url ( "mystyle.css" );
2.1. 조건부 @import 규칙
가져오기 조건을 통해 가져오기를 미디어 또는 기능 지원에 따라 다르게 적용할 수 있습니다. 가져오기 조건이 없으면, 가져오기는 무조건 적용됩니다. (<media-query-list>에 all을 지정하면 같은 효과입니다.) 가져오기 조건이 일치하지 않으면, 가져온 스타일시트의 규칙은 적용되지 않으며, 이는 가져온 스타일시트가 해당 조건으로 @media 및/또는 @supports 블록에 감싸진 것과 동일하게 처리됩니다.
@import url ( "fineprint.css" ) print; @import url ( "bluish.css" ) projection, tv; @import url ( "narrow.css" ) handheld and( max-width:400 px );
따라서 사용자 에이전트는 가져오기 조건이 일치하지 않는 한 조건부 가져오기를 가져오지 않을 수 있습니다. 또한 <supports-condition>이 가져온 스타일시트의 적용을 막으면, UA는 반드시 스타일시트를 가져오지 않아야 하며(다른 링크로 로드되는 경우는 제외) 반드시 import 규칙의 CSSImportRule.styleSheet 값에 null을 반환해야 합니다 (다른 링크로 로드된 경우에도).
@import url ( "fallback-layout.css" ) supports ( not( display: flex)); @supports ( display: flex) { ...}
가져오기 조건은 <media-query-list>로 제공되며, 이는 미디어 쿼리 리스트로 파싱되고 해석됩니다. 그리고 <supports-condition>은 [[supports query]]로 파싱되고 해석됩니다. <supports-condition> 대신 <declaration>이 제공된 경우, 이는 <supports-decl> (즉, 추가 괄호가 암시됨)로 해석되어야 하며, <supports-condition>으로 취급됩니다.
@import "mystyle.css" supports ( display: flex); @import "mystyle.css" supports (( display: flex));
가져오기 조건의 평가와 전체 구문은 Media Queries [MEDIAQ] 및 CSS 조건부 규칙 [CSS-CONDITIONAL-3] 명세에서 정의됩니다.
2.2. 스타일시트 가져오기 처리
동일한 스타일시트가 문서 내 여러 위치에서 import되거나 link된 경우, 사용자 에이전트는 각각의 링크를 독립된 스타일시트에 대한 링크처럼 처리(또는 그런 것처럼 동작)해야 합니다.
참고: 이는 리소스 가져오기에 대한 요구사항이 아니라, 스타일시트가 CSSOM에 반영되고 이 명세 등에서 사용되는 방식에 관한 것입니다. 적절한 캐싱을 전제하면, UA가 스타일시트를 한 번만 가져오는 것이 적합합니다. 여러 번 import되거나 연결되어 있더라도 말입니다.
가져온 스타일시트의 계단식 소스(origin)는 해당 스타일시트를 import한 스타일시트의 계단식 소스(origin)입니다.
가져온 스타일시트의 환경 인코딩은 해당 스타일시트를 import한 스타일시트의 인코딩입니다. [css-syntax-3]
2.3. CSS 스타일시트의 Content-Type
가져온 스타일시트의 처리는 연결된 리소스의 실제 타입에 따라 달라집니다:
-
리소스에 Content-Type 메타데이터가 없는 경우, 타입은
text/css
로 처리됩니다. -
호스트 문서가 쿼크 모드(quirks mode)인 경우, 그리고 호스트 문서의 origin이 연결된 리소스 응답(response) URL의 origin과 동일(origin)인 경우, 타입은
text/css
로 처리됩니다. -
그 외의 경우, 타입은 Content-Type 메타데이터로부터 결정됩니다.
연결된 리소스의 타입이 text/css
인 경우,
반드시 CSS 스타일시트로 해석되어야 합니다.
그렇지 않으면 네트워크 오류로 해석되어야 합니다.
3. 축약 속성
일부 속성은 축약 속성입니다. 즉, 하나의 속성으로 여러 속성의 값을 지정할 수 있습니다. 축약 속성은 자신의 모든 세부(롱핸드) 속성(sub-property)을 마치 그 자리에 모두 펼친 것처럼 설정합니다.
축약 속성 형식에서 값을 생략하면, 별도 정의가 없는 한, 누락된 각 세부 속성(sub-property)은 초기값이 할당됩니다.
예를 들어, background: green을 background-color: green 대신 작성하면, 배경색이 background-image로 이미지를 설정한 이전 선언을 덮어쓰게 됩니다.
h1{ font-weight : bold; font-size : 12 pt ; line-height : 14 pt ; font-family : Helvetica; font-variant : normal; font-style : normal; }
다음과 같이 축약할 수 있습니다
h1{ font : bold12 pt /14 pt Helvetica}
CSS에 더 많은 font 세부 속성(sub-property)이 추가되더라도, 축약 선언은 그 값들도 초기값으로 리셋합니다.
특정 경우, 축약 속성에 특별한 구문이나 키워드가 있어 세부 속성(sub-property)의 값과 직접적으로 대응되지 않을 수 있습니다. (이 경우 축약 속성이 값의 확장(expansion)을 명시적으로 정의합니다.)
다른 경우, 속성이 리셋 전용 세부 속성(reset-only sub-property)일 수 있습니다: 다른 세부 속성처럼, 축약 속성에서 명시되지 않으면 초기값으로 리셋되지만, 그 값을 직접 설정할 구문이 축약 속성에는 포함되어 있지 않을 수 있습니다. 예를 들어, border 축약 속성은 border-image를 초기값 none으로 리셋하지만, 다른 값으로 설정할 구문은 없습니다. [css-backgrounds-3]
축약 속성에 CSS 전역 키워드(CSS-wide keywords) [css-values-3]가 지정되면, 모든 세부 속성이 해당 키워드로 설정되며, 리셋 전용 세부 속성도 포함됩니다. (이 키워드들은 축약 속성 내에서 다른 값과 함께 선언할 수 없습니다.)
축약 속성에 !important를 선언하는 것은 모든 세부 속성에 !important를 선언하는 것과 동일합니다.
3.1. 속성 별칭(Aliasing)
속성은 일정 기간 지원된 후 이름이 변경되는 경우가 있습니다. 공급업체 접두사(vendor-prefixed) 속성이 표준화되는 경우가 그 예입니다. 호환성을 위해 기존 이름도 계속 지원해야 하지만, 새로운 이름이 우선됩니다. 이를 위해 CSS는 이전 구문을 새로운 구문으로 "별칭(alias)"하는 두 가지 방법을 정의합니다.
- 레거시 이름 별칭(legacy name alias)
-
기존 속성의 값 구문이 새 속성과 동일하다면,
두 이름은 대소문자 변환처럼 파싱 시 별칭 처리됩니다:
파싱 시 기존 속성은 새 속성으로 변환됩니다.
이 변환은 CSSOM에서도 적용되며,
문자열 인자와 속성 접근자 모두에 해당합니다:
기존 속성 이름으로 요청하면
투명하게 새 속성 이름에 전달됩니다.
예를 들어, old-name이 레거시 이름 별칭이라면,
getComputedStyle
은( el). oldNamenewName
속성의 계산된 스타일을 반환하며,el
는 new-name 속성에. style. setPropertyValue( "old-name" , "value" )
를 설정합니다."value" - 레거시 축약(legacy shorthand)
-
기존 속성이 새 속성과 구문이 다르면,
두 이름은 축약 속성
메커니즘으로 별칭 처리됩니다.
이러한 축약은 레거시 축약으로
정의되며,
사용은 폐기(deprecated)되었습니다.
그 외에는 일반 축약과 동일하게 동작하지만,
CSSOM은 선언을 직렬화할 때
이를 사용하지 않습니다. [CSSOM]
예를 들어, page-break-* 속성들은 레거시 축약이며, break-* 속성의 별칭입니다 (참고: CSS Fragmentation 3 § 3.4 Page Break Aliases: the page-break-before, page-break-after, and page-break-inside properties).
page-break-before: always를 설정하면 파싱 시 break-before: page로 확장됩니다. 마치 다른 축약 속성처럼 동작합니다. 마찬가지로 break-before: page가 설정된 경우,
getComputedStyle
호출 시( el). pageBreakBefore
가 반환됩니다. 하지만 스타일 블록을 직렬화할 때 (참고: CSSOM 1 § 6.7.2 Serializing CSS Values), page-break-before 속성은 절대 직렬화 대상 축약으로 선택되지 않으며, 원래 속성 또는 break-before가 지정되었는지와 무관합니다; 대신 break-before가 항상 선택됩니다."always"
3.2. 모든 속성 리셋: all 속성
이름(Name): | all |
---|---|
값(Value): | initial | inherit | unset | revert | revert-layer |
초기값(Initial): | 각 속성별 참조 |
적용 대상(Applies to): | 각 속성별 참조 |
상속됨(Inherited): | 각 속성별 참조 |
퍼센트(Percentages): | 각 속성별 참조 |
계산값(Computed value): | 각 속성별 참조 |
애니메이션 타입(Animation type): | 각 속성별 참조 |
정규 순서(Canonical order): | 문법 기준(per grammar) |
all 속성은 축약 속성으로, 모든 CSS 속성을 리셋합니다. 단, direction과 unicode-bidi는 제외됩니다. 이 속성은 CSS 전역 키워드(CSS-wide keywords)만 허용합니다. 사용자 정의 속성(custom properties)은 리셋하지 않습니다. [css-variables-1]
참고: 제외된 CSS 속성 direction과 unicode-bidi는 실제로 마크업 수준(feature)이며,
작성자의 스타일 시트에서 설정하면 안 됩니다.
(이들은 CSS 속성으로 존재하지만, UA가 지원하지 않는 문서 언어를 스타일링하기 위함입니다.)
작성자는 HTML의 dir
속성 등 적절한 마크업을 사용해야 합니다. [css-writing-modes-3]
이는 페이지에 포함된 "위젯"의 루트 요소 등에 유용할 수 있으며, 바깥 페이지의 스타일을 상속받고 싶지 않은 경우에 사용합니다. 다만 해당 요소에 적용된 "기본" 스타일 (예: display: block 등 블록 요소에 UA 스타일시트에서 적용된 것) 역시 모두 제거됨에 유의해야 합니다.
4. 값 처리
사용자 에이전트가 문서를 파싱하고 문서 트리를 구성한 후, 트리 내의 모든 요소, 그리고 이에 대응되는 포맷 구조의 모든 박스에 대상 미디어 타입에 적용되는 모든 속성에 값을 할당해야 합니다.
주어진 요소 또는 박스의 CSS 속성의 최종 값은 여러 단계의 계산 결과입니다:
- 먼저, 각 요소의 각 속성에 적용된 선언값(declared values)을 모두 수집합니다. 요소에는 0개 또는 여러 개의 선언값이 적용될 수 있습니다.
- 계단식(cascading)을 통해 계단식 값(cascaded value)이 결정됩니다. 각 속성, 각 요소별로 최대 1개의 계단식 값이 존재합니다.
- 기본값 처리(defaulting)를 통해 지정 값(specified value)이 결정됩니다. 모든 요소는 각 속성별로 정확히 하나의 지정 값을 가집니다.
- 값 의존성 해결을 통해 계산 값(computed value)이 결정됩니다. 모든 요소는 각 속성별로 정확히 하나의 계산 값을 가집니다.
- 문서 포맷팅을 통해 사용 값(used value)이 결정됩니다. 해당 속성이 요소에 적용되는 경우에만 사용 값이 존재합니다.
- 마지막으로, 사용 값이 표시 환경의 제약에 따라 실제 값(actual value)으로 변환됩니다. 사용 값과 같이, 특정 속성이 요소에 대해 실제 값을 가질 수도 있고, 그렇지 않을 수도 있습니다.
연결되지
않은(connected) 요소 또는 문서의 평탄화(flattened) 요소
트리에 속하지 않는 요소는
CSS 값 처리에 참여하지 않으며,
선언값, 계단식 값, 지정 값, 계산 값, 사용 값, 실제 값을 가지지 않습니다.
(예를 들어 style
속성으로 스타일 선언이 할당된 경우에도 마찬가지입니다.)
4.1. 선언값(Declared Values)
각 속성 선언은 요소에 적용될 때 해당 속성에 대한 선언값(declared value)을 제공합니다. 자세한 내용은 선언 필터링을 참고하세요.
이 값들은 계단식 처리(cascade)로 단일 "우승 값(winning value)"을 선택하는 과정에서 처리됩니다.
4.1.1. 값 별칭(Value Aliasing)
일부 속성 값에는 레거시 값 별칭(legacy value aliases)이 있습니다: 파싱 시, 레거시 구문이 새 구문으로 변환되어 파싱된 입력과 다른 선언값이 생성됩니다. 이러한 별칭은 대개 레거시 호환성 요구를 처리하기 위해 사용되며, 공급업체 접두사(vendor-prefixed) 값을 표준 값으로 변환하는 데 활용됩니다.
4.2. 계단식 값(Cascaded Values)
계단식 값(cascaded value)은 계단식 처리의 결과입니다: 계단식에서 "우승"한 선언값을 나타냅니다. (계단식 출력(output of the cascade)에서 가장 먼저 정렬된 값) 계단식 출력이 빈 리스트라면, 계단식 값은 없습니다.
4.3. 지정 값(Specified Values)
지정 값(specified value)은 스타일시트 작성자가 해당 요소에 의도한 주어진 속성의 값입니다. 계단식 값을 기본값 처리(defaulting) 과정에 넣어 모든 요소의 모든 속성에 지정 값이 존재하도록 보장합니다.
대부분의 경우 지정 값은 계단식 값입니다. 단, 계단식 값이 전혀 없으면 지정 값이 기본값 처리로 결정됩니다. CSS 전역 키워드가 계단식 값이 되는 경우에는 해당 키워드에 따라 지정 값이 설정됩니다. 자세한 내용은 § 7.3 명시적 기본값 처리를 참고하세요.
4.4. 계산 값(Computed Values)
계산 값(computed value)은 지정 값을 속성 정의 테이블의 "계산 값" 행에 따라 해결한 결과로, 일반적으로 상속을 준비하기 위해 절대값화(absolutizing)됩니다. 상속(inheritance)을 위해서입니다.
참고: 계산 값은 상속 시 부모에서 자식으로 전달되는 값입니다.
역사적 이유로,
getComputedStyle()
함수가 반환하는 값과는 다를 수 있습니다.
이 함수는 때때로 사용 값을 반환하기 때문입니다. [CSSOM]
또한 계산 값은 추상 데이터 표현체로,
정의는 데이터 표현을 반영하며,
데이터 직렬화 방식과는 다릅니다.
예를 들어, 직렬화 규칙에서는 파싱 시 암시되는 특정 값을 생략할 수 있지만,
이런 값도 계산 값에 포함됩니다.
- 상대 단위(em, ex, vh, vw)는 적절한 기준 크기와 곱하여 절대값으로 만들어야 합니다.
- 특정 키워드(예: smaller, bolder)는 정의에 따라 대체해야 합니다.
- 일부 속성의 퍼센트 값은 기준값(속성에 정의됨)과 곱하여 절대값으로 만들어야 합니다.
- 유효한 상대 URL은 반드시 절대 URL로 변환되어야 합니다.
아래 표의 예시(f), (g), (h)를 참고하세요.
참고: 일반적으로 계산 값은 지정 값을 문서 레이아웃이나 비용이 크거나 병렬화가 어려운 작업(네트워크 요청 해결, 부모 외의 값 참조 등)을 하지 않고 가능한 한 많이 해결합니다.
계산 값은 속성이 적용되지 않더라도 존재합니다. 단, 일부 속성은 속성이 요소에 적용되는지 여부에 따라 계산 값 결정 방식을 변경할 수 있습니다.
4.5. 사용 값(Used Values)
사용 값(used value)은 계산 값에 남은 계산을 완료하여 문서 포맷팅에 사용되는 절대 이론값으로 만든 결과입니다.
예를 들어, width: auto 선언은 요소의 조상 레이아웃을 알지 못하면 길이로 해결할 수 없으므로, 계산 값은 auto이고, 사용 값은 100px처럼 절대 길이입니다. [CSS2]
또 다른 예로,
<div>
는 계산된 break-before 값이 auto일 수 있지만,
첫 자식에서 전파되어 사용 값 break-before가 page가 될 수 있습니다. [css-break-3]
속성이 해당 요소나 박스 타입에 적용되지 않으면 해당 속성에 대한 사용 값이 없습니다.
예를 들어, flex 속성은 사용 값이 플렉스 아이템(flex items)이 아닌 요소에는 존재하지 않습니다.
4.5.1. 적용 가능한 속성(Applicable Properties)
속성이 적용(apply to)되지 않는 요소나 박스 타입(“Applies to” 행에 명시됨)에는, 해당 타입의 박스나 요소에 직접적으로 효과를 주지 않습니다.
참고: 적용되지 않는 속성도 간접적으로 포맷팅에 영향을 줄 수 있습니다. 계산 값이 적용되는 다른 속성의 계산에 영향줄 수 있고, 계산 값은 항상 존재하므로 하위 노드로 상속되어 그들에게 영향을 줄 수 있습니다.
p
요소에 설정하면
(기본적으로 display:
block)
효과를 주지만,
text-transform은 인라인 박스에만 적용됩니다.
속성이 상속되어 단락의 익명 루트 인라인 박스(root inline box)에 적용되어
그 안의 텍스트에 영향을 미치기 때문입니다.
참고: “모든 요소”에 적용된다고 정의된 속성은 모든 요소와 display 타입에 적용되지만, 모든 의사 요소(pseudo-element)에 반드시 적용되는 것은 아닙니다. 의사 요소는 종종 자체 렌더링 모델이나 다른 제한이 있기 때문입니다. 단, ::before와 ::after 의사 요소는 일반 요소와 거의 동일하게 박스를 생성하므로 “모든 요소”에 적용되는 속성을 모두 허용하도록 정의됩니다. 자세한 정보는 [CSS-PSEUDO-4]를 참고하세요. 의사 요소 관련 내용입니다.
4.6. 실제 값(Actual Values)
사용 값은 원칙적으로 사용할 준비가 된 값이지만, 사용자 에이전트가 특정 환경에서 해당 값을 사용할 수 없을 수도 있습니다. 예를 들어, 사용자 에이전트가 테두리를 정수 픽셀 너비로만 렌더링할 수 있다면 사용 너비를 근사해야 합니다. 또한, 폰트 크기는 폰트의 가용성이나 font-size-adjust 값에 따라 조정될 수도 있습니다. 실제 값(actual value)은 이러한 조정이 이루어진 후의 사용 값입니다.
참고: 요소의 실제 값을 조사하면 문서 레이아웃 방식에 대해 많은 정보를 얻을 수 있습니다. 하지만 모든 정보가 실제 값에 기록되는 것은 아닙니다. 예를 들어, page-break-after의 실제 값은 해당 요소 뒤에 페이지 분할이 있는지 여부를 반영하지 않습니다. 마찬가지로 orphans의 실제 값도 해당 요소에 고아 줄이 몇 줄 있는지를 반영하지 않습니다. 아래 표의 예시(j), (k)를 참고하세요.
4.7. 예시(Examples)
속성(Property) | 우승 선언(Winning declaration) | 계단식 값(Cascaded value) | 지정 값(Specified value) | 계산 값(Computed value) | 사용 값(Used value) | 실제 값(Actual value) | |
---|---|---|---|---|---|---|---|
(a) | text-align | text-align: left
| left | left | left | left | left |
(b) | border-top-width, border-right-width, border-bottom-width, border-left-width | border-width: inherit
| inherit | 4.2px | 4.2px | 4.2px | 4px |
(c) | width | (없음) | (없음) | auto (초기값) | auto | 120px | 120px |
(d) | list-style-position | list-style-position: inherit
| inherit | inside | inside | inside | inside |
(e) | list-style-position | list-style-position: initial
| initial | outside (초기값) | outside | outside | outside |
(f) | font-size | font-size: 1.2em
| 1.2em | 1.2em | 14.1px | 14.1px | 14px |
(g) | width | width: 80%
| 80% | 80% | 80% | 354.2px | 354px |
(h) | width | width: auto
| auto | auto | auto | 134px | 134px |
(i) | height | height: auto
| auto | auto | auto | 176px | 176px |
(j) | page-break-after | (없음) | (없음) | auto (초기값) | auto | auto | auto |
(k) | orphans | orphans: 3
| 3 | 3 | 3 | 3 | 3 |
4.8. 조각(fragment)별 값 처리
일부 CSS 기능은 조각(fragment) 단위로 값 처리에 영향을 줄 수 있습니다. 예시로 CSS Pseudo-Elements 4 § 2.1.3 상속과 ::first-line 의사 요소를 참고하세요. 여기서는 ::first-line 의사 요소 내 조각의 상속이 달라집니다. 이런 경우, 개별 조각(fragment)이 서로 다른 지정 값을 가지게 되면, 다른 속성의 계산 값에 기반해 해결되는 값(예: currentcolor 또는 em 단위)은 각 박스 조각(box fragment)별로 해결됩니다. 이후의 값 처리 과정은 각 조각에서 일반적으로 진행됩니다.
각 박스(box)별로 단일
값만 가정하는 API는(박스 조각별이 아니라)
트리-준수(tree-abiding)가 아닌
의사 요소(pseudo-elements)의 효과를 무시해야 합니다.
(예를 들어, ::first-line 스타일은
getComputedStyle()
으로
반환되는 값에는 영향을 주지 않습니다.)
< div >< span > First line< br /> Second line</ span ></ div > < div >< span > First line</ span ></ div > < div > First line< br >< span > Second line</ span ></ div > < style > div { color : blue ; } div :: first-line { color : yellow ; } span { border : thin solid currentcolor ; } </ style >
각
div
에서,
“First line” 텍스트는 노란색이고 “Second line” 텍스트는 파란색입니다.
각 줄을 감싸는
span
의
각 조각의 테두리도 해당 색상과 일치합니다.
하지만 모든 span에 대해 getComputedStyle()
을
호출하면,
border-color는 모두 "blue"
로 반환됩니다.
이는 ::first-line 의사 요소의 효과가
분할(fragment)을 인식하지 못하는 API에서는 무시되기 때문입니다.
5. 선언 필터링(Filtering)
선언값을 찾으려면, 구현체는 먼저 각 요소에 적용되는 모든 선언을 식별해야 합니다. 선언이 요소에 적용되는 조건은 다음과 같습니다:
- 해당 선언이 현재 문서에 적용되는 스타일시트에 속해 있을 것.
- 조건부 규칙이 거짓 조건인 경우 [CSS-CONDITIONAL-3]로 한정되지 않을 것.
- 해당 선언이 요소와 매칭되는 선택자를 가진 스타일 규칙에 속할 것. [SELECT] (필요하다면 스코핑(scoping)을 고려)
- 구문적으로 유효할 것: 선언의 속성이 알려진 속성명이고, 선언의 값이 해당 속성의 구문과 일치할 것.
적용되는 선언들의 값은, 각 요소의 각 속성별로 선언값의 리스트를 형성합니다. 그 다음 섹션인 계단식(cascade)에서 이 리스트들의 우선순위가 결정됩니다.
6. 계단식(Cascading)
계단식(cascade)은 주어진 요소의 주어진 속성에 대해 선언값의 무순서 리스트를 받아, 아래에서 결정된 선언의 우선순위에 따라 정렬하고, 단일 계단식 값을 출력합니다.
6.1. 계단식 정렬 순서(Cascade Sorting Order)
계단식은 아래의 기준에 따라 선언을 정렬합니다. 우선순위는 내림차순입니다:
- 출처(origin)와 중요도(importance)
-
선언의 출처(origin)는
어디서 왔는지에 따라 결정되고,
중요도(importance)는
!important로 선언되었는지에 따라 결정됩니다 (아래 참고).
각 출처(origin)의 우선순위는 다음과 같습니다 (내림차순):
- 트랜지션 선언 [css-transitions-1]
- 중요(Important) UA 선언
- 중요(Important) 사용자(User) 선언
- 중요(Important) 작성자(Author) 선언
- 애니메이션 선언 [css-animations-1]
- 일반(Normal) 작성자(Author) 선언
- 일반(Normal) 사용자(User) 선언
- 일반(Normal) UA 선언
이 리스트에서 앞쪽 출처(origin)의 선언이 뒤쪽 출처(origin)의 선언보다 우선합니다.
- 컨텍스트(Context)
-
문서 언어는 서로 다른 캡슐화 컨텍스트(encapsulation contexts)에서 온 선언들을
혼합(blending)할 수 있습니다. 예를 들어 트리 컨텍스트(tree
contexts)와 같은,
섀도 트리(shadow trees)에서의 중첩 트리 컨텍스트가 있습니다. [DOM]
서로 다른 캡슐화 컨텍스트에서 나온 두 선언을 비교할 때, 일반(Normal) 규칙에서는 바깥 컨텍스트의 선언이 우선, 중요(Important) 규칙에서는 안쪽 컨텍스트의 선언이 우선합니다. 이때 [DOM] 트리 컨텍스트는 섀도-포함 트리 순서(shadow-including tree order)로 중첩된 것으로 간주합니다.
참고: 이는 일반(Normal) 선언이 캡슐화 컨텍스트에 속해 있으면 바깥 컨텍스트에서 쉽게 덮어쓸 수 있는 기본값 역할을 하게 되고, 중요(Important) 선언이 캡슐화 컨텍스트에 속해 있으면 바깥 컨텍스트에서 덮어쓸 수 없는 강제 조건이 됩니다.
- 요소-부착 스타일(Element-Attached Styles)
-
일반(Normal)과 중요(Important) 선언별로,
요소에 직접 부착된 선언(예: style
속성의 내용)
선택자에 의해 간접적으로 매핑된 스타일 규칙보다 같은 중요도 내에서 우선합니다.
자세한 내용은 [css-style-attr] 참고.
참고: 비-CSS 프리젠테이션 힌트(마크업 등)는 별도로 처리됩니다. § 6.5 비-CSS 프리젠테이션 힌트의 우선순위 참고.
- 레이어(Layers)
-
각 출처(origin)와 컨텍스트(context) 내 선언들은
명시적으로 계단식 레이어(cascade
layer)에 할당될 수 있습니다.
이 단계에서,
명시적 레이어에 할당되지 않은 선언은 암시적 최종 레이어에 추가됩니다.
계단식 레이어(및 선언)는 등장 순서대로 정렬됩니다. 서로 다른 레이어에 속한 선언을 비교할 때, 일반(Normal) 규칙에서는 마지막 레이어의 선언이 우선, 중요(Important) 규칙에서는 첫 번째 레이어의 선언이 우선합니다.
참고: 이는 일반(Normal)과 중요(Important) 출처(origin)에서 사용하는 레이어링 논리와 동일합니다. !important 플래그가 두 경우 모두 "덮어쓰기" 역할을 유지하도록 하는 것입니다.
- 특이성(Specificity)
- Selectors 모듈 [SELECT]에서 선택자의 특이성 계산 방법을 설명합니다. 각 선언은 자신이 속한 스타일 규칙과 같은 특이성을 가집니다. 특이성이 가장 높은 선언이 우승합니다.
- 등장 순서(Order of Appearance)
-
문서 순서상 마지막 선언이 우승합니다.
이때:
- 스타일시트는 최종 CSS 스타일시트 순서대로 정렬됩니다.
- import된 스타일시트의 선언은 해당 스타일시트가 @import 규칙 위치에 대체된 것처럼 정렬됩니다.
- 원본 문서에서 독립적으로 링크된 스타일시트의 선언은 호스트 문서 언어가 결정하는 링크 순서대로 연결된 것처럼 취급합니다.
- style 속성의 선언은 해당 요소의 문서 순서대로 정렬되며, 모든 스타일시트 뒤에 위치합니다.
계단식의 출력(output of the cascade)은 각 요소의 각 속성별로 선언값의 (비어 있을 수도 있는) 정렬된 리스트입니다.
6.2. 계단식 출처(Cascading Origins)
각 스타일 규칙은 계단식 출처(cascade origin)를 가지며, 이것이 계단식에 들어가는 위치를 결정합니다. CSS는 세 가지 주요 출처(origin)를 정의합니다:
- 작성자 출처(Author Origin)
- 작성자는 소스 문서에 대해 문서 언어의 규칙에 따라 스타일시트를 지정합니다. 예를 들어 HTML에서는 스타일시트를 문서 내에 포함하거나 외부에서 링크할 수 있습니다.
- 사용자 출처(User Origin)
- 사용자는 특정 문서에 대해 스타일 정보를 지정할 수 있습니다. 예를 들어 사용자가 스타일시트가 포함된 파일을 지정하거나, 사용자 에이전트가 사용자 스타일시트를 생성하는 인터페이스를 제공할 수 있습니다 (혹은 그런 것처럼 동작할 수 있습니다).
- UA 출처(User-Agent Origin)
- 적합한 사용자 에이전트는 기본 스타일시트를 적용해야 하며 (혹은 그런 것처럼 동작해야 함). UA 기본 스타일시트는 문서 언어의 요소를 일반적인 표현 기대치에 맞게 표현해야 합니다 (예: 시각적 브라우저에서 HTML의 EM 요소는 이탤릭 폰트로 표시됨). 예시로 HTML 사용자 에이전트 스타일시트 참고. [HTML]
CSS 확장에서는 다음과 같은 추가 출처(origin)를 정의합니다:
- 애니메이션 출처(Animation Origin)
- CSS 애니메이션 [css-animations-1] 실행 시 효과를 나타내는 “가상” 규칙을 생성합니다.
- 트랜지션 출처(Transition Origin)
- CSS 애니메이션과 마찬가지로, CSS 트랜지션 [css-transitions-1]도 실행 시 효과를 나타내는 “가상” 규칙을 생성합니다.
6.3. 중요 선언: !important 애노테이션
CSS는 작성자와 사용자 스타일시트 사이의 권한 균형을 만들고자 합니다. 기본적으로 작성자 스타일시트 규칙이 사용자 스타일시트 규칙을 덮어쓰고, 사용자 스타일시트 규칙이 UA 기본 스타일시트 규칙을 덮어씁니다. 이를 균형 있게 하기 위해 중요(important) 마크를 선언할 수 있으며, 계단식에서 가중치가 높아져 우선순서가 반전됩니다.
선언이 중요(important)로 간주되려면 [css-syntax-3] 정의대로 !important 애노테이션이 있어야 합니다. 즉, 값의 마지막 두(공백/주석 제외) 토큰이 구분자 !와 식별자 important여야 합니다. 이외의 선언은 일반(normal)(비-중요) 선언입니다.
중요(important) 선언은 일반(normal) 선언보다 우선합니다. 작성자와 사용자 스타일시트 모두 중요 선언을 포함할 수 있으며, 사용자 출처(user-origin) 중요 선언이 작성자 출처(author-origin) 중요 선언을 덮어씁니다. 이 CSS 기능은 접근성을 높여, 특별한 요구(큰 폰트, 색상 조합 등)가 있는 사용자가 표현을 제어할 수 있게 합니다.
중요(important) 선언은 모든 출처에서 애니메이션보다 우선합니다. 이를 통해 작성자가 애니메이션 값을 중요한 상황에서 덮어쓸 수 있습니다. (애니메이션 값은 일반적으로 다른 모든 규칙을 덮어씁니다.) [css-animations-1]
UA 스타일시트에도 중요 선언이 포함될 수 있습니다. 이들은 모든 작성자, 사용자 선언을 덮어씁니다.
/* 사용자의 스타일시트 */ p{ text-indent : 1 em !important} p{ font-style : italic !important} p{ font-size : 18 pt } /* 작성자의 스타일시트 */ p{ text-indent : 1.5 em !important} p{ font : normal12 pt sans-serif !important} p{ font-size : 24 pt }
속성(Property) | 우승 값(Winning value) |
---|---|
text-indent | 1em |
font-style | italic |
font-size | 12pt |
font-family | sans-serif |
6.4. 계단식 레이어(Cascade Layers)
계단식 출처가 사용자와 작성자 스타일 간의 권한 균형을 제공하는 것처럼, 계단식 레이어는 단일 출처(origin) 내에서 스타일 우선순위를 구조적으로 조직하고 균형 잡는 방법을 제공합니다. 하나의 계단식 레이어 내 규칙들은 서로 계단식되며, 레이어 밖의 스타일 규칙과는 섞이지 않습니다.
작성자는 레이어를 만들어 요소의 기본값, 서드파티 라이브러리, 테마, 컴포넌트, 오버라이드 등 다양한 스타일 관심사를 표현할 수 있고, 각 레이어 내에서 선택자나 특이성(specificity)을 변경하지 않고, 레이어 간 충돌 해결에 소스 순서에 의존하지 않으면서, 계단식 레이어의 순서를 명시적으로 재정렬할 수 있습니다.
audio{ /* 특이성 0,0,1 - 암시적(최종) 레이어 */ display: flex; } @layer reset{ audio[ controls] { /* 특이성 0,1,1 - 명시적 "reset" 레이어 */ display: block; } }
audio
요소의 레이어 없는 선언이
audio[controls]
의 명시적 레이어 선언보다 우선합니다 — 특이성이 더 낮고, 소스 순서상 먼저 나와도 마찬가지입니다.
이름을 정의하는 at-규칙 (@keyframes 또는 @font-face 등)이 계단식 레이어 안에 정의되어 있으면 이름 충돌을 해결할 때 레이어 순서를 사용합니다.
/* 레이어 순서를 명시적으로 설정하여 "override" 레이어가 우선 */ @layer framework, override; @layer override{ @keyframes slide-left{ from{ translate : 0 ; } to{ translate : -100 % 0 ; } } } @layer framework{ @keyframes slide-left{ from{ margin-left : 0 ; } to{ margin-left : -100 % ; } } } .sidebar{ animation : slide-left300 ms ; }
이 경우 override 레이어가 framework 레이어보다 높은 계단식 우선순위를 가지므로
slide-left
애니메이션은 translate
속성으로 동작합니다(margin-left
대신).
6.4.1. 계단식 레이어 선언
계단식 레이어는 다음 방법으로 선언할 수 있습니다:
-
@import 규칙에서 layer 키워드 또는 layer() 함수를 사용하여, 가져온 파일의 내용을 해당 레이어로 할당
-
@layer 블록 at-규칙을 사용하여, 자식 스타일 규칙을 해당 레이어로 할당
-
@layer 문장 at-규칙을 사용하여, 규칙을 할당하지 않고 이름만 선언
link 또는 style 요소를 계단식 레이어에 할당하는 속성 제공? [Issue #w3c/csswg-drafts#5853]
6.4.2. 레이어 이름과 중첩(Layer Naming and Nesting)
계단식 레이어는 레이어 이름(layer name)을 가지며, 이는 각 레이어 중첩 단계(level)를 나타내는 순서 있는 리스트입니다. 각 구간(segment)은 CSS 식별자로 명명되거나 익명일 수 있습니다. (따라서 한 레이어가 다른 레이어에 중첩되면, 이름이 이어 붙여집니다.) 한 레이어가 다른 레이어에 중첩되는 경우는, 다른 레이어의 범위 내에서 선언되는 경우입니다. 예: @layer 규칙이 또 다른 @layer 안에 있을 때, 계층화된 @import가 계층화된 import 안에 있을 때, 또는 @layer 규칙이 계층화된 import 안에 있을 때 등입니다.
레이어 이름이 동일한 순서로 동일한 구간을 포함하면 동일한 계단식 레이어를 나타냅니다. 단, 익명 구간은 각 발생마다 고유한 식별자를 가집니다. 중첩(nesting)으로 인해 여러 레이어가 동일한 익명 구간을 공유할 수 있습니다.
headings.css
와 links.css
의 내용이 audio[controls]
규칙과 동일 레이어에서 계단식됩니다:
@import url ( headings.css ) layer ( default); @import url ( links.css ) layer ( default); @layer default{ audio[ controls] { display : block; } }
@layer base{ p{ max-width : 70 ch ; } } @layer framework{ @layer base{ p{ margin-block : 0.75 em ; } } @layer theme{ p{ color : #222; } } }
결과 레이어는 다음과 같이 트리로 표현할 수 있습니다:
-
base
-
framework
-
base
-
theme
-
또는 중첩 식별자를 포함한 평면 리스트로 표현할 수도 있습니다:
-
base
-
framework.base
-
framework.theme
구문적으로, 명시적 레이어 이름은 @layer와 @import 규칙의 <layer-name>으로 표현됩니다. 이는 공백 없이 점(.)으로 구분된 <ident> 토큰의 리스트입니다:
<layer-name> = <ident> [ '.' <ident> ]*
CSS 전역 키워드(CSS-wide keywords)는 향후 사용을 위해 예약되어 있으므로 <ident>로 사용하면 해당 규칙이 파싱 시 무효가 됩니다. 여러 식별자를 점(.)으로 이어 붙이면, 해당 레이어들이 순서대로 중첩된 것을 의미합니다.
@layer framework{ @layer default{ p{ margin-block : 0.75 em ; } } @layer theme{ p{ color : #222; } } } @layer framework.theme{ /* 이 스타일은 framework 레이어 내 theme 레이어에 추가됨 */ blockquote{ color : rebeccapurple; } }
참고: 중첩된 레이어는 부모 레이어 바깥의 레이어를 참조할 수 없습니다.
6.4.2.1. 익명 레이어(Anonymous Layers)
@layer 규칙이 <layer-name>을 생략하거나, @import 규칙에서 layer 키워드만 사용해 <layer-name>을 제공하지 않을 때, 레이어 이름에 고유한 익명 구간이 추가됩니다; 따라서 바깥에서 참조할 수 없습니다.
-
여러 익명 레이어 규칙은 각각의 스타일을 별도의 레이어에 배치합니다. 각 발생마다 서로 다른 익명 레이어 이름을 참조합니다.
@layer { /* layer 1 */ } @layer { /* layer 2 */ } -
하나의 익명 레이어 내에서는, 같은 이름의 자식 레이어가 동일한 계단식 레이어를 참조합니다. 익명 부모 레이어를 공유하기 때문입니다.
@layer { @layer foo{ /* layer 1 */ } @layer foo{ /* also layer 1 */ } } -
별도의 익명 레이어 내에서는, 같은 이름의 자식 레이어가 서로 다른 계단식 레이어를 참조합니다. 익명 부모 레이어가 다르기 때문입니다.
@layer { @layer foo{ /* layer 1 */ } } @layer { @layer foo{ /* layer 2 */ } }
이는 단순히 편의를 위한 축약일 수도 있고, 팀에서 조직 규칙을 강제하기 위한 용도로(해당 레이어 내 모든 코드는 한 곳에서 정의해야 함), 또는 라이브러리가 내부 "비공개" 레이어 집합을 합치고 숨기고 싶을 때(작성자 조작에서 숨김) 사용할 수도 있습니다:
/* bootstrap-base.css */ /* 각 서브 파일마다 익명 래퍼 레이어 */ @import url ( base-forms.css ) layer; @import url ( base-links.css ) layer; @import url ( base-headings.css ) layer;
/* bootstrap.css */ /* 내부 이름은 접근 불가, "base"로 흡수됨 */ @import url ( bootstrap-base.css ) layer ( base);
/* author.css */ /* 작성자는 bootstrap.base 레이어에는 접근 가능하지만 익명 레이어 내부에는 접근 불가 */ @import url ( bootstrap.css ) layer ( bootstrap); /* bootstrap 레이어에 추가 스타일을 넣을 수 있음: */ @layer bootstrap{ ...}
6.4.3. 레이어 순서(Layer Ordering)
계단식 레이어는 처음 선언된 순서대로 정렬되며, 중첩된 레이어는 부모 레이어 내에 그룹화되고 모든 레이어 없는(unlayered) 규칙보다 먼저 그룹화됩니다.
/* 레이어 없는 스타일은 레이어 순서상 마지막에 위치 */ h1{ color : darkslateblue; } @layer reset.type{ strong{ font-weight : bold; } } @layer framework{ .title{ font-weight : 100 ; } @layer theme{ h1, h2{ color : maroon; } } } @layer reset{ [ hidden] { display : none; } }
바깥쪽(outer) 레이어들이 먼저 정렬되며, 레이어 없는 스타일 규칙은 암시적 바깥 레이어에 추가되어 명시적 레이어보다 더 높은 우선순위를 갖습니다(더 뒤에 나옴):
-
reset
-
framework
-
(암시적 바깥 레이어)
각 레이어 내에서는, 중첩된 레이어들이 등장 순서대로 정렬되고, 추가 중첩 없이 스타일 규칙이 명시적 중첩 레이어 뒤의 암시적 서브 레이어(sub-layer)에 추가됩니다:
-
reset.type
-
reset (암시적 서브 레이어)
-
framework.theme
-
framework (암시적 서브 레이어)
-
(암시적 바깥 레이어)
조건부 그룹 규칙(conditional group rule) 안에 정의된 레이어는 조건이 참이거나 해당 조건부 그룹 규칙이 문서 내 요소별로 다르게 평가될 수 있는 경우에만 레이어 순서에 기여합니다.
참고: 레이어 순서는 문서 전체에 대해 전역(global)이므로, 요소-민감(element-sensitive)한 조건부 그룹 규칙 내에서 정의된 레이어도 전역 레이어 순서 설정 시 반드시 포함되어야 합니다(조건과 무관하게). 문서에 대해 전역적인 조건(예: @media, @supports)에서는 해당 @layer 규칙을 조건부로 포함할 수 있습니다.
@media ( min-width:30 em ) { @layer layout{ .title{ font-size : x-large; } } } @media ( prefers-color-scheme: dark) { @layer theme{ .title{ color : white; } } } @layer theme, layout;
첫 번째 미디어 쿼리가 뷰포트 크기 조건에 맞으면, layout 레이어가 레이어 순서상 가장 먼저 옵니다. 컬러 스킴 조건이 맞거나 둘 다 아니면, theme이 가장 먼저 옵니다.
작성자가 이런 동작을 피하려면 미리 명시적으로 레이어 순서를 설정하고, 조건부 규칙 내에서 새 레이어를 정의하지 않으면 됩니다.
참고: 계단식 레이어는 해당 출처(origin)와 컨텍스트(context)에 범위가 한정되므로, light DOM의 레이어 순서는 shadow DOM의 동일 이름 레이어 순서에 영향을 주지 않습니다(반대도 마찬가지).
작성자가 레이어 없는 스타일을 명시적으로 레이어 순서에 배치할 수 있도록 허용? [Issue #6323]
6.4.4. 인라인 레이어 선언: @layer 규칙
@layer 규칙은 계단식 레이어를 선언하며, 스타일 규칙을 할당할 수 있습니다.
6.4.4.1. 인라인 스타일 할당: @layer 블록 at-규칙
@layer 블록 at-규칙(block at-rule)은 자식 스타일 규칙들을 특정 이름의 계단식 레이어에 할당합니다. 이 블록 레이어 할당 구문은 다음과 같습니다:
@layer <layer-name>? { <stylesheet> }
이런 @layer 블록 규칙은 조건이 참인 조건부 그룹 규칙 [CSS-CONDITIONAL-3]과 동일한 제한 및 처리 규칙을 가집니다.
@layer framework{ h1, h2{ color : maroon; background : white;} @media ( prefers-color-scheme: dark) { h1, h2{ color : red; background : black; } } }
참고: @layer 블록 at-규칙은 @import 규칙과 섞어서 사용할 수 없습니다.
6.4.4.2. 스타일 없이 선언: @layer 문장 at-규칙
@layer 규칙은 스타일 규칙을 할당하지 않고 레이어 이름만 제공하여 새로운 레이어를 정의하는 데에도 사용할 수 있습니다:
@layer <layer-name>#;
이런 빈 @layer 규칙은 @import 및 @namespace 규칙 앞(있다면 @charset 규칙 뒤에) 뿐만 아니라 @layer 블록 at-규칙이 허용되는 모든 위치에 사용할 수 있습니다.
참고: @layer 규칙은 @import와 @namespace 규칙 사이에는 허용되지 않습니다. @layer 규칙이 @import 또는 @namespace 규칙 뒤에 위치하면, 그 이후의 @import 또는 @namespace 규칙은 무시됩니다.
블록 구문과 달리, 이 구문에서는 여러 레이어 이름을 쉼표로 구분해 제공할 수 있으며, 지정된 순서대로 각각의 레이어를 선언합니다.
참고: 레이어 순서는 레이어 이름의 첫 등장으로 결정되기 때문에(아래 § 6.4.3 레이어 순서 참고), 이 규칙을 사용하면 페이지가 레이어 순서를 미리 선언할 수 있어, 스타일시트를 전체 읽지 않아도 순서를 알 수 있습니다. 또한 인라인 레이어를 import된 레이어와 섞어서 선언할 수 있는데, 이는 블록 구문에서는 불가능합니다.
theme.css
스타일 규칙이 이후 default 블록에 추가된 규칙보다 우선합니다.
레이어 순서가 이미 정해졌기 때문입니다:
@layer default, theme, components; @import url ( theme.css ) layer ( theme); @layer default{ audio[ controls] { display : block; } }
@import 규칙을 @layer 규칙들 사이에 배치하여, 순서를 정할 수도 있습니다. 아래 예시도 같은 결과가 됩니다:
@layer default; @import url ( theme.css ) layer ( theme); @layer components; @layer default{ audio[ controls] { display : block; } }
단, @import와 @namespace 규칙은 반드시 연속적으로 나와야 하며, 그 사이에 다른 규칙이 끼어 있으면 안 됩니다. 아래 예시는 잘못된 구문입니다:
@import url ( default.css ) layer ( default); @layer theme; @import url ( components.css ) layer ( components); @layer theme{ audio[ controls] { display : block; } }
6.5. 비-CSS 프리젠테이션 힌트의 우선순위
UA는 소스 문서의 마크업에서 프리젠테이션 힌트를 존중할 수 있습니다.
예를 들어 bgcolor
속성이나
s
요소 등입니다([HTML] 참고).
모든 문서 언어 기반 스타일링은 해당 CSS 규칙으로 변환되어
계단식에 UA-origin 또는 특별 작성자 프리젠테이션 힌트 출처(author presentational hint origin)로 들어가야
하며,
이는 일반 사용자 출처(user
origin)와
작성자 출처(author
origin) 사이에 위치합니다.
계단식(cascading) 시에는 작성자 프리젠테이션 힌트
출처가 독립적인 출처(origin)로 취급되지만,
revert
키워드 측면에서는 의 일부로 간주됩니다.
문서 언어는 해당 프리젠테이션 힌트가 계단식에 UA-origin 또는 작성자 출처(author-origin)로 들어가는지 정의할 수 있습니다. 만약 정의되어 있다면 UA는 해당 규정대로 동작해야 합니다. 예를 들어 [SVG11]은 프리젠테이션 속성을 로 매핑합니다.
참고: 계단식에 UA-origin 규칙으로 들어가는 프리젠테이션 힌트는, 작성자 출처 또는 사용자 출처 스타일로 덮어쓸 수 있습니다. 작성자 프리젠테이션 힌트 출처 규칙으로 들어가는 힌트는, 스타일로 덮어쓸 수 있지만, 중요(important)가 아닌 사용자 출처 스타일로는 덮어쓸 수 없습니다. 호스트 언어는 이런 점을 고려해 프리젠테이션 힌트의 출처를 선택해야 합니다.
7. 기본값 처리(Defaulting)
계단식(cascade)이 값을 반환하지 않으면, 지정 값을 다른 방식으로 찾아야 합니다. 상속 속성(inherited properties)은 부모 요소를 통해 상속(inheritance)으로 기본값을 가져오고, 그 외의 속성은 초기값(initial value)을 사용합니다. 작성자는 inherit 및 initial 키워드로 상속 또는 초기화를 명시적으로 요청할 수 있습니다.
7.1. 초기값(Initial Values)
각 속성은 초기값(initial value)을 가지며, 이는 속성 정의 테이블에 명시되어 있습니다. 속성이 상속 속성이 아니고, 계단식이 값을 반환하지 않으면, 해당 속성의 지정 값은 초기값입니다(initial value).
7.2. 상속(Inheritance)
상속(Inheritance)은 속성 값을 부모 요소에서 자식 요소로 전달합니다. 요소의 속성의 상속 값(inherited value)은 부모 요소의 해당 속성 계산 값(computed value)입니다. 루트 요소의 경우 부모 요소가 없으므로, 상속 값은 해당 속성의 초기값입니다.
[DOM] 트리(섀도 포함)에서는,
상속은 평탄화(flattened) 요소 트리에서 동작합니다. 이 뜻은, 슬롯에 할당된 요소는
slot
에서
상속받으며,
직접적인 light tree 부모에서는 상속받지 않습니다. 의사
요소(pseudo-elements)는 각 의사 요소에 명시된 가상의 태그 시퀀스대로 상속받습니다. [CSS-PSEUDO-4]
일부 속성은 상속 속성(inherited properties)입니다. 이는 속성 정의 테이블에 명시되어 있습니다. 즉, 계단식이 값을 반환하지 않으면, 상속(inheritance)으로 값이 결정됩니다.
속성은 명시적으로 상속받을 수도 있습니다. inherit 키워드 참고.
참고: 상속은 문서 트리를 따르며 익명 박스에서 가로채지 않으며, 박스 트리의 조작 등으로 영향을 받지 않습니다.
7.3. 명시적 기본값 처리(Explicit Defaulting)
아래에 여러 CSS 전역 속성 값이 정의되어 있습니다; 속성에 이 값을 명시적으로 선언하면 특정 기본값 처리 동작을 지정하는 것입니다. CSS 값 및 단위 [css-values-3]에 명시된 대로, 모든 CSS 속성은 이 값들을 허용할 수 있습니다.
7.3.1. 속성 리셋: initial 키워드
속성의 계단식 값이 initial 키워드라면, 해당 속성의 지정 값은 초기값입니다.
7.3.2. 명시적 상속: inherit 키워드
속성의 계단식 값이 inherit 키워드라면, 해당 속성의 지정 값과 계산 값은 상속 값입니다.
7.3.3. 모든 선언 삭제: unset 키워드
속성의 계단식 값이 unset 키워드라면, 상속 속성일 경우 inherit로 처리하고, 상속 속성이 아니면 initial로 처리합니다. 이 키워드는 앞서 계단식에서 발생한 모든 선언값을 지우며, 속성에 맞게 올바르게 상속하거나(상속 속성일 경우), 그렇지 않으면 초기화합니다 (또는 축약 속성(longhands) 전체에 대해).
7.3.4. 계단식 출처 롤백: revert 키워드
속성의 계단식 값이 revert 키워드라면, 그 선언이 속한 계단식 출처에 따라 동작이 달라집니다:
- UA 출처(user-agent origin)
- unset과 동일하게 처리합니다.
- 사용자 출처(user origin)
- 계단식 값을 UA 레벨로 롤백합니다. 즉, 해당 요소의 해당 속성에 대해 작성자-origin 또는 사용자-origin 규칙이 지정되지 않은 것처럼 지정 값을 계산합니다.
- 작성자 출처(author origin)
- 계단식 값을 사용자 레벨로 롤백합니다. 즉, 해당 요소의 해당 속성에 대해 작성자-origin 규칙이 지정되지 않은 것처럼 지정 값을 계산합니다. revert 목적상, 이 출처에는 애니메이션 origin도 포함됩니다.
7.3.5. 계단식 레이어 롤백: revert-layer 키워드
속성의 계단식 값이 revert-layer 키워드라면, 계단식 값을 아래 레이어로 롤백하여, 해당 요소의 해당 속성에 대해 현재 계단식 레이어 또는 그 안의 일반(normal) 및 중요(important) 수준 사이에서 규칙이 지정되지 않은 것처럼 지정 값을 계산합니다. revert-layer가 중요 요소-부착 스타일(element-attached styles)에서 사용되면, 요소-부착 스타일과 그 사이의 애니메이션 출처(animation origin)만 롤백되며, 그 사이의 작성자 출처(author-origin) 중요 규칙은 롤백되지 않습니다.
참고: 같은 계단식 출처(origin)에 더 낮은 우선순위 선언이 없으면, revert-layer 값이 계단식 값을 이전 출처로 롤백합니다.
참고: 애니메이션 출처(animation origin)는 작성자 출처(author origin)와 revert에서처럼 합쳐지지 않으며, 실제로 독립적인 계단식 레이어를 형성합니다.
8. 레이어 API
8.1.
CSSImportRule
인터페이스 확장
CSSImportRule
인터페이스는 아래와 같이 확장됩니다:
partial interface CSSImportRule {readonly attribute CSSOMString ?layerName ; };
layerName
속성은 at-규칙에 선언된 레이어 이름을 나타내며,
레이어가 익명일 경우 빈 문자열,
at-규칙이 레이어를 선언하지 않는 경우 null입니다.
8.2.
CSSLayerBlockRule
인터페이스
CSSLayerBlockRule
인터페이스는
@layer 블록 규칙(block rule)을 나타냅니다:
[Exposed =Window ]interface :
CSSLayerBlockRule CSSGroupingRule {readonly attribute CSSOMString name ; };
name
속성은 at-규칙에 선언된 레이어 이름을 나타내며,
레이어가 익명일 경우 빈 문자열입니다.
@layer outer{ @layer foo.bar{ } }
이 경우, 내부 @layer 규칙의 name
값은 "foo.bar"입니다(즉, "outer.foo.bar" 아님).
8.3.
CSSLayerStatementRule
인터페이스
CSSLayerStatementRule
인터페이스는
@layer 문장(statement)을 나타냅니다:
[Exposed =Window ]interface :
CSSLayerStatementRule CSSRule {readonly attribute FrozenArray <CSSOMString >nameList ; };
nameList
속성은 at-규칙에서 선언된 레이어 이름의 리스트를 나타내며,
CSSLayerBlockRule
의
name
속성과 동일한 규칙으로 정규화(normalization)됩니다.
9. 변경 사항
9.1. 2021년 10월 15일 워킹드래프트 이후 변경 사항
2021년 10월 15일 워킹 드래프트 이후의 주요 변경 사항:
-
@import 미디어 쿼리와 supports 조건의 문법 스타일 업데이트
-
함수형 표기(parse-time alias) 허용 (이슈 6193)
-
CSSImportRule.layerName을 nullable로 변경 (이슈 6576)
-
style 속성에서 revert-layer가 author 레이어를 되돌리지 않음을 명확화 (이슈 6743)
-
style 속성과 keyframes에서 revert-layer의 동작 명확화 (이슈 6743)
-
§ 4.1.1 값 별칭(Value Aliasing) 섹션 추가 (이슈 6193)
-
§ 8 레이어 API 섹션 추가 (이슈 6576)
-
style 속성 또는 revert-layer 키워드가 keyframes at-규칙에서 사용될 때의 동작 명확화 (이슈 6743)
9.2. 2021년 8월 29일 워킹드래프트 이후 변경 사항
2021년 8월 29일 워킹 드래프트 이후의 변경 사항:
-
레이어 없는 스타일의 정렬 방식 되돌림. (§ 9.3 2021년 6월 8일 워킹드래프트 이후 변경 사항 및 이슈 6284 참고)
-
프리젠테이션 힌트를 레이어 대신 작성자 프리젠테이션 힌트 출처(author presentational hint origin)로 사용하도록 정의함. [CSS-CASCADE-4]에 맞춤. (이슈 6659)
9.3. 2021년 6월 8일 워킹드래프트 이후 변경 사항
2021년 6월 8일 워킹 드래프트 이후의 주요 변경 사항:
-
레이어 이름에서 CSS 전역 키워드 예약 (이슈 6323)
-
@layer 규칙이 전역 조건부 규칙을 존중하지만, 컨테이너 쿼리 등 비전역 조건에서는 항상 레이어 순서에 적용됨을 명확화 (이슈 6407)
-
이름 정의 at-규칙이 충돌 해결 시 레이어 순서를 따르도록 명확화 (특이성 해결과 유사) (이슈 6404)
9.4. 2021년 3월 19일 워킹드래프트 이후 변경 사항
2021년 3월 19일 워킹 드래프트 이후의 주요 변경 사항:
-
일반 출처(normal origins)에서 레이어 없는 스타일 우선순서 최고에서 최저로 변경 (이슈 6284)
9.5. 2021년 1월 19일 워킹드래프트 이후 변경 사항
2021년 1월 19일 퍼블릭 워킹 드래프트 이후의 주요 변경 사항:
-
revert-layer 키워드 추가 (이슈 5793)
9.6. 레벨 4 이후 추가 사항
레벨 4 이후 추가된 기능은 다음과 같습니다:
-
계단식 레이어가 계단식 정렬 기준에 추가됨(그리고 style 속성이 계단식 정렬 기준의 독립 단계로 정의되어 상호작용이 적절해짐)
-
@layer 규칙 도입
-
layer/layer() 옵션이 @import 정의에 추가됨
-
값을 이전 레이어로 롤백하기 위한 revert-layer 키워드 도입
9.7. 레벨 3 이후 추가 사항
레벨 3 이후 추가된 기능은 다음과 같습니다:
-
계단식을 롤백하기 위한 revert 키워드 도입
-
supports-조건 supports() 구문이 @import 규칙에 도입됨
-
Shadow DOM 지원을 위해 캡슐화 컨텍스트(encapsulation context)가 계단식 정렬 기준에 추가됨 [DOM]
-
레거시 구문 지원을 위한 속성 이중 별칭 메커니즘 정의. § 3.1 속성 별칭(Aliasing) 참고.
9.8. 레벨 2 이후 추가 사항
레벨 2 이후 추가된 기능은 다음과 같습니다:
감사의 말씀
David Baron, Tantek Çelik, Florian Rivoal, Simon Sapin, Jen Simmons, 그리고 Boris Zbarsky가 이 명세에 기여했습니다.
개인정보 및 보안 고려사항
-
계단식 처리(cascade process)는 same-origin과 cross-origin 스타일시트를 구분하지 않으므로, cross-origin 스타일시트의 내용을 문서에 적용된 계산된 스타일에서 추론할 수 있습니다.
-
사용자 환경설정(user preferences)과 UA 기본값은 스타일 규칙 적용을 통해 표현되며, 이는 계단식 처리 과정에서 노출되어 계산된 스타일에서 추론될 수 있습니다.
-
@import 규칙은 CORS 프로토콜을 cross-origin 스타일시트 로딩에 적용하지 않으며, 자유롭게 import 및 적용할 수 있습니다.
-
@import 규칙은
Content-Type
메타데이터가 없는 리소스(혹은 호스트 문서가 쿼크 모드일 때 동일 출처 파일)를text/css
로 간주하여, 임의 파일을 페이지에 import해 CSS로 해석 가능하게 만들며, 문서에 적용된 계산된 스타일에서 민감한 데이터가 추론될 수 있습니다.