1. 소개
이 절은 규범적이지 않다.
이 모듈은 CSS 스타일시트와 CSS 구문을 사용하는 기타 항목
(예: HTML style 속성)의 추상 구문과
구문 분석을 정의한다.
Unicode 코드 포인트 스트림(즉, 텍스트)을 CSS 토큰 스트림으로 변환한 다음, 스타일시트, 규칙, 선언과 같은 CSS 객체로 변환하는 알고리즘을 정의한다.
1.1. 모듈 간 상호작용
이 모듈은 CSS 스타일시트의 구문과 구문 분석을 정의한다. CSS 2.1에 정의된 어휘 스캐너와 문법을 대체한다.
2. CSS 구문 설명
이 절은 규범적이지 않다.
CSS 문서는 문서의 요소에 스타일을 적용하는 한정
규칙인 일련의 스타일 규칙과—
한정 규칙은
프렐류드로 시작하고
그 뒤에 일련의 선언을 포함하는 {}로 둘러싸인 블록이 온다.
프렐류드의 의미는 규칙이 나타나는 컨텍스트에 따라 달라진다—
일반적인 규칙은 다음과 같은 형태일 수 있다:
p > a {
color: blue;
text-decoration: underline;
}
위 규칙에서 "p > a"는 선택자이며,
소스 문서가 HTML인 경우
p
요소의 자식인 모든
a
요소를 선택한다.
"color: blue"는
선택자와 일치하는 요소의
color
속성이 blue 값을 가져야 함을 지정하는 선언이다.
마찬가지로 해당 요소의 text-decoration 속성은 underline 값을 가져야 한다.
At-규칙은 모두 서로 다르지만, 공통적인 기본 구조를 가진다. "@" 코드 포인트로 시작하고 그 뒤에 CSS 키워드 형태의 이름이 온다. 일부 at-규칙은 단순한 문이며, 이름 뒤에 동작을 지정하는 CSS 값이 더 오고 마지막에 세미콜론으로 끝난다. 나머지는 블록이다. 이름 뒤에 CSS 값이 올 수 있지만, 한정 규칙과 유사하게 {}로 둘러싸인 블록으로 끝난다. 이러한 블록의 콘텐츠도 주어진 at-규칙에 따라 다르다. 때로는 한정 규칙처럼 일련의 선언을 포함하며, 때로는 추가 블록, at-규칙 또는 완전히 다른 구조를 포함할 수 있다.
다음은 포함할 수 있는 다양한 구문을 보여 주는 at-규칙의 몇 가지 예이다.
@import "my-styles.css";
@import at-규칙은 단순한 문이다. 이름 뒤에 가져올 스타일시트를 나타내는 하나의 문자열 또는 url() 함수를 받는다.
@page :left {
margin-left: 4cm;
margin-right: 3cm;
}
@page at-규칙은 선택적인 페이지 선택자(:left 의사 클래스)와 인쇄할 때 페이지에 적용되는 속성 블록으로 구성된다. 이러한 점에서 일반적인 스타일 규칙과 매우 유사하지만, 해당 속성이 "요소"에 적용되는 것이 아니라 페이지 자체에 적용된다는 점이 다르다.
@media print {
body { font-size: 10pt }
}
@media at-규칙은 미디어 유형과 선택적인 미디어 쿼리 목록으로 시작한다. 블록에는 완전한 규칙이 포함되며, 이 규칙은 @media 조건이 충족될 때만 적용된다.
속성 이름과 at-규칙 이름은 항상 ident 시퀀스이다. 이는 ident 시작 코드 포인트, 두 개의 하이픈 또는 하이픈 다음에 오는 ident 시작 코드 포인트로 시작해야 하며, 그 뒤에 0개 이상의 ident 코드 포인트를 포함할 수 있다. CSS가 구문에서 사용하는 코드 포인트를 포함한 모든 코드 포인트를 이스케이프하여 포함할 수 있다.
선택자 구문은 선택자 명세에 정의되어 있다. 마찬가지로 매우 다양한 CSS 값의 구문은 값 및 단위 명세에 정의되어 있다. 개별 at-규칙의 특수 구문은 해당 규칙을 정의하는 명세에서 찾을 수 있다.
2.1. 이스케이프
이 절은 규범적이지 않다.
모든 Unicode 코드 포인트는 ident 시퀀스 또는 따옴표로 묶인 문자열에서 이스케이프하여 포함할 수 있다. CSS 이스케이프 시퀀스는 백슬래시(\)로 시작하고 다음 중 하나가 이어진다:
- 16진수 숫자나 줄 바꿈이 아닌 모든 Unicode 코드 포인트. 이스케이프 시퀀스는 해당 코드 포인트로 대체된다.
-
또는 1개에서 6개의 16진수 숫자와
그 뒤에 오는 선택적인 공백.
이스케이프 시퀀스는 16진수 숫자로 값이 지정된 Unicode 코드 포인트로
대체된다.
이 선택적인 공백을 사용하면 16진수 이스케이프 시퀀스 뒤에
"실제" 16진수 숫자가 올 수 있다.
값이 "&B"인 ident 시퀀스는 \26 B 또는 \000026B로 작성할 수 있다.
이스케이프 시퀀스 뒤의 "실제" 공백은 두 번 입력해야 한다.
2.2. 오류 처리
이 절은 규범적이지 않다.
CSS에서 오류가 발생하면
구문 분석기는 정상적인 구문 분석으로 돌아가기 전에
최소한의 콘텐츠만 버리면서
원활하게 복구하려고 시도한다.
오류가 항상 실수인 것은 아니기 때문이다—
정확한 오류 복구 동작은 구문 분석기 자체에 자세히 설명되어 있지만, 간단히 설명해도 상당히 정확할 만큼 단순하다.
- 스타일시트의 "최상위 수준"에서는
<at-keyword-token>이 at-규칙을 시작한다.
그 밖의 모든 것은 한정 규칙을 시작하고
규칙의 프렐류드에 포함된다.
이로 인해 유효하지 않은 선택자가 생성될 수 있지만,
이는 CSS 구문 분석기의 관심사가 아니다—
최악의 경우 선택자가 아무것과도 일치하지 않음을 의미할 뿐이다. - at-규칙이 시작되면 구문 분석기의 관점에서는 어떤 것도 유효하지 않지 않다. 모두 at-규칙의 프렐류드에 속한다. <semicolon-token>을 만나면 at-규칙이 즉시 끝나고, 여는 중괄호 <{-token>을 만나면 at-규칙의 본문이 시작된다. at-규칙은 다른 것과 짝을 이루지 않고 다른 블록 안에도 있지 않은 닫는 중괄호 <}-token>을 찾을 때까지 블록((), {}, []로 둘러싸인 콘텐츠)의 짝을 맞추며 앞으로 탐색한다. 그런 다음 at-규칙의 콘텐츠를 해당 at-규칙 자체의 문법에 따라 해석한다.
- 한정 규칙도 비슷하게 작동하지만 세미콜론으로 끝나지는 않는다. 대신 세미콜론은 규칙의 프렐류드 일부로 받아들여진다. 첫 번째 {} 블록을 찾으면 그 콘텐츠는 항상 선언 목록으로 해석된다.
- 선언 목록을 해석할 때 어느 지점에서든 알 수 없는 구문이 나타나면 구문 분석기는 현재 작성 중인 선언을 버리고, 세미콜론(또는 블록의 끝)을 찾을 때까지 앞으로 탐색한다. 그런 다음 새로 시작하여 선언의 구문 분석을 다시 시도한다.
- 규칙, 선언, 함수, 문자열 등이 아직 열린 상태에서 스타일시트가 끝나면 모두 자동으로 닫힌다. 그렇다고 해서 유효하지 않게 되는 것은 아니지만, 불완전할 수 있으며 따라서 문법에 따라 검증될 때 버려질 수 있다.
각 구문(선언, 스타일 규칙, at-규칙)이 구문 분석된 후 사용자 에이전트는 예상되는 문법에 따라 이를 검사한다. 문법과 일치하지 않으면 유효하지 않은 것으로 판정되고, UA가 이를 무시하며, 전혀 존재하지 않았던 것처럼 취급한다.
3. CSS 토큰화 및 구문 분석
사용자 에이전트는 text/css 리소스에서 [CSSOM] 트리를 생성하기 위해 이 명세에서 설명하는 구문 분석 규칙을 사용해야 한다. 이러한 규칙을 통틀어 CSS 구문 분석기라고 한다.
이 명세는 구문상 올바른지 여부와 관계없이 CSS 문서의 구문 분석 규칙을 정의한다. 구문 분석 알고리즘의 특정 지점을 구문 분석 오류라고 한다. 구문 분석 오류에 대한 오류 처리는 명확히 정의되어 있다. 사용자 에이전트는 이러한 문제가 발생하면 아래 설명대로 동작하거나, 아래 설명된 규칙을 적용하고 싶지 않은 오류를 처음 만났을 때 처리를 중단해야 한다.
문서에 하나 이상의 구문 분석 오류 조건이 있으면 적합성 검사기는 사용자에게 최소 하나의 구문 분석 오류 조건을 보고해야 하며, 문서에 구문 분석 오류 조건이 없으면 보고해서는 안 된다. 문서에 구문 분석 오류 조건이 두 개 이상 있으면 적합성 검사기는 두 개 이상의 구문 분석 오류 조건을 보고할 수 있다. 적합성 검사기는 구문 분석 오류에서 복구할 필요가 없지만, 복구하는 경우 사용자 에이전트와 동일한 방식으로 복구해야 한다.
3.1. 구문 분석 모델 개요
CSS 구문 분석 프로세스의 입력은 Unicode 코드 포인트 스트림으로 구성되며, 토큰화 단계를 거친 다음 트리 구성 단계를 거친다. 출력은 CSSStyleSheet 객체이다.
참고: 스크립팅을 지원하지 않는 구현은 실제로 CSSOM CSSStyleSheet 객체를 생성할 필요가 없지만, 그러한 경우에도 CSSOM 트리는 명세의 나머지 부분을 위한 모델로 사용된다.
3.2. 입력 바이트 스트림
스타일시트를 구문 분석할 때 토큰화 단계의 입력을 구성하는 Unicode 코드 포인트 스트림은 처음에는 사용자 에이전트에 바이트 스트림으로 보일 수 있다 (일반적으로 네트워크 또는 로컬 파일 시스템에서 가져온다). 그런 경우 사용자 에이전트는 특정 문자 인코딩에 따라 이러한 바이트를 코드 포인트로 디코딩해야 한다.
-
stylesheet의 대체 인코딩을 결정하고, 그 결과를 fallback으로 둔다.
-
대체 인코딩 fallback을 사용하여 stylesheet의 바이트 스트림을 디코딩하고 결과를 반환한다.
참고: 디코딩 알고리즘은 바이트 순서 표시(BOM)에 우선권을 부여하며, 이를 찾지 못한 경우에만 대체 인코딩을 사용한다.
- HTTP 또는 이에 준하는 프로토콜이 stylesheet에 대해 encoding label을 제공하는 경우 (예: Content-Type 헤더의 charset 매개변수를 통해), encoding label에서 인코딩을 가져온다. 실패를 반환하지 않으면 해당 인코딩을 반환한다.
-
그렇지 않으면 stylesheet의 바이트 스트림을 확인한다.
스트림의 처음 1024바이트가 다음 16진수 시퀀스로 시작하는 경우
40 63 68 61 72 73 65 74 20 22 XX* 22 3B
각
XX바이트는 016 이상 2116 이하의 값 또는 2316 이상 7F16 이하의 값이며,XX바이트 시퀀스로 구성되고ASCII로 해석한 문자열에서 인코딩을 가져온다.해당 바이트 시퀀스는 무엇을 의미하는가?
위의 바이트 시퀀스를 ASCII로 디코딩하면 "
@charset "…";" 문자열이며, 여기서 "…"는 인코딩 레이블에 해당하는 바이트 시퀀스이다.반환 값이
utf-16be또는utf-16le이면utf-8을 반환한다. 실패가 아닌 다른 값이면 해당 값을 반환한다.선언에서 utf-16을 지정했는데 왜 utf-8을 사용하는가?
인코딩 선언의 바이트는 ASCII로 “
@charset "…";”을 나타내지만, UTF-16은 ASCII와 호환되지 않는다. 문서에 올바른 바이트를 넣기 위해 완전히 의미 없는 문자열(예:䁣桡牳整•utf-16be∻)을 입력했거나, 이는 권장하고 싶지 않은 방식이며, 또는 문서가 실제로 ASCII 호환 인코딩을 사용하지만 인코딩 선언이 사실과 다른 것이다.어느 경우든 UTF-8을 기본값으로 사용하는 것이 합리적이다.
또한 이는 HTML의
<meta charset>속성 동작을 모방한다.참고: 인코딩 선언의 구문은 @charset이라는 이름의 at-규칙 구문처럼 보이지만, 실제로 그러한 규칙은 존재하지 않으며, 이를 작성하는 방법에 관한 규칙은 일반적으로 그러한 규칙을 인식할 때보다 훨씬 더 제한적이다. 여러 공백, 주석 또는 작은따옴표를 사용하는 것처럼 CSS에서 유효한 @charset 규칙을 생성할 수 있는 여러 작업도 (그러한 규칙이 존재한다고 가정하면) 인코딩 선언이 인식되지 않게 한다. 이 동작은 인코딩 선언을 최대한 단순하게 유지하여 올바르게 구현될 가능성을 극대화한다.
- 그렇지 않고 참조하는 문서에서 환경 인코딩을 제공하면 이를 반환한다.
- 그렇지 않으면
utf-8을 반환한다.
UTF-8은 웹의 기본 인코딩이며 많은 최신 웹 기반 파일 형식은 UTF-8 인코딩을 가정하거나 요구하지만, CSS는 어떤 인코딩이 주류가 될지 명확해지기 전에 만들어졌으므로 스타일시트가 UTF-8이라고 자동으로 가정할 수 없다.
스타일시트 작성자는 스타일시트를 UTF-8로 작성해야 하며,
HTTP 헤더(또는 이에 준하는 방법)가 스타일시트의 인코딩을
UTF-8로 선언하거나,
참조하는 문서가 해당 인코딩을 UTF-8로 선언하도록 해야 한다.
(HTML에서는 문서의 head에 <meta charset=utf-8> 요소를 추가하여
이를 수행한다.)
이러한 옵션을 모두 사용할 수 없다면 작성자는 스타일시트를 UTF-8 BOM 또는 다음의 정확한 문자로 시작해야 한다.
@charset "utf-8";
바이트에서 디코딩되는 CSS 스타일시트를 참조하는 문서 언어는 각 스타일시트에 환경 인코딩을 정의할 수 있으며, 이는 다른 인코딩 힌트를 사용할 수 없을 때 대체 인코딩으로 사용된다.
환경 인코딩이라는 개념은 레거시 콘텐츠와의 호환성을 위해서만 존재한다. 새로운 형식과 새로운 연결 메커니즘은 환경 인코딩을 제공해서는 안 되며, 더 명시적인 정보가 없으면 스타일시트가 대신 UTF-8을 기본값으로 사용하도록 해야 한다.
참고: [HTML]은
<link rel=stylesheet>의
환경 인코딩을 정의한다.
참고: [CSSOM]은
<xml-stylesheet?>의
환경 인코딩을 정의한다.
참고: [CSS-CASCADE-3]은 @import의
환경 인코딩을 정의한다.
3.3. 입력 스트림 전처리
입력 스트림은 입력 바이트 스트림이 디코딩될 때 그 안으로 푸시되는 필터링된 코드 포인트로 구성된다.
4. 토큰화
코드 포인트 스트림 input을 CSS 토큰 스트림으로 토큰화하려면, <EOF-token>에 도달할 때까지 input에서 반복해서 토큰을 소비하고, 반환된 각 토큰을 스트림에 푸시한다.
참고: 토큰을 소비 알고리즘을 호출할 때마다 하나의 토큰을 반환하므로, 원하는 경우 구문 분석 도중에 코드 포인트 스트림을 "요청 시" 토큰화하는 데에도 사용할 수 있다.
토큰화 단계의 출력은 다음 토큰 중 0개 이상으로 이루어진 스트림이다: <ident-token>, <function-token>, <at-keyword-token>, <hash-token>, <string-token>, <bad-string-token>, <url-token>, <bad-url-token>, <delim-token>, <number-token>, <percentage-token>, <dimension-token>, <whitespace-token>, <CDO-token>, <CDC-token>, <colon-token>, <semicolon-token>, <comma-token>, <[-token>, <]-token>, <(-token>, <)-token>, <{-token> 및 <}-token>.
- <ident-token>, <function-token>, <at-keyword-token>, <hash-token>, <string-token> 및 <url-token>에는 0개 이상의 코드 포인트로 구성된 값이 있다. 또한 해시 토큰에는 "id" 또는 "unrestricted"로 설정되는 유형 플래그가 있다. 별도로 설정되지 않으면 유형 플래그의 기본값은 "unrestricted"이다.
- <delim-token>에는 하나의 코드 포인트로 구성된 값이 있다.
- <number-token>, <percentage-token> 및 <dimension-token>에는 숫자 값이 있다. <number-token> 및 <dimension-token>에는 추가로 "integer" 또는 "number"로 설정되는 유형 플래그가 있다. 별도로 설정되지 않으면 유형 플래그의 기본값은 "integer"이다. <dimension-token>에는 추가로 하나 이상의 코드 포인트로 구성된 단위가 있다.
참고: 해시 토큰의 유형 플래그는 선택자 구문 [SELECT]에서 사용된다. "id" 유형의 해시 토큰만 유효한 ID 선택자이다.
4.1. 토큰 레일로드 다이어그램
이 절은 비규범적이다.
이 절에서는 토크나이저를 레일로드 다이어그램 형태로 비규범적으로 보여 준다. 레일로드 다이어그램은 명시적인 구문 분석기보다 간결하면서도 정규 표현식보다 읽기 쉬운 경우가 많다.
이 다이어그램은 비규범적이며 불완전하다. "올바른" 토큰의 문법을 설명하지만 오류 처리는 전혀 설명하지 않는다. 각 토큰의 구문을 직관적으로 파악하기 쉽도록 하기 위한 목적으로만 제공된다.
<foo-token>과 같은 이름이 있는 다이어그램은 토큰을 나타낸다. 나머지는 다른 다이어그램에서 참조하는 생성 규칙이다.
- comment
-
- newline
-
- whitespace
-
- hex digit
-
- escape
-
- <whitespace-token>
-
- ws*
-
- <ident-token>
-
- <function-token>
-
- <at-keyword-token>
-
- <hash-token>
-
- <string-token>
-
- <url-token>
-
- <number-token>
-
- <dimension-token>
-
- <percentage-token>
-
- <CDO-token>
-
- <CDC-token>
-
4.2. 정의
이 절에서는 토큰화 단계에서 사용하는 여러 용어를 정의한다.
- 다음 입력 코드 포인트
- 입력 스트림에서 아직 소비되지 않은 첫 번째 코드 포인트.
- 현재 입력 코드 포인트
- 마지막으로 소비된 코드 포인트.
- 현재 입력 코드 포인트를 다시 소비
- 현재 입력 코드 포인트를 입력 스트림의 맨 앞에 다시 넣어, 다음에 다음 입력 코드 포인트를 소비하라는 지시를 받으면 대신 현재 입력 코드 포인트를 다시 소비하도록 한다.
- EOF 코드 포인트
- 입력 스트림의 끝을 나타내는 개념적인 코드 포인트. 입력 스트림이 비어 있을 때마다 다음 입력 코드 포인트는 항상 EOF 코드 포인트이다.
- 숫자
- U+0030 DIGIT ZERO (0) 이상 U+0039 DIGIT NINE (9) 이하의 코드 포인트.
- 16진수 숫자
- 숫자, U+0041 LATIN CAPITAL LETTER A (A) 이상 U+0046 LATIN CAPITAL LETTER F (F) 이하의 코드 포인트, 또는 U+0061 LATIN SMALL LETTER A (a) 이상 U+0066 LATIN SMALL LETTER F (f) 이하의 코드 포인트.
- 대문자
- U+0041 LATIN CAPITAL LETTER A (A) 이상 U+005A LATIN CAPITAL LETTER Z (Z) 이하의 코드 포인트.
- 소문자
- U+0061 LATIN SMALL LETTER A (a) 이상 U+007A LATIN SMALL LETTER Z (z) 이하의 코드 포인트.
- 문자
- 대문자 또는 소문자.
- 비ASCII 코드 포인트
- 값이 U+0080 <control> 이상인 코드 포인트.
- ident 시작 코드 포인트
- 문자, 비ASCII 코드 포인트 또는 U+005F LOW LINE (_).
- ident 코드 포인트
- ident 시작 코드 포인트, 숫자 또는 U+002D HYPHEN-MINUS (-).
- 인쇄할 수 없는 코드 포인트
- U+0000 NULL 이상 U+0008 BACKSPACE 이하의 코드 포인트, U+000B LINE TABULATION, U+000E SHIFT OUT 이상 U+001F INFORMATION SEPARATOR ONE 이하의 코드 포인트 또는 U+007F DELETE.
- 줄 바꿈
- U+000A LINE FEED. U+000D CARRIAGE RETURN과 U+000C FORM FEED는 이 정의에 포함되지 않는다는 점에 유의한다. 전처리 중에 U+000A LINE FEED로 변환되기 때문이다.
- 공백
- 줄 바꿈, U+0009 CHARACTER TABULATION 또는 U+0020 SPACE.
- 허용되는 최대 코드 포인트
- Unicode에서 정의한 가장 큰 코드 포인트: U+10FFFF.
- ident 시퀀스
-
<ident-token>과 같은 구문을 갖는 코드 포인트 시퀀스.
참고: <at-keyword-token>에서 "@" 뒤의 부분, <hash-token>("id" 유형 플래그 사용)에서 "#" 뒤의 부분, <function-token>에서 "(" 앞의 부분 및 <dimension-token>의 단위는 모두 ident 시퀀스이다.
- 표현
-
토큰의 표현은
해당 토큰을 생성한 토큰 소비 알고리즘
호출이 소비한
입력
스트림의 하위 시퀀스이다.
이는 입력 텍스트의 미묘한 세부 정보에 의존하는 일부 알고리즘을 위해 보존된다.
토큰을 단순히 "재직렬화"하면 이러한 세부 정보가 달라질 수 있기 때문이다.
표현은 내부 알고리즘에서만 소비되며 직접 노출되지 않으므로 정확한 텍스트를 실제로 보존할 필요는 없다. 각 토큰을 소스 텍스트의 오프셋과 연결하는 것과 같은 동등한 방법으로도 충분하다.
참고: 특히 표현은 .009가 .009 또는 9e-3 중 어느 형태로 작성되었는지, 그리고 문자가 리터럴로 작성되었는지 CSS 이스케이프로 작성되었는지와 같은 세부 정보를 보존한다. 전자는 <urange> 생성 규칙을 올바르게 구문 분석하는 데 필요하다. 후자는 기본적으로 토큰화 추상화가 우연히 노출된 것이지만, 구현을 더 쉽게 정의할 수 있으므로 허용된다.
토큰화 알고리즘이 아니라 다른 알고리즘에서 토큰을 직접 생성한 경우 해당 표현은 빈 문자열이다.
4.3. 토크나이저 알고리즘
이 절에서 정의한 알고리즘은 코드 포인트 스트림을 토큰 스트림으로 변환한다.
4.3.1. 토큰 소비
이 절에서는 코드 포인트 스트림에서 토큰을 소비하는 방법을 설명한다. 모든 유형 중 하나인 단일 토큰을 반환한다.
다음 입력 코드 포인트를 소비한다.
- 공백
- 가능한 한 많은 공백을 소비한다. <whitespace-token>을 반환한다.
- U+0022 QUOTATION MARK (")
- 문자열 토큰을 소비하고 반환한다.
- U+0023 NUMBER SIGN (#)
-
다음
입력 코드 포인트가 ident
코드 포인트이거나 다음 두 입력 코드 포인트가 유효한 이스케이프이면
다음을 수행한다:
- <hash-token>을 생성한다.
- 다음 세 입력 코드 포인트가 ident 시퀀스를 시작하면, <hash-token>의 유형 플래그를 "id"로 설정한다.
- ident 시퀀스를 소비하고, <hash-token>의 값을 반환된 문자열로 설정한다.
- <hash-token>을 반환한다.
그렇지 않으면 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환한다.
- U+0027 APOSTROPHE (')
- 문자열 토큰을 소비하고 반환한다.
- U+0028 LEFT PARENTHESIS (()
- <(-token>을 반환한다.
- U+0029 RIGHT PARENTHESIS ())
- <)-token>을 반환한다.
- U+002B PLUS SIGN (+)
-
입력 스트림이 숫자로 시작하면, 현재 입력 코드 포인트를 다시 소비하고, 숫자 토큰을
소비한 다음
반환한다.
그렇지 않으면 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환한다.
- U+002C COMMA (,)
- <comma-token>을 반환한다.
- U+002D HYPHEN-MINUS (-)
-
입력 스트림이 숫자로 시작하면, 현재 입력 코드 포인트를 다시 소비하고, 숫자 토큰을
소비한 다음
반환한다.
그렇지 않고 다음 두 입력 코드 포인트가 U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->)이면 이를 소비하고 <CDC-token>을 반환한다.
그렇지 않고 입력 스트림이 ident 시퀀스로 시작하면, 현재 입력 코드 포인트를 다시 소비하고, ident 유사 토큰을 소비한 다음 반환한다.
그렇지 않으면 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환한다.
- U+002E FULL STOP (.)
-
입력 스트림이 숫자로 시작하면, 현재 입력 코드 포인트를 다시 소비하고, 숫자 토큰을
소비한 다음
반환한다.
그렇지 않으면 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환한다.
- U+003A COLON (:)
- <colon-token>을 반환한다.
- U+003B SEMICOLON (;)
- <semicolon-token>을 반환한다.
- U+003C LESS-THAN SIGN (<)
-
다음 세
입력 코드 포인트가
U+0021 EXCLAMATION MARK
U+002D HYPHEN-MINUS
U+002D HYPHEN-MINUS
(!--)이면
이를 소비하고
<CDO-token>을 반환한다.
그렇지 않으면 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환한다.
- U+0040 COMMERCIAL AT (@)
-
다음 세
입력 코드 포인트가 ident
시퀀스를 시작하면, ident 시퀀스를 소비하고,
값이 반환된 값으로 설정된 <at-keyword-token>을 생성한 다음
반환한다.
그렇지 않으면 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환한다.
- U+005B LEFT SQUARE BRACKET ([)
- <[-token>을 반환한다.
- U+005C REVERSE SOLIDUS (\)
-
입력 스트림이 유효한 이스케이프로 시작하면, 현재 입력 코드 포인트를 다시 소비하고, ident 유사 토큰을 소비한 다음
반환한다.
그렇지 않으면 이는 구문 분석 오류이다. 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환한다.
- U+005D RIGHT SQUARE BRACKET (])
- <]-token>을 반환한다.
- U+007B LEFT CURLY BRACKET ({)
- <{-token>을 반환한다.
- U+007D RIGHT CURLY BRACKET (})
- <}-token>을 반환한다.
- 숫자
- 현재 입력 코드 포인트를 다시 소비하고, 숫자 토큰을 소비한 다음 반환한다.
- ident 시작 코드 포인트
- 현재 입력 코드 포인트를 다시 소비하고, ident 유사 토큰을 소비한 다음 반환한다.
- EOF
- <EOF-token>을 반환한다.
- 그 밖의 모든 것
- 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환한다.
4.3.2. 주석 소비
이 절에서는 코드 포인트 스트림에서 주석을 소비하는 방법을 설명한다. 아무것도 반환하지 않는다.
다음 두 입력 코드 포인트가 U+002F SOLIDUS (/) 다음에 U+002A ASTERISK (*)가 오는 형태이면, 이를 소비하고 이후의 코드 포인트 중 U+002A ASTERISK (*) 다음에 U+002F SOLIDUS (/)가 오는 첫 번째 지점까지 포함하여 소비하거나 EOF 코드 포인트까지 소비한다. 이 단계의 시작으로 돌아간다.
앞 단락이 EOF 코드 포인트를 소비하여 종료되었다면, 이는 구문 분석 오류이다.
아무것도 반환하지 않는다.
4.3.3. 숫자 토큰 소비
이 절에서는 코드 포인트 스트림에서 숫자 토큰을 소비하는 방법을 설명한다. <number-token>, <percentage-token> 또는 <dimension-token> 중 하나를 반환한다.
숫자를 소비하고 그 결과를 number로 둔다.
다음 세 입력 코드 포인트가 ident 시퀀스를 시작하면 다음을 수행한다:
- number와 같은 값 및 유형 플래그를 갖고 단위가 처음에는 빈 문자열로 설정된 <dimension-token>을 생성한다.
- ident 시퀀스를 소비한다. <dimension-token>의 단위를 반환된 값으로 설정한다.
- <dimension-token>을 반환한다.
그렇지 않고 다음 입력 코드 포인트가 U+0025 PERCENTAGE SIGN (%)이면, 이를 소비한다. number와 같은 값을 갖는 <percentage-token>을 생성하고 반환한다.
그렇지 않으면 number와 같은 값 및 유형 플래그를 갖는 <number-token>을 생성하고 반환한다.
4.3.4. ident 유사 토큰 소비
이 절에서는 코드 포인트 스트림에서 ident 유사 토큰을 소비하는 방법을 설명한다. <ident-token>, <function-token>, <url-token> 또는 <bad-url-token>을 반환한다.
ident 시퀀스를 소비하고 그 결과를 string으로 둔다.
string의 값이 "url"과 ASCII 대소문자 구분 없이 일치하고, 다음 입력 코드 포인트가 U+0028 LEFT PARENTHESIS (()이면 이를 소비한다. 다음 두 입력 코드 포인트가 공백인 동안 다음 입력 코드 포인트를 소비한다. 다음 한두 개의 입력 코드 포인트가 U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE (') 또는 공백 다음에 U+0022 QUOTATION MARK (")나 U+0027 APOSTROPHE (')가 오는 형태이면, 값이 string으로 설정된 <function-token>을 생성하고 반환한다. 그렇지 않으면 URL 토큰을 소비하고 반환한다.
그렇지 않고 다음 입력 코드 포인트가 U+0028 LEFT PARENTHESIS (()이면 이를 소비한다. 값이 string으로 설정된 <function-token>을 생성하고 반환한다.
그렇지 않으면 값이 string으로 설정된 <ident-token>을 생성하고 반환한다.
4.3.5. 문자열 토큰 소비
이 절에서는 코드 포인트 스트림에서 문자열 토큰을 소비하는 방법을 설명한다. <string-token> 또는 <bad-string-token>을 반환한다.
이 알고리즘은 문자열을 끝내는 코드 포인트를 나타내는 ending code point와 함께 호출될 수 있다. ending code point가 지정되지 않으면 현재 입력 코드 포인트를 사용한다.
처음에 값이 빈 문자열로 설정된 <string-token>을 생성한다.
스트림에서 다음 입력 코드 포인트를 반복해서 소비한다:
- ending code point
- <string-token>을 반환한다.
- EOF
- 이는 구문 분석 오류이다. <string-token>을 반환한다.
- 줄 바꿈
- 이는 구문 분석 오류이다. 현재 입력 코드 포인트를 다시 소비하고, <bad-string-token>을 생성한 다음 반환한다.
- U+005C REVERSE SOLIDUS (\)
-
다음
입력 코드 포인트가 EOF이면
아무것도 하지 않는다.
그렇지 않고 다음 입력 코드 포인트가 줄 바꿈이면 이를 소비한다.
그렇지 않으면 (스트림이 유효한 이스케이프로 시작한다) 이스케이프된 코드 포인트를 소비하고 반환된 코드 포인트를 <string-token>의 값에 추가한다.
- 그 밖의 모든 것
- 현재 입력 코드 포인트를 <string-token>의 값에 추가한다.
4.3.6. URL 토큰 소비
이 절에서는 코드 포인트 스트림에서 URL 토큰을 소비하는 방법을 설명한다. <url-token> 또는 <bad-url-token>을 반환한다.
참고: 이 알고리즘은 처음의 "url("가 이미 소비되었다고 가정한다. 또한 url(foo)와 같은 "따옴표로 묶이지 않은" 값을 소비하기 위해 호출된다고 가정한다. url("foo")와 같이 따옴표로 묶인 값은 <function-token>으로 구문 분석된다. ident 유사 토큰 소비는 이 차이를 자동으로 처리한다. 그 외의 경우에는 이 알고리즘을 직접 호출해서는 안 된다.
- 처음에 값이 빈 문자열로 설정된 <url-token>을 생성한다.
- 가능한 한 많은 공백을 소비한다.
-
스트림에서 다음 입력
코드 포인트를 반복해서 소비한다:
- U+0029 RIGHT PARENTHESIS ())
- <url-token>을 반환한다.
- EOF
- 이는 구문 분석 오류이다. <url-token>을 반환한다.
- 공백
- 가능한 한 많은 공백을 소비한다. 다음 입력 코드 포인트가 U+0029 RIGHT PARENTHESIS ()) 또는 EOF이면 이를 소비하고 <url-token>을 반환한다 (EOF를 만났다면 이는 구문 분석 오류이다). 그렇지 않으면 잘못된 URL의 나머지 부분을 소비하고, <bad-url-token>을 생성한 다음 반환한다.
- U+0022 QUOTATION MARK (")
- U+0027 APOSTROPHE (')
- U+0028 LEFT PARENTHESIS (()
- 인쇄할 수 없는 코드 포인트
- U+0027 APOSTROPHE (')
- 이는 구문 분석 오류이다. 잘못된 URL의 나머지 부분을 소비하고, <bad-url-token>을 생성한 다음 반환한다.
- U+005C REVERSE SOLIDUS (\)
-
스트림이 유효한 이스케이프로 시작하면, 이스케이프된 코드 포인트를 소비하고 반환된
코드 포인트를 <url-token>의 값에 추가한다.
그렇지 않으면 이는 구문 분석 오류이다. 잘못된 URL의 나머지 부분을 소비하고, <bad-url-token>을 생성한 다음 반환한다.
- 그 밖의 모든 것
- 현재 입력 코드 포인트를 <url-token>의 값에 추가한다.
4.3.7. 이스케이프된 코드 포인트 소비
이 절에서는 이스케이프된 코드 포인트를 소비하는 방법을 설명한다. U+005C REVERSE SOLIDUS (\)가 이미 소비되었고 다음 입력 코드 포인트가 유효한 이스케이프의 일부임이 이미 확인되었다고 가정한다. 코드 포인트를 반환한다.
다음 입력 코드 포인트를 소비한다.
- 16진수 숫자
- 가능한 한 많은 16진수 숫자를 소비하되 최대 5개까지만 소비한다. 이는 총 1~6개의 16진수 숫자가 소비되었음을 의미한다. 다음 입력 코드 포인트가 공백이면 이 역시 소비한다. 16진수 숫자를 16진수로 해석한다. 이 숫자가 0이거나, 서로게이트에 해당하거나, 허용되는 최대 코드 포인트보다 크면 U+FFFD REPLACEMENT CHARACTER (�)를 반환한다. 그렇지 않으면 해당 값을 갖는 코드 포인트를 반환한다.
- EOF
- 이는 구문 분석 오류이다. U+FFFD REPLACEMENT CHARACTER (�)를 반환한다.
- 그 밖의 모든 것
- 현재 입력 코드 포인트를 반환한다.
4.3.8. 두 코드 포인트가 유효한 이스케이프인지 확인
이 절에서는 두 코드 포인트가 유효한 이스케이프인지 확인하는 방법을 설명한다. 여기에 설명된 알고리즘은 두 코드 포인트를 명시적으로 전달하여 호출하거나 입력 스트림 자체를 전달하여 호출할 수 있다. 후자의 경우 해당 두 코드 포인트는 순서대로 현재 입력 코드 포인트와 다음 입력 코드 포인트이다.
참고: 이 알고리즘은 추가 코드 포인트를 소비하지 않는다.
첫 번째 코드 포인트가 U+005C REVERSE SOLIDUS (\)가 아니면 false를 반환한다.
그렇지 않고 두 번째 코드 포인트가 줄 바꿈이면 false를 반환한다.
그렇지 않으면 true를 반환한다.
4.3.9. 세 코드 포인트가 ident 시퀀스를 시작하는지 확인
이 절에서는 세 코드 포인트가 ident 시퀀스를 시작하는지 확인한다. 여기에 설명된 알고리즘은 세 코드 포인트를 명시적으로 전달하여 호출하거나 입력 스트림 자체를 전달하여 호출할 수 있다. 후자의 경우 해당 세 코드 포인트는 순서대로 현재 입력 코드 포인트와 다음 두 입력 코드 포인트이다.
참고: 이 알고리즘은 추가 코드 포인트를 소비하지 않는다.
첫 번째 코드 포인트를 확인한다:
- U+002D HYPHEN-MINUS
- 두 번째 코드 포인트가 ident 시작 코드 포인트 또는 U+002D HYPHEN-MINUS이거나, 두 번째 및 세 번째 코드 포인트가 유효한 이스케이프이면 true를 반환한다. 그렇지 않으면 false를 반환한다.
- ident 시작 코드 포인트
- true를 반환한다.
- U+005C REVERSE SOLIDUS (\)
- 첫 번째 및 두 번째 코드 포인트가 유효한 이스케이프이면 true를 반환한다. 그렇지 않으면 false를 반환한다.
- 그 밖의 모든 것
- false를 반환한다.
4.3.10. 세 코드 포인트가 숫자를 시작하는지 확인
이 절에서는 세 코드 포인트가 숫자를 시작하는지 확인하는 방법을 설명한다. 여기에 설명된 알고리즘은 세 코드 포인트를 명시적으로 전달하여 호출하거나 입력 스트림 자체를 전달하여 호출할 수 있다. 후자의 경우 해당 세 코드 포인트는 순서대로 현재 입력 코드 포인트와 다음 두 입력 코드 포인트이다.
참고: 이 알고리즘은 추가 코드 포인트를 소비하지 않는다.
첫 번째 코드 포인트를 확인한다:
- U+002B PLUS SIGN (+)
- U+002D HYPHEN-MINUS (-)
-
두 번째 코드 포인트가 숫자이면
true를 반환한다.
그렇지 않고 두 번째 코드 포인트가 U+002E FULL STOP (.)이며 세 번째 코드 포인트가 숫자이면 true를 반환한다.
그렇지 않으면 false를 반환한다.
- U+002E FULL STOP (.)
- 두 번째 코드 포인트가 숫자이면 true를 반환한다. 그렇지 않으면 false를 반환한다.
- 숫자
- true를 반환한다.
- 그 밖의 모든 것
- false를 반환한다.
4.3.11. ident 시퀀스 소비
이 절에서는 ident 시퀀스를 소비하는 방법을 코드 포인트 스트림을 대상으로 설명한다. 스트림의 처음부터 시작하여 인접한 코드 포인트로 구성할 수 있는 가장 긴 이름을 포함하는 문자열을 반환한다.
참고: 이 알고리즘은 반환되는 코드 포인트가 <ident-token>을 구성하도록 보장하는 데 필요한 처음 몇 코드 포인트의 검증을 수행하지 않는다. 이것이 의도한 용도라면 이 알고리즘을 호출하기 전에 스트림이 ident 시퀀스로 시작하는지 확인한다.
처음에 result를 빈 문자열로 둔다.
스트림에서 다음 입력 코드 포인트를 반복해서 소비한다:
- ident 코드 포인트
- 코드 포인트를 result에 추가한다.
- 스트림이 유효한 이스케이프로 시작
- 이스케이프된 코드 포인트를 소비한다. 반환된 코드 포인트를 result에 추가한다.
- 그 밖의 모든 것
- 현재 입력 코드 포인트를 다시 소비한다. result를 반환한다.
4.3.12. 숫자 소비
이 절에서는 코드 포인트 스트림에서 숫자를 소비하는 방법을 설명한다. 숫자 value와 "integer" 또는 "number"인 type을 반환한다.
참고: 이 알고리즘은 스트림에서 숫자를 얻을 수 있음을 보장하는 데 필요한 처음 몇 코드 포인트의 검증을 수행하지 않는다. 이 알고리즘을 호출하기 전에 스트림이 숫자로 시작하는지 확인한다.
다음 단계를 순서대로 실행한다:
- 처음에 type을 "integer"로 설정한다. repr을 빈 문자열로 둔다.
- 다음 입력 코드 포인트가 U+002B PLUS SIGN (+) 또는 U+002D HYPHEN-MINUS (-)이면 이를 소비하여 repr에 추가한다.
- 다음 입력 코드 포인트가 숫자인 동안 이를 소비하여 repr에 추가한다.
-
다음 두
입력 코드 포인트가
U+002E FULL STOP (.) 다음에 숫자가 오는 형태이면
다음을 수행한다:
- 이를 소비한다.
- 이를 repr에 추가한다.
- type을 "number"로 설정한다.
- 다음 입력 코드 포인트가 숫자인 동안 이를 소비하여 repr에 추가한다.
-
다음 두
개 또는 세 개의 입력 코드 포인트가
U+0045 LATIN CAPITAL LETTER E (E) 또는 U+0065 LATIN SMALL LETTER E (e)이고,
선택적으로 그 뒤에 U+002D HYPHEN-MINUS (-) 또는 U+002B PLUS SIGN (+)가 오며,
그 뒤에 숫자가 오면
다음을 수행한다:
- 이를 소비한다.
- 이를 repr에 추가한다.
- type을 "number"로 설정한다.
- 다음 입력 코드 포인트가 숫자인 동안 이를 소비하여 repr에 추가한다.
- repr을 숫자로 변환하고, value를 반환된 값으로 설정한다.
- value와 type을 반환한다.
4.3.13. 문자열을 숫자로 변환
이 절에서는 문자열을 숫자로 변환하는 방법을 설명한다. 숫자를 반환한다.
참고: 이 알고리즘은 문자열에 숫자만 포함되어 있는지 확인하는 검증을 수행하지 않는다. 이 알고리즘을 호출하기 전에 문자열에 유효한 CSS 숫자만 포함되어 있는지 확인한다.
문자열을 왼쪽에서 오른쪽 순서로 다음 일곱 구성 요소로 나눈다:
- 부호: 하나의 U+002B PLUS SIGN (+) 또는 U+002D HYPHEN-MINUS (-), 또는 빈 문자열. 부호가 U+002D HYPHEN-MINUS (-)이면 s를 숫자 -1로 둔다. 그렇지 않으면 s를 숫자 1로 둔다.
- 정수부: 0개 이상의 숫자. 숫자가 하나 이상 있으면 해당 숫자를 10진수 정수로 해석하여 형성한 수를 i로 둔다. 그렇지 않으면 i를 숫자 0으로 둔다.
- 소수점: 하나의 U+002E FULL STOP (.), 또는 빈 문자열.
- 소수부: 0개 이상의 숫자. 숫자가 하나 이상 있으면 해당 숫자를 10진수 정수로 해석하여 형성한 수를 f로 두고 숫자의 개수를 d로 둔다. 그렇지 않으면 f와 d를 숫자 0으로 둔다.
- 지수 표시자: 하나의 U+0045 LATIN CAPITAL LETTER E (E) 또는 U+0065 LATIN SMALL LETTER E (e), 또는 빈 문자열.
- 지수 부호: 하나의 U+002B PLUS SIGN (+) 또는 U+002D HYPHEN-MINUS (-), 또는 빈 문자열. 부호가 U+002D HYPHEN-MINUS (-)이면 t를 숫자 -1로 둔다. 그렇지 않으면 t를 숫자 1로 둔다.
- 지수: 0개 이상의 숫자. 숫자가 하나 이상 있으면 해당 숫자를 10진수 정수로 해석하여 형성한 수를 e로 둔다. 그렇지 않으면 e를 숫자 0으로 둔다.
숫자 s·(i + f·10-d)·10te를 반환한다.
4.3.14. 잘못된 URL의 나머지 부분 소비
이 절에서는 토크나이저가 <url-token>이 아니라 <bad-url-token>의 중간에 있음을 인식한 후 "정리"하기 위해 코드 포인트 스트림에서 잘못된 URL의 나머지 부분을 소비하는 방법을 설명한다. 아무것도 반환하지 않는다. 유일한 용도는 정상적인 토큰화를 재개할 수 있는 복구 지점에 도달할 만큼 입력 스트림을 소비하는 것이다.
스트림에서 다음 입력 코드 포인트를 반복해서 소비한다:
- U+0029 RIGHT PARENTHESIS ())
- EOF
- 반환한다.
- 입력 스트림이 유효한 이스케이프로 시작
- 이스케이프된 코드 포인트를 소비한다. 이를 통해 이스케이프된 오른쪽 괄호("\)")를 만나도 <bad-url-token>이 끝나지 않는다. 그 밖에는 "그 밖의 모든 것" 절과 동일하다.
- 그 밖의 모든 것
- 아무것도 하지 않는다.
5. 구문 분석
구문 분석 단계의 입력은 토큰화 단계에서 생성된 토큰 스트림 또는 목록이다. 출력은 구문 분석기가 호출되는 방식에 따라 달라지며, 이는 이 절의 뒷부분에 나열된 진입점에서 정의한다. 구문 분석기 출력은 at-규칙, 한정 규칙 및/또는 선언으로 구성될 수 있다.
구문 분석기의 출력은 특정 항목의 유효성과 관계없이 CSS의 기본 구문에 따라 구성된다. 구현은 여러 구문 분석기 알고리즘에서 항목이 반환될 때 그 유효성을 검사하고, 구현 자체의 문법 지식에 따라 항목이 유효하지 않으면 알고리즘이 아무것도 반환하지 않은 것으로 취급하거나, 명시된 대로 전체 트리를 구성한 다음 유효하지 않은 항목을 제거하여 "정리"할 수 있다.
트리에 나타날 수 있는 항목은 다음과 같다:
- at-규칙
-
at-규칙에는 이름,
구성 요소 값 목록으로 이루어진 프렐류드,
단순 {} 블록으로 이루어진 선택적인 블록이 있다.
참고: 이 명세는 at-규칙의 블록에 포함될 수 있는 콘텐츠를 제한하지 않는다. 개별 at-규칙은 블록을 허용하는지, 허용한다면 이를 어떻게 구문 분석하는지 정의해야 한다(가급적 이 명세에서 정의한 구문 분석기 알고리즘이나 진입점 중 하나를 사용한다).
- 한정 규칙
- 한정 규칙에는 구성 요소 값 목록으로 이루어진 프렐류드와 단순 {} 블록으로 이루어진 블록이 있다.
- 선언
-
개념적으로 선언은 속성 또는 설명자 이름을
값과 연결하는 특정 사례이다.
구문상 선언에는 이름,
구성 요소 값 목록으로 이루어진 값,
처음에는 설정되지 않은 important 플래그가 있다.
선언은 다시 속성 선언 또는 설명자 선언으로 분류된다. 전자는 CSS 속성을 설정하고 대부분 한정 규칙에 나타나며, 후자는 CSS 설명자를 설정하고 at-규칙에만 나타난다. (이 분류는 구문 수준에서 이루어지는 것이 아니다. 대신 선언이 나타나는 위치에 따라 이루어지며, 해당 규칙을 정의하는 각 명세에서 정의한다.)
- 구성 요소 값
- 구성 요소 값은 보존된 토큰, 함수 또는 단순 블록 중 하나이다.
- 보존된 토큰
-
토크나이저가 생성한 모든 토큰 중
<function-token>, <{-token>, <(-token>
및 <[-token>을 제외한 토큰.
참고: 위에 나열된 보존되지 않은 토큰은 항상 함수 또는 단순 블록과 같은 상위 수준 객체로 소비되므로 그 자체로는 구문 분석기 출력에 나타나지 않는다.
참고: <}-token>, <)-token>, <]-token>, <bad-string-token> 및 <bad-url-token>은 항상 구문 분석 오류이지만, 이 명세에서는 미디어 쿼리와 같은 다른 명세가 선언 또는 블록 전체를 버리는 것보다 더 세밀한 오류 처리를 정의할 수 있도록 토큰 스트림에서 이를 보존한다.
- 함수
- 함수에는 이름과 구성 요소 값 목록으로 이루어진 값이 있다.
- 단순
블록
- {}-블록
- []-블록
- ()-블록
- {}-블록
- 단순 블록에는 연결된 토큰(<[-token>, <(-token> 또는 <{-token> 중 하나)과 구성 요소 값 목록으로 이루어진 값이 있다.
5.1. 구문 분석기 레일로드 다이어그램
이 절은 비규범적이다.
이 절에서는 구문 분석기를 레일로드 다이어그램 형태로 비규범적으로 보여 준다.
이 다이어그램은 비규범적이며 불완전하다. "올바른" 스타일시트의 문법을 설명하지만 오류 처리는 전혀 설명하지 않는다. 구문을 직관적으로 파악하기 쉽도록 하기 위한 목적으로만 제공된다.
- Stylesheet
-
- Rule list
-
- At-rule
-
- Qualified rule
-
- Declaration list
-
- Declaration
-
- !important
-
- Component value
-
- {} block
-
- () block
-
- [] block
-
- Function block
-
5.2. 정의
- 현재 입력 토큰
- 토크나이저가 생성한 토큰 목록에서 현재 처리 중인 토큰 또는 구성 요소 값.
- 다음 입력 토큰
- 토크나이저가 생성한 토큰 목록에서 현재 입력 토큰 뒤에 오는 토큰 또는 구성 요소 값. 현재 입력 토큰 뒤에 토큰이 없으면 다음 입력 토큰은 <EOF-token>이다.
- <EOF-token>
- 토큰 목록의 끝을 나타내는 개념적인 토큰. 토큰 목록이 비어 있을 때마다 다음 입력 토큰은 항상 <EOF-token>이다.
- 다음 입력 토큰 소비
- 현재 입력 토큰을 현재의 다음 입력 토큰으로 두고, 이에 따라 다음 입력 토큰을 조정한다.
- 현재 입력 토큰을 다시 소비
- 다음에 알고리즘이 다음 입력 토큰을 소비하도록 지시하면, 대신 아무것도 하지 않는다 (현재 입력 토큰을 변경하지 않고 유지한다).
5.3. 구문 분석기 진입점
이 절에서 정의한 알고리즘은 CSS 토큰 목록에서 상위 수준 CSS 객체를 생성한다.
주어진 input을 토큰 스트림으로 정규화하려면:
-
input이 CSS 토큰 목록이면 input을 반환한다.
-
input이 CSS 구성 요소 값 목록이면 input을 반환한다.
참고: 토큰 목록과 구성 요소 값 목록의 유일한 차이점은 함수나 블록처럼 항목을 "포함하는" 일부 객체가 구성 요소 값 목록에서는 하나의 엔터티이지만 토큰 목록에서는 여러 엔터티라는 것이다. 이는 이 명세의 어떤 알고리즘에도 영향을 주지 않는다.
-
input이 문자열이면, input에서 코드 포인트를 필터링하고, 그 결과를 토큰화한 다음 최종 결과를 반환한다.
-
단언: 앞의 유형만 input으로 전달해야 한다.
참고: 다른 명세는 자체 목적에 필요한 추가 진입점을 정의할 수 있다.
- "스타일시트 구문 분석"은 스타일시트를 구문 분석하는 일반적인 구문 분석기 진입점으로 사용하기 위한 것이다.
- "규칙 목록 구문 분석"은 @media와 같은 at-규칙의 콘텐츠를 위한 것이다. <CDO-token> 및 <CDC-token> 처리 방식이 "스타일시트 구문 분석"과 다르다.
- "규칙 구문 분석"은
CSSStyleSheet#insertRule메서드와 텍스트를 하나의 규칙으로 구문 분석하는 유사한 함수를 위한 것이다. - "선언 구문 분석"은 @supports 조건에서 사용된다. [CSS3-CONDITIONAL]
- "선언 목록 구문 분석"은
텍스트를 하나의 스타일 규칙 콘텐츠로 구문 분석하는
style속성의 콘텐츠를 위한 것이다. - "구성 요소 값 구문 분석"은 attr()의 구문 분석 규칙처럼 하나의 값을 소비해야 하는 경우를 위한 것이다.
- "구성 요소 값 목록 구문 분석"은
텍스트를 하나의 선언 값으로 구문 분석하는
표현 속성의 콘텐츠,
독립적인 선택자 [SELECT]
또는 미디어 쿼리 목록 [MEDIAQ]을 구문 분석하기 위한 것으로,
선택자 API 또는
mediaHTML 속성에서 사용되는 경우와 같다.
5.3.1. CSS 문법에 따라 무언가를 구문 분석
문자열이나 토큰 목록이 특정 CSS 문법과 일치하는지 확인하고, 일치한다면 해당 문법에 따라 이를 구조 분해하는 것이 필요한 경우가 많다. 이 절에서는 이러한 작업을 위한 일반적인 연결 지점을 제공한다. "foo를 CSS <color>로 구문 분석"과 같이 또는 이와 유사하게 호출해야 한다.
이 알고리즘은 입력이 제공된 문법과 일치하지 않으면 실패를 반환하고, 일치하면 문법에 따라 입력을 구문 분석한 결과를 반환한다. 이 결과는 제공된 문법 명세에 대응하는 명시되지 않은 구조이다. 반환 값은 표현의 모호성이 문제가 되지 않는 명세 문구에서만 다뤄야 한다. 명세 언어 외부에 노출하려는 경우 결과를 사용하는 명세는 이를 명확히 정의된 표현으로 명시적으로 변환해야 한다. 예를 들어 CSS 직렬화 알고리즘을 호출할 수 있다 (예: "CSS <string> 값으로 직렬화").
참고: 이 알고리즘과 CSS 문법에 따라 쉼표로 구분된 목록 구문 분석은 다른 명세에서 호출하려는 유일한 구문 분석 알고리즘인 경우가 대부분이다. 나머지 구문 분석 알고리즘은 주로 [CSSOM] 및 관련된 "CSS 구조를 명시적으로 구성하는" 경우를 위한 것이다. 다른 알고리즘 중 하나를 사용해야 한다고 생각한다면 먼저 CSSWG에 지침을 문의한다.
- input을 정규화하고 input을 그 결과로 설정한다.
- input에서 구성 요소 값 목록을 구문 분석하고 반환 값을 result로 둔다.
- result를 grammar와 일치시키려고 시도한다. 성공하면 일치한 결과를 반환한다. 그렇지 않으면 실패를 반환한다.
5.3.2. CSS 문법에 따라 쉼표로 구분된 목록 구문 분석
쉼표가 포함된 문법에 따라 값을 구문 분석할 수는 있지만, 값의 어느 부분이라도 구문 분석에 실패하면 전체를 구문 분석할 수 없으며 실패를 반환한다.
때로는 이것이 원하는 동작이지만
(목록 값을 갖는 CSS 속성 등),
다른 경우에는 값에서 쉼표로 구분된 각 하위 부분을 별도로 구문 분석하여
구문 분석에 성공한 부분은 한 방식으로 처리하고
실패한 부분은 다른 방식으로 처리하는 것이 더 낫다
(일반적으로 이를 무시한다.
예를 들면
<img sizes>에서와
같다).
이 알고리즘은 이를 정확히 수행하기 위한 간편한 연결 지점을 제공한다. "최상위 수준" 쉼표로 분할된 값 목록을 반환하며, 각 값은 실패 (구문 분석에 실패한 경우) 또는 구문 분석 결과 (구문 분석 알고리즘에서 설명한 명시되지 않은 구조)이다.
- input을 정규화하고 input을 그 결과로 설정한다.
- input에 <whitespace-token>만 포함되어 있으면 빈 목록을 반환한다.
- input에서 쉼표로 구분된 구성 요소 값 목록을 구문 분석하고 반환 값을 list로 둔다.
- list의 각 item에 대해, item을 grammar로 구문 분석한 결과로 item을 대체한다.
- list를 반환한다.
5.3.3. 스타일시트 구문 분석
5.3.4. 규칙 목록 구문 분석
5.3.5. 규칙 구문 분석
- input을 정규화하고 input을 그 결과로 설정한다.
- input의 다음 입력 토큰이 <whitespace-token>인 동안, input에서 다음 입력 토큰을 소비한다.
-
input의 다음
입력
토큰이 <EOF-token>이면
구문 오류를 반환한다.
그렇지 않고 input의 다음 입력 토큰이 <at-keyword-token>이면, input에서 at-규칙을 소비하고 반환 값을 rule로 둔다.
그렇지 않으면 input에서 한정 규칙을 소비하고 반환 값을 rule로 둔다. 아무것도 반환되지 않았다면 구문 오류를 반환한다.
- input의 다음 입력 토큰이 <whitespace-token>인 동안, input에서 다음 입력 토큰을 소비한다.
- input의 다음 입력 토큰이 <EOF-token>이면 rule을 반환한다. 그렇지 않으면 구문 오류를 반환한다.
5.3.6. 선언 구문 분석
참고: "선언 목록 구문 분석"과 달리, 이는 at-규칙이 아닌 선언만 구문 분석한다.
- input을 정규화하고 input을 그 결과로 설정한다.
- input의 다음 입력 토큰이 <whitespace-token>인 동안, 다음 입력 토큰을 소비한다.
- input의 다음 입력 토큰이 <ident-token>이 아니면 구문 오류를 반환한다.
- input에서 선언을 소비한다. 무언가가 반환되었다면 이를 반환한다. 그렇지 않으면 구문 오류를 반환한다.
5.3.7. 스타일 블록의 콘텐츠 구문 분석
참고: 이 알고리즘은 중첩된 스타일 규칙과 기타 at-규칙을 허용해야 하는 스타일 규칙의 콘텐츠를 구문 분석한다. @page 또는 @keyframes 자식 규칙에서처럼 중첩된 스타일 규칙이 필요하지 않으면 선언 목록 구문 분석을 사용한다.
- input을 정규화하고 input을 그 결과로 설정한다.
- input에서 스타일 블록의 콘텐츠를 소비하고 결과를 반환한다.
5.3.8. 선언 목록 구문 분석
참고: 이름과 달리 이는 CSS 2.1이 @page에서 수행하는 것처럼 선언과 at-규칙이 혼합된 목록을 실제로 구문 분석한다. 예상하지 않은 at-규칙은(주어진 컨텍스트에서는 모든 at-규칙일 수도 있다) 유효하지 않으며 소비자가 무시한다.
참고: 이 알고리즘은 중첩된 스타일 규칙을 처리하지 않는다. 이러한 처리가 필요하면 스타일 블록의 콘텐츠 구문 분석을 사용한다.
5.3.9. 구성 요소 값 구문 분석
- input을 정규화하고 input을 그 결과로 설정한다.
- input의 다음 입력 토큰이 <whitespace-token>인 동안, input에서 다음 입력 토큰을 소비한다.
- input의 다음 입력 토큰이 <EOF-token>이면 구문 오류를 반환한다.
- input에서 구성 요소 값을 소비하고 반환 값을 value로 둔다.
- input의 다음 입력 토큰이 <whitespace-token>인 동안, 다음 입력 토큰을 소비한다.
- input의 다음 입력 토큰이 <EOF-token>이면 value를 반환한다. 그렇지 않으면 구문 오류를 반환한다.
5.3.10. 구성 요소 값 목록 구문 분석
- input을 정규화하고 input을 그 결과로 설정한다.
- <EOF-token>이 반환될 때까지 input에서 구성 요소 값을 반복해서 소비하고, 반환된 값을 목록에 추가한다(마지막 <EOF-token>은 제외한다). 목록을 반환한다.
5.3.11. 쉼표로 구분된 구성 요소 값 목록 구문 분석
- input을 정규화하고 input을 그 결과로 설정한다.
- 처음에 list of cvls를 구성 요소 값 목록으로 이루어진 빈 목록으로 둔다.
-
<EOF-token> 또는 <comma-token>이 반환될 때까지 input에서
구성
요소 값을 반복해서 소비하고,
반환된 값을 목록에 추가한다(마지막 <EOF-token>
또는 <comma-token>은 제외한다).
해당 목록을 list of cvls에 추가한다.
반환된 것이 <comma-token>이면 이 단계를 반복한다.
- list of cvls를 반환한다.
5.4. 구문 분석기 알고리즘
다음 알고리즘은 구문 분석기를 구성한다. 위의 구문 분석기 진입점에서 이 알고리즘을 호출한다.
이 알고리즘은 토큰 목록이나 구성 요소 값 목록을 사용하여 호출할 수 있다. (구성 요소 값 목록에서는 일부 토큰이 함수와 단순 블록으로 대체된다는 점이 다르다.) 토큰화 단계에서 입력 스트림이 비어 있음을 나타내기 위해 EOF 코드 포인트를 반환했던 것과 마찬가지로, 이 단계의 목록도 다음 토큰을 요청했지만 목록이 비어 있으면 <EOF-token>을 반환해야 한다.
특정 목록을 사용하여 알고리즘을 호출할 수 있으며, 이 경우 해당 목록만 소비한다 (해당 목록이 소진되면 <EOF-token>을 반환하기 시작한다). 그렇지 않으면 호출한 알고리즘과 같은 목록을 사용해 암시적으로 호출된다.
5.4.1. 규칙 목록 소비
top-level flag가 주어졌을 때 규칙 목록을 소비하려면:
처음에 빈 규칙 목록을 생성한다.
다음 입력 토큰을 반복해서 소비한다:
- <whitespace-token>
- 아무것도 하지 않는다.
- <EOF-token>
- 규칙 목록을 반환한다.
- <CDO-token>
- <CDC-token>
-
top-level flag가 설정되어 있으면
아무것도 하지 않는다.
그렇지 않으면 현재 입력 토큰을 다시 소비한다. 한정 규칙을 소비한다. 무언가가 반환되었다면 규칙 목록에 추가한다.
- <at-keyword-token>
- 현재 입력 토큰을 다시 소비한다. at-규칙을 소비하고 반환된 값을 규칙 목록에 추가한다.
- 그 밖의 모든 것
- 현재 입력 토큰을 다시 소비한다. 한정 규칙을 소비한다. 무언가가 반환되었다면 규칙 목록에 추가한다.
5.4.2. at-규칙 소비
at-규칙을 소비하려면:
다음 입력 토큰을 소비한다. 이름이 현재 입력 토큰의 값으로 설정되고, 프렐류드가 처음에는 빈 목록으로 설정되며, 값이 처음에는 없음으로 설정된 새 at-규칙을 생성한다.
다음 입력 토큰을 반복해서 소비한다:
- <semicolon-token>
- at-규칙을 반환한다.
- <EOF-token>
- 이는 구문 분석 오류이다. at-규칙을 반환한다.
- <{-token>
- 단순 블록을 소비하여 at-규칙의 블록에 할당한다. at-규칙을 반환한다.
- 단순 블록이며 연결된 토큰이 <{-token>인 경우
- 해당 블록을 at-규칙의 블록에 할당한다. at-규칙을 반환한다.
- 그 밖의 모든 것
- 현재 입력 토큰을 다시 소비한다. 구성 요소 값을 소비한다. 반환된 값을 at-규칙의 프렐류드에 추가한다.
5.4.3. 한정 규칙 소비
한정 규칙을 소비하려면:
프렐류드가 처음에는 빈 목록으로 설정되고 값이 처음에는 없음으로 설정된 새 한정 규칙을 생성한다.
다음 입력 토큰을 반복해서 소비한다:
- <EOF-token>
- 이는 구문 분석 오류이다. 아무것도 반환하지 않는다.
- <{-token>
- 단순 블록을 소비하여 한정 규칙의 블록에 할당한다. 한정 규칙을 반환한다.
- 단순 블록이며 연결된 토큰이 <{-token>인 경우
- 해당 블록을 한정 규칙의 블록에 할당한다. 한정 규칙을 반환한다.
- 그 밖의 모든 것
- 현재 입력 토큰을 다시 소비한다. 구성 요소 값을 소비한다. 반환된 값을 한정 규칙의 프렐류드에 추가한다.
5.4.4. 스타일 블록의 콘텐츠 소비
스타일 블록의 콘텐츠를 소비하려면:
처음에 빈 선언 목록 decls와 처음에 빈 규칙 목록 rules를 생성한다.
다음 입력 토큰을 반복해서 소비한다:
- <whitespace-token>
- <semicolon-token>
- 아무것도 하지 않는다.
- <EOF-token>
- decls를 rules로 확장한 다음 decls를 반환한다.
- <at-keyword-token>
- 현재 입력 토큰을 다시 소비한다. at-규칙을 소비하고 결과를 rules에 추가한다.
- <ident-token>
- 처음에 현재 입력 토큰으로 채운 임시 목록을 초기화한다. 다음 입력 토큰이 <semicolon-token> 또는 <EOF-token>이 아닌 동안 구성 요소 값을 소비하여 임시 목록에 추가한다. 임시 목록에서 선언을 소비한다. 무언가가 반환되었다면 decls에 추가한다.
- 값이 "&"(U+0026 AMPERSAND)인 <delim-token>
- 현재 입력 토큰을 다시 소비한다. 한정 규칙을 소비한다. 무언가가 반환되었다면 rules에 추가한다.
- 그 밖의 모든 것
- 이는 구문 분석 오류이다. 현재 입력 토큰을 다시 소비한다. 다음 입력 토큰이 <semicolon-token> 또는 <EOF-token>이 아닌 동안 구성 요소 값을 소비하고 반환된 값을 버린다.
5.4.5. 선언 목록 소비
선언 목록을 소비하려면:
처음에 빈 선언 목록을 생성한다.
다음 입력 토큰을 반복해서 소비한다:
- <whitespace-token>
- <semicolon-token>
- 아무것도 하지 않는다.
- <EOF-token>
- 선언 목록을 반환한다.
- <at-keyword-token>
- 현재 입력 토큰을 다시 소비한다. at-규칙을 소비한다. 반환된 규칙을 선언 목록에 추가한다.
- <ident-token>
- 처음에 현재 입력 토큰으로 채운 임시 목록을 초기화한다. 다음 입력 토큰이 <semicolon-token> 또는 <EOF-token>이 아닌 동안 구성 요소 값을 소비하여 임시 목록에 추가한다. 임시 목록에서 선언을 소비한다. 무언가가 반환되었다면 선언 목록에 추가한다.
- 그 밖의 모든 것
- 이는 구문 분석 오류이다. 현재 입력 토큰을 다시 소비한다. 다음 입력 토큰이 <semicolon-token> 또는 <EOF-token>이 아닌 동안 구성 요소 값을 소비하고 반환된 값을 버린다.
5.4.6. 선언 소비
참고: 이 알고리즘은 다음 입력 토큰이 <ident-token>인지 이미 확인되었다고 가정한다.
선언을 소비하려면:
다음 입력 토큰을 소비한다. 이름이 현재 입력 토큰의 값으로 설정되고 값이 처음에는 빈 목록으로 설정된 새 선언을 생성한다.
- 다음 입력 토큰이 <whitespace-token>인 동안, 다음 입력 토큰을 소비한다.
-
다음 입력
토큰이 <colon-token>이 아니면
이는 구문 분석 오류이다.
아무것도 반환하지 않는다.
그렇지 않으면 다음 입력 토큰을 소비한다.
- 다음 입력 토큰이 <whitespace-token>인 동안, 다음 입력 토큰을 소비한다.
- 다음 입력 토큰이 <EOF-token>이 아닌 동안, 구성 요소 값을 소비하여 선언의 값에 추가한다.
- 선언 값에서 마지막 두 개의 비<whitespace-token>이 값이 "!"인 <delim-token>과 값이 "important"와 ASCII 대소문자 구분 없이 일치하는 <ident-token> 순서이면, 선언의 값에서 이를 제거하고 선언의 important 플래그를 true로 설정한다.
- 선언 값의 마지막 토큰이 <whitespace-token>인 동안 해당 토큰을 제거한다.
- 선언을 반환한다.
5.4.7. 구성 요소 값 소비
구성 요소 값을 소비하려면:
다음 입력 토큰을 소비한다.
현재 입력 토큰이 <{-token>, <[-token> 또는 <(-token>이면, 단순 블록을 소비하고 반환한다.
그렇지 않고 현재 입력 토큰이 <function-token>이면, 함수를 소비하고 반환한다.
그렇지 않으면 현재 입력 토큰을 반환한다.
5.4.8. 단순 블록 소비
참고: 이 알고리즘은 현재 입력 토큰이 <{-token>, <[-token> 또는 <(-token>인지 이미 확인되었다고 가정한다.
단순 블록을 소비하려면:
종료 토큰은 현재 입력 토큰의 대칭 형태이다. (예를 들어 <[-token>을 사용해 호출했다면, 종료 토큰은 <]-token>이다.)
연결된 토큰이 현재 입력 토큰으로 설정되고 값이 처음에는 빈 목록으로 설정된 단순 블록을 생성한다.
다음 입력 토큰을 반복해서 소비하고 다음과 같이 처리한다:
- 종료 토큰
- 블록을 반환한다.
- <EOF-token>
- 이는 구문 분석 오류이다. 블록을 반환한다.
- 그 밖의 모든 것
- 현재 입력 토큰을 다시 소비한다. 구성 요소 값을 소비하여 블록의 값에 추가한다.
참고: CSS에는 선언을 포함할 수 있는 블록과 한정 규칙을 포함할 수 있는 블록 사이에 불편한 구문적 모호성이 있다. 따라서 규칙을 처리하는 모든 "소비" 알고리즘은 처음에 더 구체적인 선언 목록 소비 또는 규칙 목록 소비 알고리즘 대신 이보다 일반적인 알고리즘을 사용한다. 이러한 더 구체적인 알고리즘은 문법이 적용될 때, 문법에 <declaration-list> 또는 <rule-list>/<stylesheet>이 포함되는지에 따라 호출된다.
5.4.9. 함수 소비
참고: 이 알고리즘은 현재 입력 토큰이 <function-token>인지 이미 확인되었다고 가정한다.
함수를 소비하려면:
이름이 현재 입력 토큰의 값과 같고 값이 처음에는 빈 목록으로 설정된 함수를 생성한다.
다음 입력 토큰을 반복해서 소비하고 다음과 같이 처리한다:
- <)-token>
- 함수를 반환한다.
- <EOF-token>
- 이는 구문 분석 오류이다. 함수를 반환한다.
- 그 밖의 모든 것
- 현재 입력 토큰을 다시 소비한다. 구성 요소 값을 소비하고 반환된 값을 함수의 값에 추가한다.
6. An+B 마이크로 구문
CSS의 여러 기능은 :nth-child() 의사 클래스처럼 목록의 인덱스를 나타내야 한다. An+B 마이크로 구문은 이를 위해 유용하며, 작성자가 하나의 요소나 목록에서 일정한 간격으로 나타나는 모든 요소를 쉽게 지정할 수 있게 한다.
An+B 표기법은 정수 간격(A)과 오프셋(B)을 정의하고, n의 모든 양의 정수 또는 0 값에 대해 목록에서 An+B번째 요소를 나타낸다. 목록의 첫 번째 요소는 인덱스 0이 아니라 1을 갖는다.
A와 B의 값이 0보다 크면, 이는 실질적으로 목록을 A개 요소로 이루어진 그룹으로 나누고 (마지막 그룹은 나머지 요소를 포함한다), 각 그룹의 B번째 요소를 선택한다.
An+B 표기법은 even 및 odd 키워드도 허용하며, 각각 2n 및 2n+1과 같은 의미를 갖는다.
A와 B의 값은 음수일 수 있지만, n ≥ 0일 때 An+B의 양수 결과만 사용된다.
A와 B가 모두 0이면, 의사 클래스는 목록의 어떤 요소도 나타내지 않는다.
6.1. 비공식 구문 설명
이 절은 비규범적이다.
A가 0이면 An 부분을 생략할 수 있다 (B 부분이 이미 생략된 경우는 제외한다). An이 포함되지 않고 B가 음수가 아니면, B 앞의 + 기호도(허용되는 경우) 생략할 수 있다. 이 경우 구문은 B로만 단순화된다.
A가 1 또는 -1이면
규칙에서 1을 생략할 수 있다.
B가 0이면 모든 A번째 요소가 선택된다. 이 경우 A 부분이 이미 생략되지 않았다면 +B(또는 -B) 부분을 생략할 수 있다.
B가 음수이면 음수 부호가 + 기호를 대체한다.
An과 B 부분이 모두 있을 때 이를 구분하는 + 또는 -의 양쪽에는 공백을 사용할 수 있다.
6.2. <an+b> 타입
An+B 표기법은 원래 CSS의 나머지 부분과 약간 다른 토크나이저를 사용하여 정의되었기 때문에, CSS 토큰으로 표현하면 다소 특이한 정의가 된다. 이 절에서는 CSS 토큰으로 An+B 표기법을 인식하는 방법 (따라서 CSS 문법을 위한 <an+b> 타입을 정의하는 방법)과 CSS 토큰을 해석하여 A와 B의 값을 얻는 방법을 설명한다.
<an+b> 타입은 (값 및 단위 명세의 값 정의 구문을 사용하여) 다음과 같이 정의된다:
<an+b> = odd | even | <integer> | <n-dimension> | '+'?† n | -n | <ndashdigit-dimension> | '+'?† <ndashdigit-ident> | <dashndashdigit-ident> | <n-dimension> <signed-integer> | '+'?† n <signed-integer> | -n <signed-integer> | <ndash-dimension> <signless-integer> | '+'?† n- <signless-integer> | -n- <signless-integer> | <n-dimension> ['+' | '-'] <signless-integer> '+'?† n ['+' | '-'] <signless-integer> | -n ['+' | '-'] <signless-integer>
여기서:
<n-dimension>은 유형 플래그가 "integer"로 설정되고 단위가 "n"과 ASCII 대소문자 구분 없이 일치하는 <dimension-token>이다.<ndash-dimension>은 유형 플래그가 "integer"로 설정되고 단위가 "n-"과 ASCII 대소문자 구분 없이 일치하는 <dimension-token>이다.<ndashdigit-dimension>은 유형 플래그가 "integer"로 설정되고 단위가 "n-*"와 ASCII 대소문자 구분 없이 일치하는 <dimension-token>이며, 여기서 "*"는 하나 이상의 숫자로 이루어진 시퀀스이다.<ndashdigit-ident>은 값이 "n-*"와 ASCII 대소문자 구분 없이 일치하는 <ident-token>이며, 여기서 "*"는 하나 이상의 숫자로 이루어진 시퀀스이다.<dashndashdigit-ident>은 값이 "-n-*"와 ASCII 대소문자 구분 없이 일치하는 <ident-token>이며, 여기서 "*"는 하나 이상의 숫자로 이루어진 시퀀스이다.<integer>는 유형 플래그가 "integer"로 설정된 <number-token>이다.<signed-integer>는 유형 플래그가 "integer"로 설정되고 표현이 "+" 또는 "-"로 시작하는 <number-token>이다.<signless-integer>는 유형 플래그가 "integer"로 설정되고 표현이 숫자로 시작하는 <number-token>이다.
†: 위에 표시된 경우와 같이 더하기 기호(+)가 "n"으로 시작하는 ident 앞에 오면 두 토큰 사이에 공백이 없어야 한다. 그렇지 않으면 토큰이 위 문법과 일치하지 않는다. 그 밖의 두 토큰 사이에서는 공백이 유효하며 무시된다.
생성 규칙의 각 절은 다음과 같이 해석한다:
- odd
- A는 2이고 B는 1이다.
- even
- A는 2이고 B는 0이다.
<integer>- A는 0이고 B는 정수의 값이다.
<n-dimension>'+'? n-n- A는 각각 dimension의 값, 1 또는 -1이다. B는 0이다.
<ndashdigit-dimension>'+'? <ndashdigit-ident>- A는 각각 dimension의 값 또는 1이다. B는 각각 dimension의 단위 또는 ident의 값에서 첫 번째 코드 포인트를 제거하고 나머지를 10진수로 해석한 값이다. B는 음수이다.
<dashndashdigit-ident>- A는 -1이다. B는 ident의 값에서 처음 두 코드 포인트를 제거하고 나머지를 10진수로 해석한 값이다. B는 음수이다.
<n-dimension> <signed-integer>'+'? n <signed-integer>-n <signed-integer>- A는 각각 dimension의 값, 1 또는 -1이다. B는 정수의 값이다.
<ndash-dimension> <signless-integer>'+'? n- <signless-integer>-n- <signless-integer>- A는 각각 dimension의 값, 1 또는 -1이다. B는 정수 값의 부정값이다.
<n-dimension> ['+' | '-'] <signless-integer>'+'? n ['+' | '-'] <signless-integer>-n ['+' | '-'] <signless-integer>- A는 각각 dimension의 값, 1 또는 -1이다. B는 정수의 값이다.
둘 사이에
'-'가 제공되었다면 B는 대신 정수 값의 부정값이다.
7. Unicode-Range 마이크로 구문
@font-face 규칙의 unicode-range 설명자와 같은 일부 구문에는 하나 이상의 Unicode 코드 포인트를 설명할 방법이 필요하다. <urange> 생성 규칙은 하나 이상의 Unicode 코드 포인트 범위를 나타낸다.
비공식적으로 <urange> 생성 규칙에는 세 가지 형태가 있다:
- U+0001
- 하나의 코드 포인트로 이루어진 범위를 정의하며, 여기서는 코드 포인트 "1"이다.
- U+0001-00ff
- 첫 번째 값 이상 두 번째 값 이하의 코드 포인트 범위를 정의하며, 여기서는 "1" 이상 "ff"(10진수로 255) 이하의 범위이다.
- U+00??
- "?" 문자가 모든 16진수 숫자에 걸치는 코드 포인트 범위를 정의하며, 여기서는 U+0000-00ff 값과 같은 범위를 정의한다.
각 형태에서 각각의 16진수에는 최대 6개의 숫자를 사용할 수 있다 ("?"를 16진수 숫자로 취급하는 경우).
7.1. <urange> 타입
<urange> 표기법은 원래 CSS에서 원시 토큰으로 정의되었지만, 거의 사용되지 않으며 적법한 <ident-token>과 혼란스러운 방식으로 충돌한다. 이 절에서는 기존 CSS 토큰으로 <urange> 표기법을 인식하는 방법과 이를 Unicode 코드 포인트 범위로 해석하는 방법을 설명한다.
혼동을 일으키는 충돌이란 무엇인가?
예를 들어 CSS u + a { color: green;
}에서
의도한 의미는 u 요소 뒤에 오는
a 요소의 색상을
녹색으로 지정하는 것이다.
일반적으로 결합자와
그 주위의 선택자 사이에는 공백이 필요하지 않으므로,
다음과 같이 축소해도 동등해야 한다.
다른 결합자라면 두 CSS 조각은 동등하지만, 이전에 특수한 unicode-range 토큰이 존재했기 때문에 축소된 코드의 선택자 부분에는 이제 두 ident와 결합자가 아니라 unicode-range가 포함된다. 따라서 선택자 문법과 일치하지 않으며 규칙은 유효하지 않은 것으로 폐기된다.
(이 예는 Firefox에 보고된 실제 버그에서 가져왔다.)
참고: 여기에 설명된 구문은 의도적으로 매우 저수준이며 구현자를 대상으로 한다. 작성자는 필요한 모든 정보가 들어 있고 실제로 읽을 수 있는 이전 절의 비공식 구문 설명을 대신 참조하여 <urange>를 사용해야 한다.
<urange> 타입은 (값 및 단위 명세의 값 정의 구문을 사용하여) 다음과 같이 정의된다:
<urange> = u '+' <ident-token> '?'* | u <dimension-token> '?'* | u <number-token> '?'* | u <number-token> <dimension-token> | u <number-token> <number-token> | u '+' '?'+
이 생성 규칙에서는 토큰 사이에 공백이 올 수 없다.
<urange> 생성 규칙은 하나 이상의 연속된 Unicode 코드 포인트 범위를 음이 아닌 정수인 start value와 end value로 나타낸다. 위 생성 규칙을 범위로 해석하려면 다음 단계를 순서대로 실행한다:
-
첫 번째 u 토큰을 건너뛰고 생성 규칙에 있는 모든 토큰의 표현을 서로 연결한다. 이를 text로 둔다.
-
text의 첫 번째 문자가 U+002B PLUS SIGN이면 이를 소비한다. 그렇지 않으면 이는 유효하지 않은 <urange>이며 이 알고리즘을 종료해야 한다.
-
text에서 가능한 한 많은 16진수 숫자를 소비한다. 그런 다음 가능한 한 많은 U+003F QUESTION MARK (?) 코드 포인트를 소비한다. 소비된 코드 포인트가 0개이거나 6개를 초과하는 코드 포인트가 소비되었다면 이는 유효하지 않은 <urange>이며 이 알고리즘을 종료해야 한다.
U+003F QUESTION MARK (?) 코드 포인트가 하나라도 소비되었다면 다음을 수행한다:
-
text에 코드 포인트가 남아 있으면, 이는 유효하지 않은 <urange>이며 이 알고리즘을 종료해야 한다.
-
소비된 코드 포인트를 16진수로 해석하되, U+003F QUESTION MARK (?) 코드 포인트를 U+0030 DIGIT ZERO (0) 코드 포인트로 대체한다. 이것이 start value이다.
-
소비된 코드 포인트를 다시 16진수로 해석하되, U+003F QUESTION MARK (?) 코드 포인트를 U+0046 LATIN CAPITAL LETTER F (F) 코드 포인트로 대체한다. 이것이 end value이다.
-
이 알고리즘을 종료한다.
그렇지 않으면 소비된 코드 포인트를 16진수로 해석한다. 이것이 start value이다.
-
-
text에 코드 포인트가 남아 있지 않으면 end value는 start value와 같다. 이 알고리즘을 종료한다.
-
text의 다음 코드 포인트가 U+002D HYPHEN-MINUS (-)이면 이를 소비한다. 그렇지 않으면 이는 유효하지 않은 <urange>이며 이 알고리즘을 종료해야 한다.
-
text에서 가능한 한 많은 16진수 숫자를 소비한다.
소비된 16진수 숫자가 0개이거나 6개를 초과하는 16진수 숫자가 소비되었다면 이는 유효하지 않은 <urange>이며 이 알고리즘을 종료해야 한다. text에 코드 포인트가 남아 있으면, 이는 유효하지 않은 <urange>이며 이 알고리즘을 종료해야 한다.
-
소비된 코드 포인트를 16진수로 해석한다. 이것이 end value이다.
<urange>가 나타내는 코드 포인트를 결정하려면:
-
end value가 허용되는 최대 코드 포인트보다 크면 <urange>는 유효하지 않으며 구문 오류이다.
-
start value가 end value보다 크면 <urange>는 유효하지 않으며 구문 오류이다.
-
그렇지 않으면 <urange>는 start value 이상 end value 이하의 연속된 코드 포인트 범위를 나타낸다.
참고: <urange>의 구문은 의도적으로 상당히 넓다. 해당 패턴은 비공식 구문에서 생성할 수 있는 모든 토큰 시퀀스를 포착한다. 그러나 구성 토큰 사이에는 공백을 허용하지 않으므로 실제로 사용하기에 상당히 안전하다. <urange> 뒤에 <number> 또는 <dimension>이 오는 문법도 (작성자가 ''u <number>'' 절을 사용해 <urange>를 지정하면 모호해 보일 수 있지만) 실제로는 상당히 안전하다. 모호해지려면 작성자가 공백 대신 주석을 사용하여 의도적으로 <urange>와 <number>/<dimension>을 구분해야 하기 때문이다. 따라서 작성자가 혼란스러운 방식으로 구문 분석되는 내용을 작성하는 것이 가능하기는 하지만, 혼란을 일으키기 위해 실제로 작성해야 하는 코드 자체가 혼란스럽고 드물다.
8. 규칙 및 기타 값의 문법 정의
값 명세는 속성의 문법을 지정하는 방법을 정의한다. 이 절에서는 규칙을 대상으로 같은 작업을 수행한다.
속성 문법에서와 마찬가지로
<foo> 표기법은 다른 곳에서 정의되었다고 가정하는
"foo" 문법 용어를 나타낸다.
<foo>를 해당 정의로 대체하면 의미상 동일한 문법이 된다.
여러 유형의 토큰은 따옴표 없이 리터럴로 작성한다:
- <ident-token>(예:
auto,disc등)은 단순히 해당 값으로 작성한다. - <at-keyword-token>은 @ 문자 뒤에
@media와 같이 토큰의 값을 붙여 작성한다. - <function-token>은
translate(와 같이 함수 이름 뒤에 ( 문자를 붙여 작성한다. - <colon-token>(
:로 작성), <comma-token>(,로 작성), <semicolon-token>(;로 작성), <(-token>, <)-token>, <{-token> 및 <}-token>.
토큰의 값이 문법에서 정의한 값과 일치하면 해당 토큰이 일치한다. 달리 명시하지 않는 한 모든 일치는 ASCII 대소문자를 구분하지 않는다.
참고: 이스케이프를 사용하면
값이 (로 끝나거나 @로 시작하는 <ident-token>을 만들 수 있지만,
이러한 토큰은 <function-token>이나 <at-keyword-token>이 아니며
대응하는 문법 정의와 일치하지 않는다.
<delim-token>은 값을 작은따옴표로 묶어 작성한다.
예를 들어 "+" 코드 포인트를 포함하는 <delim-token>은
'+'로 작성한다.
마찬가지로 <[-token>과 <]-token>도
문법 자체의 구문에서 절을 그룹화하는 데 사용되므로
작은따옴표로 작성해야 한다.
<whitespace-token>은 문법에 표시하지 않는다.
<whitespace-token>은
문구로 된 정의에서 달리 명시하지 않는 한
모든 토큰의 앞, 뒤 및 두 토큰 사이에서 허용된다.
(예를 들어 규칙의 프렐류드가 선택자이면
공백은 의미가 있다.)
함수나 블록을 정의할 때는 문법에 종료 토큰을 지정해야 하지만, 최종 토큰 스트림에 존재하지 않더라도 여전히 일치한다.
translateX( <translation-value> )
그러나 스타일시트는 다음과 같이 함수가 닫히지 않은 상태로 끝날 수 있다:
.foo { transform: translate(50px
CSS 구문 분석기는 이를 하나의 선언을 포함하는 스타일 규칙으로 구문 분석하며, 해당 선언의 값은 이름이 "translate"인 함수이다. 종료 토큰이 토큰 스트림에 나타나지 않았더라도 이는 위 문법과 일치한다. 구문 분석기가 완료될 때는 종료 토큰의 존재 여부를 더 이상 확인할 수 없으며, 블록과 함수가 있다는 사실만 알 수 있기 때문이다.
8.1. 블록 콘텐츠 정의: <declaration-list>, <rule-list> 및 <stylesheet> 생성 규칙
CSS 구문 분석기는 일부 at-규칙의 끝에 오는 블록과 같은 블록의 콘텐츠를 구분하지 않는다. 토큰을 사용해 블록의 일반 문법을 정의하는 것은 간단하지 않지만, 이를 구문 분석하기 위한 전용의 명확한 알고리즘이 정의되어 있다.
<style-block> 생성 규칙은 스타일 규칙 블록의 콘텐츠를 나타낸다. 문법에서 블록의 유일한 값으로만 사용할 수 있으며, 블록의 콘텐츠를 스타일 블록의 콘텐츠 소비 알고리즘으로 구문 분석해야 함을 나타낸다.
<declaration-list> 생성 규칙은 선언 목록을 나타낸다. 문법에서 블록의 유일한 값으로만 사용할 수 있으며, 블록의 콘텐츠를 선언 목록 소비 알고리즘으로 구문 분석해야 함을 나타낸다.
마찬가지로 <rule-list> 생성 규칙은 규칙 목록을 나타내며 문법에서 블록의 유일한 값으로만 사용할 수 있다. 블록의 콘텐츠를 규칙 목록 소비 알고리즘으로 구문 분석해야 함을 나타낸다.
마지막으로 <stylesheet> 생성 규칙은 규칙 목록을 나타낸다. <rule-list>과 동일하지만, 이를 사용하는 블록은 기본적으로 특정 컨텍스트로 달리 제한되지 않은 모든 규칙을 허용한다.
| 선언 허용 | 중첩된 스타일 규칙 허용 | 임의의 한정 규칙 허용 | at-규칙 허용 | 예 | |
|---|---|---|---|---|---|
| <style-block> | ✓ | ✓ | ✗ | ✓ | 스타일 규칙, @nest, 중첩된 조건부 그룹 규칙 |
| <declaration-list> | ✓ | ✗ | ✗ | ✓ | @font, @counter-style, @page, @keyframes 자식 규칙 |
| <rule-list> | ✗ | ✗ | ✓ | ✓ | @keyframes, @font-feature-values |
| <stylesheet> | ✗ | ✗ | ✓ | ✓ | 스타일시트, 중첩되지 않은 조건부 그룹 규칙 |
주어진 컨텍스트가 @font-features-values에서처럼 at-규칙만 허용하려는 경우, 실제로 어떤 생성 규칙을 사용하는지는 중요하지 않지만 이름이 더 직관적인 <rule-list>이 권장된다.
@font-face { <declaration-list> }
이는 규칙 문법의 완전하고 충분한 정의이다.
다른 예로 @keyframes 규칙은 더 복잡하며, 프렐류드를 이름으로 해석하고 블록에 키프레임 규칙을 포함한다. 문법은 다음과 같다:
@keyframes <keyframes-name> { <rule-list> }
<style-block> 또는 <declaration-list>을 사용하는 규칙의 경우, 해당 규칙의 명세는 규칙 내부에서 유효한 속성, 설명자 및/또는 at-규칙을 정의해야 한다. 이는 "@foo 규칙은 이 명세/절에서 정의한 속성/설명자를 허용한다."라고 말하는 것처럼 간단할 수 있으며, 확장 명세는 "@foo 규칙은 다음 속성/설명자도 허용한다."라고 말하기만 하면 된다. 블록 안에서 발견된 선언 또는 at-규칙 중 유효한 것으로 정의되지 않은 것은 규칙의 값에서 제거해야 한다.
<style-block> 또는 <declaration-list> 안에서 !important는
모든 설명자에 대해 자동으로 유효하지 않다.
규칙이 속성을 허용한다면
해당 규칙의 명세는 속성이 캐스케이드와 상호작용하는지,
그리고 어떤 명시도로 상호작용하는지 정의해야 한다.
캐스케이드와 상호작용하지 않는다면
!important가 포함된 속성은 자동으로 유효하지 않다.
그렇지 않으면 !important 사용은 유효하며
선언을 캐스케이드에서 중요하게 만든다.
[CSS-CASCADE-3]을 참조한다.
<rule-list>을 사용하는 규칙의 경우, 해당 규칙의 명세는 규칙 내부에서 유효한 규칙의 유형을 <declaration-list>과 마찬가지로 정의해야 하며, 인식되지 않는 규칙도 마찬가지로 규칙의 값에서 제거해야 한다.
<keyframe-rule> = <keyframe-selector> { <declaration-list> }
그런 다음 키프레임 규칙은 애니메이션할 수 있는 모든 CSS 속성과 animation-timing-function 속성을 선언으로 허용하지만, 캐스케이드와 상호작용하지 않음을 추가로 정의해야 한다.
<stylesheet>을 사용하는 규칙의 경우, 기본적으로 모든 규칙이 허용되지만 해당 규칙의 명세는 규칙 내부에서 유효하지 않은 규칙 유형을 정의할 수 있다.
@media <media-query-list> { <stylesheet> }
또한 <stylesheet>에 @media 규칙을 포함할 수 없다는 제한을 정의하며, 해당 규칙이 나타나면 외부 규칙의 값에서 제거된다.
8.2. 임의의 콘텐츠 정의: <declaration-value> 및 <any-value> 생성 규칙
일부 문법에서는 문법에서 합리적인 모든 입력을 허용하고 콘텐츠에 대해 더 구체적인 오류 처리를 직접 수행하는 것이 유용하다 (문법 불일치가 일반적으로 수행하는 것처럼 구문을 단순히 무효화하는 대신).
예를 들어 사용자 지정 속성은 다른 CSS 속성의 임의 부분을 포함하거나 기존 CSS에 전혀 속하지 않는 항목에 사용될 수 있으므로 합리적인 모든 값을 허용한다. 또 다른 예로 미디어 쿼리의 <general-enclosed> 생성 규칙은 향후 MQ 구문에서 허용할 범위를 정의하고 특수 논리를 사용해 "알 수 없는" 값을 처리한다.
이를 지원하기 위해 두 개의 추가 생성 규칙을 정의한다:
<declaration-value> 생성 규칙은 하나 이상의 모든 토큰 시퀀스와 일치한다. 단, 시퀀스에는 <bad-string-token>, <bad-url-token>, 짝이 맞지 않는 <)-token>, <]-token> 또는 <}-token>, 최상위 수준의 <semicolon-token> 또는 값이 "!"인 <delim-token>이 포함되어서는 안 된다. 유효한 선언이 값으로 가질 수 있는 모든 것을 나타낸다.
<any-value> 생성 규칙은 <declaration-value>와 동일하지만, 최상위 수준의 <semicolon-token>과 값이 "!"인 <delim-token>도 허용한다. 모든 컨텍스트에서 유효한 CSS가 될 수 있는 모든 것을 나타낸다.
9. CSS 스타일시트
CSS 스타일시트를 구문 분석하려면, 먼저 스타일시트를 구문 분석한다. 결과로 생성된 모든 최상위 수준의 한정 규칙을 아래에서 정의하는 스타일 규칙으로 해석한다.
스타일 규칙이 유효하지 않거나, at-규칙이 인식되지 않거나 해당 문법 또는 컨텍스트에 따라 유효하지 않으면 이는 구문 분석 오류이다. 해당 규칙을 버린다.
9.1. 스타일 규칙
스타일 규칙은 선택자 목록을 속성 선언 목록 및 선택적으로 중첩된 규칙 목록과 연결하는 한정 규칙이다. [CSS2]에서는 규칙 집합이라고도 한다. CSS 캐스케이딩 및 상속 [CSS-CASCADE-3]은 스타일 규칙 내부의 선언이 캐스케이드에 참여하는 방법을 정의한다.
한정 규칙의 프렐류드는 <selector-list>로 구문 분석된다. 이것이 실패를 반환하면 전체 스타일 규칙이 유효하지 않다.
한정 규칙 블록의 콘텐츠는 스타일 블록의 콘텐츠로 구문 분석된다. 다른 명세나 이 명세의 향후 레벨에서 달리 정의하지 않는 한 해당 목록의 at-규칙은 유효하지 않으며 무시해야 한다.
참고: [CSS-NESTING-1]은 @nest 및 조건부 그룹 규칙을 스타일 규칙 내부에서 허용하도록 정의한다.
알 수 없는 CSS 속성의 선언이나 값이 해당 속성에서 정의한 구문과 일치하지 않는 선언은 유효하지 않으며 무시해야 한다. 스타일 규칙 콘텐츠의 유효성은 스타일 규칙 자체의 유효성에 영향을 주지 않는다. 달리 명시하지 않는 한 속성 이름은 ASCII 대소문자를 구분하지 않는다.
참고: 사용자 지정 속성 [CSS-VARIABLES]의 이름은 대소문자를 구분한다.
CSS 스타일시트의 최상위 수준에 있는 한정 규칙은 스타일 규칙이다. 다른 컨텍스트의 한정 규칙은 해당 컨텍스트의 정의에 따라 스타일 규칙일 수도 있고 아닐 수도 있다.
예를 들어 @media 규칙 [CSS3-CONDITIONAL] 내부의 한정 규칙은 스타일 규칙이지만, @keyframes 규칙 [CSS3-ANIMATIONS] 내부의 한정 규칙은 그렇지 않다.
9.2. At-규칙
at-규칙은 at-키워드로 시작하는 규칙이므로 같은 컨텍스트의 스타일 규칙과 구분할 수 있다.
At-규칙은 다음 용도로 사용된다:
-
조건부 그룹 규칙에서처럼 스타일 규칙 및 기타 at-규칙을 그룹화하고 구조화한다.
-
카운터 스타일 정의처럼 특정 요소와 연결되지 않은 스타일 정보를 선언한다.
-
그리고 스타일 규칙이 제공하지 않는 기타 용도를 담당한다.
At-규칙은 특정 규칙과 목적에 따라 다양한 형태를 취하지만, 크게 두 종류로 나뉜다. 세미콜론으로 끝나는 더 단순한 구조인 문 at-규칙과, 중첩된 한정 규칙, at-규칙 또는 선언을 포함할 수 있는 {}-블록으로 끝나는 블록 at-규칙이다.
블록 at-규칙은 일반적으로 (일반적이거나 at-규칙별) at-규칙, 한정 규칙 및/또는 설명자 선언의 모음을 포함하며, at-규칙에서 정의한 제한을 따른다. 설명자는 속성과 유사하고 같은 구문으로 선언되지만, 트리의 요소 및 박스가 아니라 특정 유형의 at-규칙과 연결된다.
9.3. @charset 규칙
스타일시트의 대체 인코딩을 결정하는 데 사용하는 알고리즘은 파일의 맨 처음 몇 바이트에서 "@charset"이라는 이름의 at-규칙과 같은 구문 형태를 갖는 특정 바이트 시퀀스를 찾는다.
그러나 실제로 @charset이라는 이름의 at-규칙은 존재하지 않는다. 스타일시트를 실제로 구문 분석할 때 @charset 규칙이 나타나면 인식되지 않는 규칙으로 취급해야 하며, 따라서 스타일시트의 문법을 검사할 때 유효하지 않은 것으로 제거해야 한다.
참고: CSS 2.1에서 @charset은 유효한 규칙이었다. 일부 레거시 명세는 여전히 @charset 규칙을 참조하고 스타일시트에 이 규칙이 존재한다고 명시적으로 설명할 수 있다.
10. 직렬화
이 명세에서 설명한 토크나이저는 주석의 토큰을 생성하지 않으며 다른 어떤 방식으로도 주석을 보존하지 않는다. 구현은 주석의 콘텐츠와 토큰 스트림에서의 위치를 보존할 수 있다. 보존하는 경우 해당 정보는 구문 분석 단계에 영향을 주어서는 안 된다.
이 명세는 CSS를 일반적으로 직렬화하는 방법을 정의하지 않으며, 이 작업은 [CSSOM] 및 개별 기능 명세에 맡긴다. 특히 주석과 공백의 직렬화는 정의하지 않는다.
직렬화에 대한 유일한 요구 사항은 구문 분석과 "왕복"해야 한다는 것이다. 즉, 스타일시트를 구문 분석하면 구문 분석하고 직렬화한 다음 다시 구문 분석했을 때와 같은 데이터 구조를 생성해야 한다. 단, 연속된 <whitespace-token>은 하나의 토큰으로 축약할 수 있다.
참고: CSS 문법은 모든 양의 공백을 항상 하나의 공백과 동일하게 해석하므로 이러한 예외가 존재할 수 있다.
- U+005C REVERSE SOLIDUS (\)를 포함하는 <delim-token>은 U+005C REVERSE SOLIDUS 뒤에 줄 바꿈이 오는 형태로 직렬화해야 한다. (토크나이저는 이러한 토큰 뒤에 줄 바꿈으로 시작하는 <whitespace-token>이 오는 경우만 방출한다.)
- "unrestricted" 유형 플래그가 있는 <hash-token>은 "id" 유형 플래그가 있는 같은 토큰만큼 많은 이스케이프가 필요하지 않을 수 있다.
- <dimension-token>의 단위는 과학적 표기법과 구분하기 위해 이스케이프해야 할 수 있다.
-
연속된 모든 토큰 쌍에서
첫 번째 토큰이 다음 표의 행 머리글에 나타나고
두 번째 토큰이 열 머리글에 나타나며,
선택한 행과 열이 교차하는 셀에 ✗가 있으면
두 토큰 사이에 주석을 넣어 직렬화해야 한다.
토크나이저가 주석을 보존한다면 보존된 주석을 사용해야 한다. 그렇지 않으면 빈 주석(
/**/)을 삽입해야 한다. (다음 표에서 두 토큰 사이에 주석을 요구하지 않더라도 보존된 주석을 다시 삽입할 수 있다.)행과 열 머리글의 단일 문자는 해당 값을 갖는 <delim-token>을 나타낸다. 단, "
("는 (-token을 나타낸다.
| ident | function | url | bad url | - | number | percentage | dimension | CDC | ( | * | % | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ident | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ||
| at-keyword | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| hash | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| dimension | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| # | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| - | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| number | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| @ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ||||||
| . | ✗ | ✗ | ✗ | |||||||||
| + | ✗ | ✗ | ✗ | |||||||||
| / | ✗ |
10.1. <an+b> 직렬화
-
A가 0이면 B의 직렬화를 반환한다.
-
그렇지 않으면 처음에 result를 빈 문자열로 둔다.
-
- A가
1임 -
"n"을 result에 추가한다.
- A가
-1임 -
"-n"을 result에 추가한다.
- A가 0이 아님
-
A를 직렬화하여 result에 추가한 다음 "n"을 result에 추가한다.
- A가
-
- B가 0보다 큼
-
"+"를 result에 추가한 다음 B의 직렬화를 result에 추가한다.
- B가 0보다 작음
-
B의 직렬화를 result에 추가한다.
-
result를 반환한다.
11. 개인정보 보호 및 보안 고려 사항
이 명세는 새로운 개인정보 보호 문제를 일으키지 않는다.
이제 모든 입력에 대한 CSS 구문 분석이 명확하게 정의되므로 이 명세은 보안을 향상시킨다.
허용 목록이나 필터와 같은 이전 구문 분석기가 이 명세와 다르게 구문 분석하는 한 어느 정도 안전하지 않다. 그러나 이전 구문 분석 명세에는 브라우저마다 다르게 해석하는 모호한 경계 사례가 많이 남아 있었으므로, 이러한 필터는 이미 잠재적으로 안전하지 않았으며 이 명세가 상황을 악화시키지는 않는다.
12. 변경 사항
이 절은 비규범적이다.
12.1. 2019년 8월 16일 후보 권고안 이후의 변경 사항
다음과 같은 실질적인 변경 사항이 적용되었다:
-
새로운 § 5.3.2 CSS 문법에 따라 쉼표로 구분된 목록 구문 분석 알고리즘을 추가했다.
-
새로운 § 5.3.7 스타일 블록의 콘텐츠 구문 분석 알고리즘과 이에 대응하는 <style-block> 생성 규칙을 추가하고, 스타일 규칙이 이를 사용하도록 정의했다.
-
스타일시트 구문 분석을 Fetch 관련 처리에 맞게 조정했다. (커밋 참조.)
input에서 스타일시트를 구문 분석하려면 선택적인 URL location이 주어졌을 때 :
- ...
- 새 스타일시트를 생성한다 . 이때 위치를 location으로 설정한다(location이 전달되지 않았다면 null로 설정한다).
- ...
다음과 같은 편집상 변경 사항이 적용되었다:
-
at-규칙, 문 at-규칙, 블록 at-규칙 및 설명자의 정의를 제공하기 위해 § 9.2 At-규칙을 추가했다. (5633)
-
때때로 “name”이라는 용어를 사용하는 대신 ident 시퀀스를 일관되게 참조하도록 변경했다.
-
토큰화 전의 여러 프로세스에 명시적인 이름을 부여하고 구문 분석 진입점에서 이를 명시적으로 참조했다 (포괄적인 "이 알고리즘의 시작에서 X를 수행한다"라는 문에 의존하는 대신).
-
이제 ident가
--로 시작할 수 있다는 사실을 올바르게 처리하도록 "둘 사이에 주석을 넣기" 표에 항목을 더 추가했다. (6874)
12.2. 2014년 2월 20일 후보 권고안 이후의 변경 사항
다음과 같은 실질적인 변경 사항이 적용되었다:
-
<unicode-range-token>을 제거하고 <urange> 생성 규칙을 만들었다.
-
문자열을 포함하는 url() 함수는 이제 일반적인 <function-token>으로 구문 분석된다. "원시" URL을 포함하는 url() 함수는 여전히 <url-token>으로 특별히 구문 분석된다.
-
"URL 토큰 소비" 알고리즘이 문자열을 소비하려고 하기 전에 문자열을 시작하는 따옴표 문자를 소비하지 않았던 버그를 수정했다.
-
현재/다음 입력 토큰 및 항목이 너무 일찍 또는 늦게 소비되는 것과 관련된 여러 구문 분석기 알고리즘의 버그를 수정했다.
-
토큰화 및 구문 분석 알고리즘의 여러 버그를 수정했다.
-
"--"로 ident를 시작할 수 있도록 ident 유사 토큰의 정의를 변경했다. 그 일부로 토큰 소비의 "-" 단계에서 절의 순서를 재배치하여 <CDC-token>이 -- <ident-token>이 되는 대신 해당 토큰으로 인식되도록 했다.
-
A가 1 또는 -1일 때 <an+b>에서 숫자를 직렬화하지 않도록 했다.
-
모든 토큰이 표현을 갖도록 정의했다.
-
두 코드 포인트가 유효한 이스케이프인지 확인의 사소한 버그를 수정했다—
이제 EOF가 뒤따르는 \는 유효한 이스케이프가 아닌 것으로 올바르게 보고된다. 이제 스타일시트의 마지막\는 자신을 <delim-token>으로 방출한다. -
@charset은 더 이상 유효한 CSS 규칙이 아니다(@charset이라는 이름의 규칙처럼 보이는 인코딩 선언만 존재한다).
-
구문 분석 중 선언 값의 시작과 끝에서 공백을 제거했다.
-
WG 결의에 따라 선택자별 토큰을 제거했다.
-
WG 결의에 따라 입력 스트림에서 서로게이트를 필터링했다. 이제 전체 명세는 스칼라 값만을 대상으로 작동한다.
다음과 같은 편집상 변경 사항이 적용되었다:
-
명시적인 종료 토큰을 지정하지 않고 호출하여 대신 현재 입력 토큰을 사용할 수 있도록 "문자열 토큰 소비" 알고리즘을 변경했다. 이 알고리즘의 세 호출 지점도 해당 형식을 사용하도록 변경했다.
-
알고리즘의 사소한 편집상 구조를 변경했다.
-
구문 분석 및 쉼표로 구분된 구성 요소 값 목록 구문 분석 API 진입점을 추가했다.
-
<declaration-value> 및 <any-value> 생성 규칙을 추가했다.
-
Infra 표준의 동일한 정의를 사용하도록 "code point"와 "surrogate code point"를 제거했다.
-
모든 범위가 양 끝값을 포함한다는 점을 명확히 했다.
-
숫자 토큰이 "%" 구분자 토큰 옆에 나타나는 경우를 처리하도록 주석 삽입 표에 열을 추가했다.
12.3. 2013년 11월 5일 최종 검토 작업 초안 이후의 변경 사항
- 직렬화 절을 다시 작성하여 "왕복" 요구 사항만 규범적으로 만들고 이를 달성하는 방법의 세부 사항은 참고로 옮겼다. 이러한 세부 사항의 일부 경계 사례를 수정했다.
- 규범 참고 문헌 목록에 [ENCODING]을 추가했다. 이전에도 규범 텍스트에서 참조했지만 규범 참고 문헌으로 나열하지 않았을 뿐이다.
-
스타일시트의 대체 인코딩을 결정하는 알고리즘에서
@charset바이트 시퀀스를 1024바이트로 제한했다. 이는 HTML이<meta charset>에 대해 수행하는 동작과 일치하며 시퀀스의 크기가 제한되도록 한다. 이는 인코딩 레이블의 선행 또는 후행 공백이 있을 때만 차이를 만든다:@charset " (많은 공백) utf-8";
12.4. 2013년 9월 19일 작업 초안 이후의 변경 사항
- 환경 인코딩 개념을 추가했다. 동작은 변경되지 않지만 일부 정의를 관련 명세로 옮겨야 한다.
12.5. CSS 2.1 및 선택자 레벨 3 이후의 변경 사항
참고: 이 명세의 목적은 현실과 일치시키는 것이다. CSS 2.1과 다른 부분은 거의 항상 CSS 2.1이 실제 브라우저 동작과 일치하지 않는 내용을 지정했거나 일부 내용을 지정하지 않았기 때문이다. 어떤 세부 사항이 브라우저와 일치하지 않는다면 거의 확실히 의도하지 않은 것이므로 알려 주기 바란다.
바이트 스트림 디코딩의 변경 사항:
- ASCII 호환 바이트 패턴에서만 @charset 규칙을 감지한다.
- ASCII와 호환되지 않는 인코딩을 지정하는 @charset 규칙은 해당 규칙 자체가 올바르게 디코딩되지 않게 하므로 무시한다.
- 문자 인코딩에 IANA 레지스트리 대신 [ENCODING]을 참조한다.
토큰화 변경 사항:
- CSS 소스의 모든 U+0000 NULL 코드 포인트는 U+FFFD REPLACEMENT CHARACTER로 대체된다.
- \0처럼 값이 0이 되는 모든 16진수 이스케이프 시퀀스는 U+0000 NULL 대신 U+FFFD REPLACEMENT CHARACTER를 생성한다.
- 모든 ASCII 정의와 일치하도록 비ASCII 코드 포인트의 정의를 변경했다. 이는 U+0080부터 U+009F까지의 코드 포인트에 영향을 주며, 이제 이들은 나머지 비ASCII 코드 포인트처럼 <delim-token>이 아니라 ident 코드 포인트이다.
- 토큰화는 더 이상 COMMENT 또는 BAD_COMMENT 토큰을 방출하지 않는다. 이제 BAD_COMMENT는 일반 토큰과 같은 것으로 간주한다(오류가 아니다). 직렬화는 연속된 두 <ident-token>과 같이 분리해야 하는 토큰 사이에 필요에 따라 주석을 삽입한다.
-
가치가 낮고 때때로 적극적으로 해로웠으므로
<unicode-range-token>을 제거했다.
(예를 들어 u+a { font-weight: bold; }는 유효하지 않은 선택자였다...)
대신 토큰 패턴을 기반으로 하는 <urange> 생성 규칙을 추가했다. 엄밀히 말하면 CSS 2.1이 허용한 것보다 느슨하지만 (숫자와 ? 문자를 원하는 만큼 사용할 수 있음), 실제 사용에 영향을 줄 만한 차이는 아니다.
- 토크나이저에서 EOF 오류 처리 규칙을 적용하고, EOF에서 BAD_STRING 또는 BAD_URI 대신 일반적인 <string-token> 및 <url-token>을 방출한다.
- BAD_URI 토큰(현재의 <bad-url-token>)은 "자체 완결적"이다. 즉, 토크나이저가 <url-token>이 아니라 <bad-url-token> 안에 있음을 인식하면 그 밖의 모든 것을 무시하고 닫는 )를 찾기 위해 앞으로 이동한다. 이 동작은 이를 <function-token>처럼 취급하여 열린 블록 등에 주의를 기울이는 것보다 단순하다. WebKit만 이 동작을 보이지만 이로 인해 호환성 버그가 발생한 것으로 보이지 않는다.
- <comma-token>을 추가했다.
- <number-token>, <percentage-token> 및 <dimension-token>은 앞의 +/- 기호를 값의 일부로 포함하도록 변경되었다 (다른 명세에서 토큰을 언급할 때마다 직접 처리해야 하는 별도의 <delim-token>으로 취급하는 대신). 이로 인한 유일한 결과는 기호와 숫자 사이에 더 이상 주석을 삽입할 수 없다는 것이다.
- WG 결의에 따라 SVG와 일치하도록 숫자/백분율/dimension에서 과학적 표기법을 지원한다.
- 이제 서로게이트의 16진수 이스케이프는 서로게이트 대신 대체 문자를 방출한다. 이를 통해 구현은 내부적으로 UTF-16을 안전하게 사용할 수 있다.
구문 분석 변경 사항:
- 이제 모든 선언 목록은 WG 결의에 따라 @page처럼 at-규칙도 허용한다. 아직 그러한 at-규칙이 정의되지 않았더라도 이는 오류 처리에 차이를 만든다. 유효성 여부와 관계없이 at-규칙은 <semicolon-token> 없이 {} 블록에서 끝나고 다음 선언이 시작될 수 있게 한다.
-
문법의 여러 위치에 나타나는
일부 기타 "특수" 토큰
(예: 짝이 맞지 않는 <}-token>)의 처리를
최소 한 브라우저에서 보이는 합리적인 동작으로 지정했다.
이전에는 해당 토큰이 그 위치에 있는 스타일시트가
스타일시트 문법과 전혀 일치하지 않았으므로
처리 방식이 완전히 정의되지 않았다.
구체적으로:
- 이제 [] 블록, () 블록 및 함수에 {} 블록, <at-keyword-token> 또는 <semicolon-token>을 포함할 수 있다.
- 이제 한정 규칙 프렐류드에 세미콜론을 포함할 수 있다.
- 이제 한정 규칙 및 at-규칙 프렐류드에 <at-keyword-token>을 포함할 수 있다.
선택자 레벨 3 [SELECT] 이후의 An+B 변경 사항:
-
이제 An+B 마이크로 구문은 별도의 토크나이저 대신
CSS 토큰을 사용하여 정식으로 정의된다.
이로 인해 다음과 같은 사소한 차이가 생겼다:
- 일부 경우에는 빼기 기호나 숫자를 이스케이프할 수 있다 (<dimension-token> 또는 <ident-token>의 단위 일부로 나타나는 경우).
감사의 말
다음 사람들의 피드백과 기여에 감사한다: Anne van Kesteren, David Baron, Elika J. Etemad (fantasai), Henri Sivonen, Johannes Koch, 呂康豪 (Kang-Hao Lu), Marc O’Morain, Raffaello Giulietti, Simon Pieter, Tyler Karaszewski, 그리고 Zack Weinberg.