1. 소개
이 절은 규범적이지 않습니다.
이 모듈은 CSS 스타일시트의 추상 구문과 파싱을 정의하며
CSS 구문을 사용하는 다른 항목도 포함합니다
(예: HTML style 속성).
유니코드 코드 포인트 스트림을 (즉, 텍스트를) CSS 토큰 스트림으로 변환하고, 이어서 스타일시트, 규칙 및 선언과 같은 CSS 객체로 변환하는 알고리즘을 정의합니다.
1.1. 모듈 상호작용
이 모듈은 CSS 스타일시트의 구문과 파싱을 정의합니다. CSS 2.1에 정의된 어휘 스캐너와 문법을 대체합니다.
2. CSS 구문 설명
이 절은 규범적이지 않습니다.
CSS 문서는 문서의 요소에 스타일을 적용하는 스타일 규칙—즉 한정 규칙—과 CSS 문서에 대한 특별한 처리 at-규칙—을 포함하며, 이는 특별한 처리 규칙이나 값을 정의합니다.
한정 규칙은 프렐류드로 시작하며 그 뒤에 일련의 선언을 포함하는 {}로 둘러싸인 블록이 있습니다. 프렐류드의 의미는 규칙이 나타나는 컨텍스트에 따라 달라집니다—스타일 규칙의 경우, 어떤 요소에 선언을 적용할지를 지정하는 선택자입니다. 각 선언에는 이름이 있고, 그 뒤에 콜론과 선언 값이 옵니다. 선언은 세미콜론으로 구분됩니다.
일반적인 규칙은 다음과 같은 형태일 수 있습니다:
p > a {
color: blue;
text-decoration: underline;
}
위 규칙에서 "p > a"는 선택자이며,
소스 문서가 HTML인 경우
모든
a
요소 중
p
요소의 자식인 요소를 선택합니다.
"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-규칙 이름은 항상 식별자 시퀀스이며, 식별자 시작 코드 포인트, 두 개의 하이픈, 또는 하이픈 뒤의 식별자 시작 코드 포인트로 시작해야 하며, 그 뒤에는 0개 이상의 식별자 코드 포인트를 포함할 수 있습니다. 어떤 코드 포인트든 포함할 수 있으며, CSS가 자체 구문에서 사용하는 코드 포인트도 이를 이스케이프하면 포함할 수 있습니다.
선택자의 구문은 Selectors 명세에 정의되어 있습니다. 마찬가지로, 매우 다양한 CSS 값의 구문은 Values & Units 명세에 정의되어 있습니다. 개별 at-규칙의 특수한 구문은 해당 규칙을 정의하는 명세에서 확인할 수 있습니다.
2.1. 이스케이프
이 절은 규범적이지 않습니다.
모든 유니코드 코드 포인트는 식별자 시퀀스 또는 따옴표로 둘러싸인 문자열에 이를 이스케이프하여 포함할 수 있습니다. CSS 이스케이프 시퀀스는 백슬래시(\)로 시작하며, 다음 중 하나가 이어집니다:
- 코드 포인트 중 16진수 숫자 또는 개행이 아닌 임의의 유니코드 코드 포인트. 이스케이프 시퀀스는 해당 코드 포인트로 대체됩니다.
-
또는 1개에서 6개의 16진수 숫자 뒤에
선택적인 공백이 옵니다.
이스케이프 시퀀스는 16진수 숫자로 값이 지정된 유니코드 코드 포인트로
대체됩니다.
이 선택적 공백을 사용하면 16진수 이스케이프 시퀀스 뒤에
"실제" 16진수 숫자가 올 수 있습니다.
값이 "&B"인 식별자 시퀀스는 \26 B 또는 \000026B로 작성할 수 있습니다.
이스케이프 시퀀스 뒤의 "실제" 공백은 두 번 써야 합니다.
2.2. 오류 처리
이 절은 규범적이지 않습니다.
CSS에서 오류가 발생하면, 파서는 정상적으로 복구하려고 시도하며, 다시 정상적인 파싱으로 돌아가기 전에 최소한의 내용만 버립니다. 이는 오류가 항상 실수인 것은 아니기 때문입니다—새 구문은 오래된 파서에는 오류처럼 보이며, 해당 구문을 포함하는 스타일시트가 오래된 UA에서 완전히 망가질 것을 걱정하지 않고 언어에 새 구문을 추가할 수 있으면 유용합니다.
정확한 오류 복구 동작은 파서 자체에 자세히 설명되어 있지만, 충분히 단순하므로 짧은 설명도 상당히 정확합니다.
- 스타일시트의 "최상위 수준"에서는, <at-keyword-token>이 at-규칙을 시작합니다. 그 밖의 모든 것은 한정 규칙을 시작하며, 규칙의 프렐류드에 포함됩니다. 이로 인해 유효하지 않은 선택자가 생성될 수 있지만, 이는 CSS 파서가 신경 쓸 문제가 아닙니다—최악의 경우 선택자가 아무것도 일치시키지 못한다는 뜻일 뿐입니다.
- at-규칙이 시작되면, 파서의 관점에서는 어떤 것도 유효하지 않은 것이 아닙니다; 모두 at-규칙의 프렐류드 일부입니다. <semicolon-token>을 만나면 at-규칙이 즉시 끝나고, 여는 중괄호 <{-token>을 만나면 at-규칙의 본문이 시작됩니다. at-규칙은 앞으로 진행하면서 블록((), {}, 또는 []로 둘러싸인 내용)을 짝지어 다른 어떤 것과도 짝지어지지 않았고 다른 블록 내부에도 있지 않은 닫는 중괄호 <}-token>을 찾을 때까지 계속합니다. 그런 다음 at-규칙의 내용은 해당 at-규칙 자체의 문법에 따라 해석됩니다.
- 한정 규칙도 비슷하게 동작하지만, 세미콜론은 규칙을 끝내지 않습니다; 대신 규칙의 프렐류드 일부로 받아들여집니다. 첫 번째 {} 블록이 발견되면, 그 내용은 항상 선언 목록으로 해석됩니다.
- 선언 목록을 해석할 때, 어느 시점에서든 알 수 없는 구문이 나타나면 파서는 현재 작성 중인 선언을 버리고, 세미콜론(또는 블록의 끝)을 찾을 때까지 앞으로 진행합니다. 그런 다음 새로 시작하여 다시 선언을 파싱하려고 시도합니다.
-
규칙, 선언, 함수, 문자열 등이 여전히 열린 상태에서 스타일시트가 끝나면,
모든 것이 자동으로 닫힙니다.
그렇다고 해서 이것들이 유효하지 않게 되는 것은 아니지만,
불완전할 수 있으며
따라서 문법에 대해 검증될 때 버려질 수 있습니다.
예를 들어, translateX() 함수의 구문은 다음과 같습니다:
translateX( <translation-value> )
그러나 스타일시트는 함수가 닫히지 않은 상태로 다음과 같이 끝날 수 있습니다:
.foo { transform: translate(50pxCSS 파서는 이를 하나의 선언을 포함하는 스타일 규칙으로 파싱하며, 그 값은 "translate"라는 이름의 함수입니다. 이는 위 문법과 일치합니다. 토큰 스트림에는 끝 토큰이 나타나지 않았지만, 파서가 완료될 즈음에는 끝 토큰이 존재했는지 더 이상 판별할 수 없기 때문입니다; 알 수 있는 것은 블록과 함수가 있다는 사실뿐입니다.
각 구문(선언, 스타일 규칙, at-규칙)이 파싱된 후, 사용자 에이전트는 예상되는 문법과 일치하는지 확인합니다. 문법과 일치하지 않으면, 해당 구문은 유효하지 않으며, UA에 의해 무시되고, UA는 해당 구문이 전혀 없는 것처럼 처리합니다.
3. CSS 토큰화 및 파싱
사용자 에이전트는 이 명세에서 설명하는 파싱 규칙을 사용하여 text/css 리소스로부터 [CSSOM] 트리를 생성해야 합니다. 이 규칙들을 함께 CSS 파서라고 부릅니다.
이 명세는 CSS 문서가 구문적으로 올바른지 여부와 관계없이 파싱 규칙을 정의합니다. 파싱 알고리즘의 특정 지점은 파싱 오류라고 합니다. 파싱 오류에 대한 오류 처리는 명확하게 정의되어 있습니다: 사용자 에이전트는 이러한 문제를 만났을 때 아래에 설명된 대로 동작하거나, 아래 설명된 규칙을 적용하고 싶지 않은 첫 번째 오류에서 처리를 중단해야 합니다.
문서에 하나 이상의 파싱 오류 조건이 존재하면 적합성 검사기는 적어도 하나의 파싱 오류 조건을 사용자에게 보고해야 하며 반대로 적합성 검사기가 사용자에게 보고할 파싱 오류 조건이 문서에는 하나도 존재하지 않는 경우, 파싱 오류 조건을 보고해서는 안 됩니다. 하나보다 많은 파싱 오류 조건이 문서에 존재하는 경우 적합성 검사기는 하나보다 많은 파싱 오류 조건을 보고할 수 있습니다. 적합성 검사기는 파싱 오류에서 복구할 필요는 없지만, 복구하는 경우에는 사용자 에이전트와 동일한 방식으로 복구해야 합니다.
3.1. 파싱 모델 개요
CSS 파싱 프로세스의 입력은 유니코드 코드 포인트 스트림으로 구성되며, 이 스트림은 토큰화 단계를 거친 뒤 트리 구성 단계를 거칩니다. 출력은 CSSStyleSheet 객체입니다.
참고: 스크립팅을 지원하지 않는 구현은 실제로 CSSOM CSSStyleSheet 객체를 생성할 필요는 없지만, 이 경우에도 CSSOM 트리는 나머지 명세를 위한 모델로 사용됩니다.
3.2. 입력 바이트 스트림
스타일시트를 파싱할 때, 토큰화 단계의 입력을 구성하는 유니코드 코드 포인트 스트림은 처음에는 사용자 에이전트에 바이트 스트림으로 보일 수 있습니다 (일반적으로 네트워크 또는 로컬 파일 시스템에서 가져옵니다). 그런 경우 사용자 에이전트는 특정 문자 인코딩에 따라 이 바이트를 코드 포인트로 디코딩해야 합니다.
-
stylesheet의 대체 인코딩을 결정하고, 그 결과를 fallback으로 둡니다.
-
대체 인코딩 fallback을 사용하여 stylesheet의 바이트 스트림을 디코딩하고 그 결과를 반환합니다.
참고: 디코딩 알고리즘은 바이트 순서 표시(BOM)에 우선순위를 부여하고, 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>속성 동작을 모방합니다.참고: 인코딩 선언의 구문은 at-규칙인 @charset의 구문처럼 보이지만, 실제로 그런 규칙은 존재하지 않으며, 이를 작성하는 방법에 대한 규칙은 일반적으로 해당 규칙을 인식하는 경우보다 훨씬 제한적입니다. 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. 입력 스트림 전처리
입력 스트림은 입력 바이트 스트림이 디코딩될 때 그 안으로 푸시되는 필터링된 코드 포인트로 구성됩니다.
- input의 모든 U+000D CARRIAGE RETURN (CR) 코드 포인트, U+000C FORM FEED (FF) 코드 포인트, 또는 U+000D CARRIAGE RETURN (CR) 뒤에 U+000A LINE FEED (LF)가 오는 쌍을 하나의 U+000A LINE FEED (LF) 코드 포인트로 대체합니다.
-
input의 모든 U+0000 NULL 또는 서로게이트 코드 포인트를
U+FFFD REPLACEMENT CHARACTER (�)로
대체합니다.
참고: CSS 콘텐츠에서 서로게이트 코드 포인트를 생성할 수 있는 유일한 방법은 OM 연산을 통해 해당 문자를 포함한
DOMString을 직접 할당하는 것입니다.
4. 토큰화
코드 포인트 스트림을 CSS 토큰 스트림 input으로 토큰화하려면, 토큰을 소비하는 작업을 input에 반복해서 수행하여 <EOF-token>에 도달할 때까지 반환된 각 토큰을 스트림에 푸시합니다.
참고: 토큰을 소비하는 알고리즘을 호출할 때마다 하나의 토큰이 반환되므로, 원한다면 파싱 중에 코드 포인트 스트림을 "온디맨드" 방식으로 토큰화하는 데도 사용할 수 있습니다.
토큰화 단계의 출력은 다음 토큰 중 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>, <unicode-range-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>에는 추가로 하나 이상의 코드 포인트로 구성된 단위가 있습니다.
- <unicode-range-token>에는 시작 코드 포인트와 끝 코드 포인트가 있습니다. 이는 코드 포인트의 포괄적 범위를 나타내며 (시작과 끝을 모두 포함합니다). 끝 코드 포인트가 시작 코드 포인트보다 앞에 있으면, 빈 범위를 나타냅니다.
참고: 해시 토큰의 유형 플래그는 Selectors 구문 [SELECT]에서 사용됩니다. "id" 유형의 해시 토큰만 유효한 ID 선택자입니다.
4.1. 토큰 철도 다이어그램
이 절은 비규범적입니다.
이 절에서는 토큰화기의 정보 제공용 표현을 철도 다이어그램 형태로 제시합니다. 철도 다이어그램은 명시적인 파서보다 더 간결하지만, 정규 표현식보다 읽기 쉬운 경우가 많습니다.
이 다이어그램은 정보 제공용이며 불완전합니다; "올바른" 토큰의 문법을 설명하지만, 오류 처리는 전혀 설명하지 않습니다. 각 토큰의 구문을 직관적으로 이해하기 쉽게 하기 위한 목적으로만 제공됩니다.
<foo-token>과 같은 이름의 다이어그램은 토큰을 나타냅니다. 나머지는 다른 다이어그램에서 참조하는 생성 규칙입니다.
- 주석
-
- 개행
-
- 공백
-
- 16진수 숫자
-
- 이스케이프
-
- <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>
-
- <unicode-range-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+00B7
-
U+00C0부터 U+00D6까지
-
U+00D8부터 U+00F6까지
-
U+00F8부터 U+037D까지
-
U+037F부터 U+1FFF까지
-
U+200C
-
U+200D
-
U+203F
-
U+2040
-
U+2070부터 U+218F까지
-
U+2C00부터 U+2FEF까지
-
U+3001부터 U+D7FF까지
-
U+F900부터 U+FDCF까지
-
U+FDF0부터 U+FFFD까지
-
U+10000 이상
이 모든 범위는 양 끝을 포함합니다.
특히 이러한 문자인 이유는 무엇입니까?
이는 HTML에서 사용할 수 있도록 허용되는 비ASCII 코드 포인트 목록과 일치하며, 유효한 사용자 정의 요소 이름에 사용됩니다. 공백으로 나타나는 여러 문자나, 일부 도구에서 렌더링 또는 파싱 문제를 일으킬 수 있는 문자, 예를 들어 방향 재정의 코드 포인트는 제외합니다.
이는 식별자에 대해 UAX 31이 권장하는 것보다 약한 제한 집합이라는 점에 유의하십시오 (JavaScript 같은 언어가 식별자 구문을 제한하는 데 사용합니다), 예를 들어 결합 문자로 식별자를 시작하는 것도 허용합니다. HTML 사용자 정의 요소 이름과의 일관성 (따라서 모든 사용자 정의 요소에 대해 선택자를 이스케이프 없이 작성할 수 있는 기능)은 가치 있는 것으로 간주되었으며, HTML에서 제한하는 문자 집합은 "중요도가 높은" 제한을 잘 포괄합니다.
이러한 제한으로 가능한 모든 혼란스러운 렌더링을 피할 수 있는 것은 아닙니다; LTR 및 RTL 스크립트의 문자를 혼합하면 여전히 예상치 못한 시각적 위치 변경이 대부분의 텍스트 편집기에서 발생할 수 있습니다, 예를 들어 그렇습니다. 소스 텍스트는 식별자가 아닌 컨텍스트에서도 제한된 문자를 포함할 수 있습니다: 예를 들어 대부분은 문자열에서 완전히 유효합니다. 유효하지 않은 CSS를 만드는 방식으로 사용하더라도, 그로 인해 발생하는 파싱 오류는 중요하지 않은 부분에만 한정될 수 있지만, 코드 검토 도구에서 소스 텍스트를 렌더링하는 데 미치는 영향은 상당하거나 악의적일 수 있습니다. 이러한 종류의 "소스 텍스트 공격"에 대한 자세한 내용은 이 Rust-lang 블로그 게시물을 참조하십시오 (보관됨).
-
- 식별자 시작 코드 포인트
- 문자, 비ASCII 식별자 코드 포인트, 또는 U+005F LOW LINE (_)입니다.
- 식별자 코드 포인트
- 식별자 시작 코드 포인트, 숫자, 또는 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입니다.
- 허용되는 최대 코드 포인트
- 유니코드에서 정의하는 가장 큰 코드 포인트: U+10FFFF입니다.
- 식별자 시퀀스
-
<ident-token>과 동일한 구문을 갖는 코드 포인트 시퀀스입니다.
참고: <at-keyword-token>에서 "@" 뒤의 부분, <hash-token>에서 ("id" 유형 플래그를 가진) "#" 뒤의 부분, <function-token>에서 "(" 앞의 부분, 그리고 <dimension-token>의 단위는 모두 식별자 시퀀스입니다.
4.3. 토큰화 알고리즘
이 절에서 정의한 알고리즘은 코드 포인트 스트림을 토큰 스트림으로 변환합니다.
4.3.1. 토큰을 소비하기
이 절에서는 코드 포인트 스트림에서 토큰을 소비하는 방법을 설명합니다. 또한 선택적인 불리언 unicode ranges allowed를 받으며, 기본값은 false입니다. 모든 유형의 단일 토큰을 반환합니다.
다음 입력 코드 포인트를 소비합니다.
- 공백
- 가능한 한 많은 공백을 소비합니다. <whitespace-token>을 반환합니다.
- U+0022 QUOTATION MARK (")
- 문자열 토큰을 소비하고 이를 반환합니다.
- U+0023 NUMBER SIGN (#)
-
다음
입력 코드 포인트가 식별자
코드 포인트이거나
다음 두 입력 코드 포인트가
유효한 이스케이프이면,
다음을 수행합니다:
- <hash-token>을 생성합니다.
- 다음 3개의 입력 코드 포인트가 식별자 시퀀스를 시작한다면, <hash-token>의 유형 플래그를 "id"로 설정합니다.
- 식별자 시퀀스를 소비하고, <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 (-)
-
입력 스트림이 숫자로 시작하면,
현재 입력 코드 포인트를 다시 소비하고,
숫자
토큰을 소비한 다음,
이를 반환합니다.
그렇지 않고, 다음 2개의 입력 코드 포인트가 U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->)이면, 이를 소비하고 <CDC-token>을 반환합니다.
그렇지 않고, 입력 스트림이 식별자 시퀀스로 시작하면, 현재 입력 코드 포인트를 다시 소비하고, 식별자형 토큰을 소비한 다음, 이를 반환합니다.
그렇지 않으면, 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환합니다.
- U+002E FULL STOP (.)
-
입력 스트림이 숫자로 시작하면,
현재 입력 코드 포인트를 다시 소비하고,
숫자
토큰을 소비한 다음,
이를 반환합니다.
그렇지 않으면, 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환합니다.
- U+003A COLON (:)
- <colon-token>을 반환합니다.
- U+003B SEMICOLON (;)
- <semicolon-token>을 반환합니다.
- U+003C LESS-THAN SIGN (<)
-
다음 3개의
입력 코드 포인트가
U+0021 EXCLAMATION MARK
U+002D HYPHEN-MINUS
U+002D HYPHEN-MINUS
(!--)이면,
이를 소비하고
<CDO-token>을 반환합니다.
그렇지 않으면, 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환합니다.
- U+0040 COMMERCIAL AT (@)
-
다음 3개의
입력 코드 포인트가
식별자
시퀀스를 시작한다면,
식별자
시퀀스를 소비하고,
값이 반환된
값으로 설정된 <at-keyword-token>을 생성한 다음,
이를 반환합니다.
그렇지 않으면, 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환합니다.
- U+005B LEFT SQUARE BRACKET ([)
- <[-token>을 반환합니다.
- U+005C REVERSE SOLIDUS (\)
-
입력 스트림이 유효한 이스케이프로 시작하면,
현재 입력 코드 포인트를 다시 소비하고,
식별자형 토큰을 소비한 다음,
이를 반환합니다.
그렇지 않으면, 이는 파싱 오류입니다. 값이 현재 입력 코드 포인트로 설정된 <delim-token>을 반환합니다.
- U+005D RIGHT SQUARE BRACKET (])
- <]-token>을 반환합니다.
- U+007B LEFT CURLY BRACKET ({)
- <{-token>을 반환합니다.
- U+007D RIGHT CURLY BRACKET (})
- <}-token>을 반환합니다.
- 숫자
- 현재 입력 코드 포인트를 다시 소비하고, 숫자 토큰을 소비한 다음, 이를 반환합니다.
- U+0055 LATIN CAPITAL LETTER U (U)
- u+0075 LATIN LOWERCASE LETTER U (u)
-
unicode ranges allowed가 true이고
입력 스트림이 unicode-range를 시작한다면,
현재 입력 코드 포인트를 다시 소비하고,
unicode-range 토큰을 소비한 다음,
이를 반환합니다.
그렇지 않으면, 현재 입력 코드 포인트를 다시 소비하고, 식별자형 토큰을 소비한 다음, 이를 반환합니다.
- 식별자 시작 코드 포인트
- 현재 입력 코드 포인트를 다시 소비하고, 식별자형 토큰을 소비한 다음, 이를 반환합니다.
- 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로 둡니다.
다음 3개의 입력 코드 포인트가 식별자 시퀀스를 시작한다면, 다음을 수행합니다:
- number와 동일한 값, 유형 플래그 및 부호 문자를 갖는 <dimension-token>을 생성하고, 단위는 처음에 빈 문자열로 설정합니다.
- 식별자 시퀀스를 소비합니다. <dimension-token>의 단위를 반환된 값으로 설정합니다.
- <dimension-token>을 반환합니다.
그렇지 않고, 다음 입력 코드 포인트가 U+0025 PERCENTAGE SIGN (%)이면, 이를 소비합니다. number와 동일한 값 및 부호 문자를 갖는 <percentage-token>을 생성하고, 이를 반환합니다.
그렇지 않으면, number와 동일한 값, 유형 플래그 및 부호 문자를 갖는 <number-token>을 생성하고, 이를 반환합니다.
4.3.4. 식별자형 토큰을 소비하기
이 절에서는 코드 포인트 스트림에서 식별자형 토큰을 소비하는 방법을 설명합니다. <ident-token>, <function-token>, <url-token>, 또는 <bad-url-token>을 반환합니다.
식별자 시퀀스를 소비하고, 그 결과를 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>으로 파싱됩니다. 식별자형 토큰을 소비하기가 자동으로 이 차이를 처리합니다; 따라서 이 알고리즘은 그 밖의 경우 직접 호출해서는 안 됩니다.
- 처음에 값이 빈 문자열로 설정된 <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. 세 코드 포인트가 식별자 시퀀스를 시작하는지 확인하기
이 절에서는 세 코드 포인트가 식별자 시퀀스를 시작하는지 확인하는 방법을 설명합니다. 여기에서 설명하는 알고리즘은 세 코드 포인트를 명시적으로 지정하여 호출하거나, 입력 스트림 자체로 호출할 수 있습니다. 후자의 경우 문제의 세 코드 포인트는 현재 입력 코드 포인트와 다음 두 입력 코드 포인트이며, 이 순서입니다.
참고: 이 알고리즘은 추가 코드 포인트를 소비하지 않습니다.
첫 번째 코드 포인트를 확인합니다:
- U+002D HYPHEN-MINUS
- 두 번째 코드 포인트가 식별자 시작 코드 포인트이거나 U+002D HYPHEN-MINUS이거나, 두 번째와 세 번째 코드 포인트가 유효한 이스케이프이면, true를 반환합니다. 그렇지 않으면 false를 반환합니다.
- 식별자 시작 코드 포인트
- 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. 세 코드 포인트가 unicode-range를 시작하는지 확인하기
이 절에서는 세 코드 포인트가 unicode-range를 시작하는지 확인하는 방법을 설명합니다. 여기에서 설명하는 알고리즘은 세 코드 포인트를 명시적으로 지정하여 호출하거나, 입력 스트림 자체로 호출할 수 있습니다. 후자의 경우 문제의 세 코드 포인트는 현재 입력 코드 포인트와 다음 두 입력 코드 포인트이며, 이 순서입니다.
참고: 이 알고리즘은 추가 코드 포인트를 소비하지 않습니다.
다음이 모두 참이면:
-
첫 번째 코드 포인트가 U+0055 LATIN CAPITAL LETTER U (U) 또는 U+0075 LATIN SMALL LETTER U (u) 중 하나입니다
-
두 번째 코드 포인트가 U+002B PLUS SIGN (+)입니다.
-
세 번째 코드 포인트가 U+003F QUESTION MARK (?) 또는 16진수 숫자 중 하나입니다
true를 반환합니다.
그렇지 않으면 false를 반환합니다.
4.3.12. 식별자 시퀀스를 소비하기
이 절에서는 코드 포인트 스트림에서 식별자 시퀀스를 소비하는 방법을 설명합니다. 문자열을 반환하며, 이 문자열은 스트림의 인접한 코드 포인트에서 구성할 수 있는 가장 긴 이름을 첫 번째 코드 포인트부터 포함합니다.
참고: 이 알고리즘은 반환된 코드 포인트가 <ident-token>을 구성하도록 보장하는 데 필요한 처음 몇 코드 포인트의 검증을 수행하지 않습니다. 이것이 의도한 용도라면, 이 알고리즘을 호출하기 전에 스트림이 식별자 시퀀스로 시작하는지 확인하십시오.
result를 처음에 빈 문자열로 둡니다.
스트림에서 다음 입력 코드 포인트를 반복해서 소비합니다:
- 식별자 코드 포인트
- 코드 포인트를 result에 추가합니다.
- 스트림이 유효한 이스케이프로 시작함
- 이스케이프된 코드 포인트를 소비합니다. 반환된 코드 포인트를 result에 추가합니다.
- 그 밖의 모든 것
- 현재 입력 코드 포인트를 다시 소비합니다. result를 반환합니다.
4.3.13. 숫자를 소비하기
이 절에서는 코드 포인트 스트림에서 숫자를 소비하는 방법을 설명합니다. 숫자 value, "integer" 또는 "number" 중 하나인 문자열 type, 그리고 "+", "-" 또는 누락 중 하나인 선택적 sign character를 반환합니다.
참고: 이 알고리즘은 스트림에서 숫자를 얻을 수 있도록 보장하는 데 필요한 처음 몇 코드 포인트의 검증을 수행하지 않습니다. 이 알고리즘을 호출하기 전에 스트림이 숫자로 시작하는지 확인하십시오.
다음 단계를 순서대로 수행합니다:
- type을 문자열 "integer"로 둡니다. number part와 exponent part를 빈 문자열로 둡니다.
- 다음 입력 코드 포인트가 U+002B PLUS SIGN (+) 또는 U+002D HYPHEN-MINUS (-)이면, 이를 소비합니다. 이를 number part에 추가하고 sign character를 그것으로 설정합니다.
- 다음 입력 코드 포인트가 숫자인 동안, 이를 소비하고 number part에 추가합니다.
-
다음 2개의
입력 코드 포인트가
U+002E FULL STOP (.) 뒤에 숫자가 오는 경우,
다음을 수행합니다:
- 다음 입력 코드 포인트를 소비하고 number part에 추가합니다.
- 다음 입력 코드 포인트가 숫자인 동안 이를 소비하고 number part에 추가합니다.
- type을 "number"로 설정합니다.
-
다음 2개
또는 3개의 입력 코드 포인트가
U+0045 LATIN CAPITAL LETTER E (E) 또는 U+0065 LATIN SMALL LETTER E (e)이고,
선택적으로 그 뒤에 U+002D HYPHEN-MINUS (-) 또는 U+002B PLUS SIGN (+)가 오며,
이어서 숫자가 오면,
다음을 수행합니다:
- 다음 입력 코드 포인트를 소비합니다.
- 다음 입력 코드 포인트가 "+" 또는 "-"이면, 이를 소비하고 exponent part에 추가합니다.
- 다음 입력 코드 포인트가 숫자인 동안 이를 소비하고 exponent part에 추가합니다.
- type을 "number"로 설정합니다.
-
value를 number part를
10진수로 해석한 결과로 둡니다.
exponent part가 비어 있지 않으면, 이를 10진수 정수로 해석하고, 10을 그 결과의 거듭제곱으로 올린 다음, 이를 value와 곱하고, value를 그 결과로 설정합니다.
- value, type 및 sign character를 반환합니다.
4.3.14. unicode-range 토큰을 소비하기
이 절에서는 unicode-range 토큰을 소비하는 방법을 설명합니다 코드 포인트 스트림에서. <unicode-range-token>을 반환합니다.
참고: 이 알고리즘은 반환된 코드 포인트가 <unicode-range-token>을 구성하도록 보장하는 데 필요한 처음 몇 코드 포인트의 검증을 수행하지 않습니다. 이 알고리즘을 호출하기 전에 스트림이 unicode-range를 시작하는지 확인하십시오.
참고: 이 토큰은 정상적인 상황에서는 토큰화기에 의해 생성되지 않습니다. 이 알고리즘은 unicode-range 설명자의 값을 소비하기 중에만 호출되며, 이 알고리즘 자체도 특수한 경우에만 호출됩니다 unicode-range 설명자를 파싱하기 위한; 전체 언어에서 이 한 번뿐인 호출은 초기 CSS의 잘못된 구문 설계 때문입니다.
-
다음 두 입력 코드 포인트를 소비하고 버립니다.
-
가능한 한 많은 16진수 숫자를 소비하되, 6개를 초과하지 않습니다. 6개보다 적은 16진수 숫자를 소비했다면, 가능한 한 많은 U+003F QUESTION MARK (?) 코드 포인트를 소비하되, 16진수 숫자와 U+003F QUESTION MARK (?) 코드 포인트의 총 개수가 6이 되도록 하는 데 필요한 수를 초과하지 않습니다.
first segment를 소비된 코드 포인트로 둡니다.
-
first segment에 물음표 코드 포인트가 하나라도 포함되어 있으면:
-
first segment의 물음표를 U+0030 DIGIT ZERO (0) 코드 포인트로 바꾸고, 그 결과를 16진수로 해석합니다. 이를 start of range로 둡니다.
-
first segment의 물음표를 U+0046 LATIN CAPITAL LETTER F (F) 코드 포인트로 바꾸고, 그 결과를 16진수로 해석합니다. 이를 end of range로 둡니다.
-
start of range에서 시작하여 end of range에서 끝나는 새로운 <unicode-range-token>을 반환합니다.
-
-
그렇지 않으면 first segment를 16진수로 해석하고, 그 결과를 start of range로 둡니다.
-
다음 2개의 입력 코드 포인트가 U+002D HYPHEN-MINUS (-)이고 그 뒤에 16진수 숫자가 오면, 다음을 수행합니다:
-
다음 입력 코드 포인트를 소비합니다.
-
가능한 한 많은 16진수 숫자를 소비하되 6개를 초과하지 않습니다. 소비된 코드 포인트를 16진수로 해석합니다. 이를 end of range로 둡니다.
-
start of range에서 시작하여 end of range에서 끝나는 새로운 <unicode-range-token>을 반환합니다.
-
-
그렇지 않으면 시작과 끝이 모두 start of range인 새로운 <unicode-range-token>을 반환합니다.
4.3.15. 잘못된 URL의 나머지를 소비하기
이 절에서는 코드 포인트 스트림에서 잘못된 URL의 나머지를 소비하는 방법을 설명하며, 토큰화기가 자신이 <url-token>이 아니라 <bad-url-token>의 중간에 있음을 깨달은 뒤 "정리"합니다. 아무것도 반환하지 않습니다; 유일한 용도는 입력 스트림을 충분히 소비하여 복구 지점에 도달하고 정상적인 토큰화를 다시 시작할 수 있도록 하는 것입니다.
스트림에서 다음 입력 코드 포인트를 반복해서 소비합니다:
- U+0029 RIGHT PARENTHESIS ())
- EOF
- 반환합니다.
- 입력 스트림이 유효한 이스케이프로 시작함
- 이스케이프된 코드 포인트를 소비합니다. 이를 통해 이스케이프된 오른쪽 괄호 ("\)")를 만나도 <bad-url-token>이 끝나지 않습니다. 그 밖에는 "그 밖의 모든 것" 절과 동일합니다.
- 그 밖의 모든 것
- 아무것도 하지 않습니다.
5. 파싱
CSS 파서는 토큰 스트림을 변환합니다 (토큰화 프로세스에서 생성되고, 이 명세의 앞부분에서 정의됨) 여러 CSS 구문 중 하나 이상으로 (호출되는 파싱 알고리즘에 따라).
5.1. 파서 철도 다이어그램
이 절은 비규범적입니다.
이 절에서는 파서의 정보 제공용 보기를 제시하며, 철도 다이어그램 형태로 제공합니다.
이 다이어그램은 정보 제공용이며 불완전합니다; "올바른" 스타일시트의 문법을 설명하지만, 오류 처리는 전혀 설명하지 않습니다. 구문을 직관적으로 이해하기 쉽게 하기 위한 목적으로만 제공됩니다.
- 스타일시트
-
- at-규칙
-
- 한정 규칙
-
- {} 블록
-
- 선언
-
- !important
-
- 구성 요소 값
-
- 단순 블록
-
- 함수 블록
-
5.2. CSS 파싱 결과
파싱 결과는 다음 중 하나일 수 있으며 (또는 이들의 목록일 수 있습니다):
- 스타일시트
-
스타일시트에는 규칙 목록이 있습니다.
- 규칙
- at-규칙
- at-규칙에는 문자열인 이름과, 구성 요소 값 목록으로 구성된 프렐류드가 있습니다. 블록 at-규칙은 ({}-블록으로 끝나며) 추가로 선언 목록과 자식 규칙 목록을 가집니다. (문형 at-규칙은 세미콜론으로 끝나며, 그렇지 않습니다.)
- 한정 규칙
-
한정 규칙에는
구성 요소 값 목록으로 구성된 프렐류드,
선언 목록,
그리고 자식 규칙 목록이 있습니다.
참고: 대부분의 한정 규칙은 스타일 규칙이며, 여기서 프렐류드는 선택자 [selectors-4]이고 선언은 속성입니다.
- 선언
-
선언에는 문자열인
이름과,
구성 요소 값 목록으로 구성된 값,
그리고 처음에는 설정되지 않은 important 플래그가 있습니다.
또한 선택적인 original text가 있으며, 이는 문자열입니다
(일부 선언에 대해서만 캡처됩니다).
선언은 추가로 속성 선언 또는 설명자 선언으로 분류되며, 전자는 CSS 속성을 설정하고 주로 한정 규칙에 나타나며 후자는 CSS 설명자를 설정하고, 이는 at-규칙에만 나타납니다. (이 분류는 Syntax 수준에서는 이루어지지 않습니다; 대신 선언이 나타나는 위치의 결과이며, 해당 규칙을 정의하는 각 명세에서 정의됩니다.)
- 구성 요소 값
- 구성 요소 값은 보존된 토큰, 함수, 또는 단순 블록 중 하나입니다.
- 보존된 토큰
-
토큰화기가 생성하는 모든 토큰
중 <function-token>,
<{-token>,
<(-token>,
및 <[-token>을 제외한 것입니다.
참고: 위에 나열된 비-보존된 토큰은 항상 상위 수준 객체, 즉 함수 또는 단순 블록으로 소비되므로, 그 자체로는 어떤 파서 출력에도 나타나지 않습니다.
참고: 토큰 <}-token>, <)-token>, <]-token>, <bad-string-token>, 및 <bad-url-token>은 항상 파싱 오류이지만, 이 명세에서는 다른 명세가, 예를 들어 Media Queries가, 전체 선언이나 블록을 버리는 것보다 더 세밀한 오류 처리를 정의할 수 있도록 토큰 스트림에 보존합니다.
- 함수
- 함수에는 이름과 구성 요소 값 목록으로 구성된 값이 있습니다.
- 단순
블록
- {}-블록
- []-블록
- ()-블록
- {}-블록
- 단순 블록에는 연관된 토큰(<[-token>, <(-token>, 또는 <{-token> 중 하나)과 구성 요소 값 목록으로 구성된 값이 있습니다.
5.3. 토큰 스트림
토큰 스트림은 구조체로, 토큰 및/또는 구성 요소 값의 스트림을 나타냅니다. 다음 항목을 가집니다:
- 토큰
-
참고: 이 명세에서는 단순화를 위해, 파싱을 시작하기 전에 입력 스트림이 완전히 토큰화되었다고 가정합니다. 그러나 파싱 알고리즘은 "미리 보기" 토큰 하나만 사용하므로, 실제로는 토큰화와 파싱을 동시에 진행할 수 있습니다.
- 인덱스
-
토큰에 대한 인덱스로, 파싱 진행 상황을 나타냅니다. 처음에는 0에서 시작합니다.
참고: 표시를 제외하면, 인덱스는 절대 뒤로 이동하지 않습니다. 따라서 이미 처리된 토큰의 접두 부분은 처리되는 즉시 버릴 수 있습니다.
- 표시된 인덱스
-
인덱스 값의 스택으로, 파서가 돌아갈 수 있는 지점을 나타냅니다. 처음에는 비어 있습니다.
CSS에는 선언 값에 대해 파싱된 정확한 텍스트를 참조해야 하는 몇몇 위치가 있습니다 (해당 텍스트에서 어떤 토큰이 생성되었는지만이 아닙니다). 이는 여기의 알고리즘 구조에 명시적으로 설명되어 있지는 않지만, 따라서 토큰 스트림은 필요할 때 선언의 원래 텍스트를 재현할 수 있어야 합니다. 이것이 필요한 시점에 대한 자세한 내용은 선언을 소비하기를 참조하십시오.
토큰 스트림에 대해 여러 연산을 수행할 수 있습니다:
- 다음 토큰
-
해당 인덱스가 목록의 끝을 벗어나게 된다면, 대신 <eof-token>입니다.
- 비어 있음
-
다음 토큰이 <eof-token>이면 토큰 스트림은 비어 있습니다.
- 토큰을 소비하기
- 토큰을 버리기
- 표시하기
- 표시를 복원하기
- 표시를 버리기
- 공백을 버리기
-
다음 토큰이 <whitespace-token>인 동안, 토큰을 버립니다.
- 처리하기
-
처리하려면, 다음 토큰 유형과 관련 작업 목록이 주어졌을 때, 다음 토큰과 관련된 작업을 수행합니다. 작업 중 하나가 무언가를 반환할 때까지 반복하고, 그런 다음 그것을 반환합니다.
<eof-token>은 개념적인 토큰으로, 실제로 토큰화기가 생성하지 않으며, 토큰 스트림이 소진되었음을 나타내는 데 사용됩니다.
5.4. 파서 진입점
이 절에서 정의한 알고리즘은 고수준 CSS 객체를 CSS 토큰 목록으로부터 생성합니다.
주어진 input을 토큰 스트림으로 정규화하려면:
참고: 다른 명세는 자체 목적을 위한 추가 진입점을 정의할 수 있습니다.
- "스타일시트를 파싱하기"는 일반적인 파서 진입점으로 사용되도록 의도되며, 스타일시트를 파싱하는 데 사용됩니다.
-
"스타일시트의 내용을 파싱하기"는
다음
CSSStyleSheet replace()메서드와 유사한 것에 사용하도록 의도되며, 텍스트를 기존 스타일시트의 내용으로 파싱합니다. -
"규칙을 파싱하기"는
다음
CSSStyleSheet insertRule()메서드와 유사한 것에 사용하도록 의도되며, 텍스트를 하나의 규칙으로 파싱합니다.CSSStyleSheet#insertRule메서드와, 존재할 수 있는 유사한 함수들도 텍스트를 하나의 규칙으로 파싱합니다. - "선언을 파싱하기"는 @supports 조건에서 사용됩니다. [CSS3-CONDITIONAL]
-
"블록의
내용을 파싱하기"는 CSS의 모든 블록 내용을 파싱하는 데 사용하도록 의도되며
(style 속성과 같은 것도 포함),
CSSStyleDeclaration cssText 속성과 같은 API에도 사용됩니다. - "구성 요소 값을 파싱하기"는 하나의 값을 소비해야 하는 것에 사용되며, 예를 들어 attr()의 파싱 규칙이 있습니다.
-
"구성 요소 값 목록을 파싱하기"는
표현 속성의 내용에 사용되며,
텍스트를 하나의 선언 값으로 파싱하거나,
독립형 선택자 [SELECT] 또는
Media Queries 목록 [MEDIAQ]을
파싱하는 데 사용되며,
예를 들어 Selectors API
또는
mediaHTML 속성이 있습니다.
5.4.1. CSS 문법에 따라 무언가를 파싱하기
문자열이나 토큰 목록을 파싱하여 특정 CSS 문법과 일치하는지 확인하고, 일치한다면, 문법에 따라 이를 구조 분해하는 것이 유용한 경우가 많습니다. 이 절에서는 이러한 종류의 연산을 위한 일반적인 훅을 제공합니다. 다음과 같이 호출해야 합니다 "foo를 CSS <color>로 파싱"하거나 이와 비슷하게 호출합니다.
이 알고리즘은 실패 또는, 입력이 제공된 문법과 일치하지 않는 경우, 문법에 따라 입력을 파싱한 결과를 반환하며, 이는 제공된 문법 명세에 대응하는 지정되지 않은 구조입니다. 반환 값은 명세 산문에서만 다루어야 하며, 그곳에서는 표현의 모호성이 문제가 되지 않습니다. 명세 언어 밖에 노출하려는 경우, 결과를 사용하는 명세는 이를 잘 정의된 표현으로 명시적으로 변환해야 하며, 예를 들어 CSS 직렬화 알고리즘을 호출하는 방식이 있습니다 (예: "CSS <string> 값으로 직렬화").
참고: 이 알고리즘과 CSS 문법에 따라 쉼표로 구분된 목록을 파싱하기는 일반적으로 다른 명세가 호출하려는 유일한 파싱 알고리즘입니다. 나머지 파싱 알고리즘은 주로 [CSSOM]과 관련된 "CSS 구조를 명시적으로 구성하는" 경우를 위한 것입니다. 다른 알고리즘 중 하나를 사용해야 한다고 생각한다면 먼저 CSSWG에 지침을 문의하십시오.
- input을 정규화하고, input을 그 결과로 설정합니다.
- input에서 구성 요소 값 목록을 파싱하고, 반환 값을 result로 둡니다.
- result를 grammar와 일치시키려고 시도합니다. 성공하면, 일치한 결과를 반환하고; 그렇지 않으면 실패를 반환합니다.
5.4.2. CSS 문법에 따라 쉼표로 구분된 목록을 파싱하기
물론 쉼표를 포함한 문법에 따라 값을 파싱할 수 있지만, 값의 어느 부분이라도 파싱에 실패하면, 전체가 파싱되지 않고, 실패를 반환합니다.
때로는 그것이 원하는 동작이며
(목록 값을 갖는 CSS 속성 등);
다른 경우에는,
쉼표로 구분된 값의 각 하위 부분을 별도로 파싱하도록 하는 것이 더 좋으며,
성공적으로 파싱되는 부분은 한 방식으로 처리하고,
파싱에 실패하는 부분은 다른 방식으로 처리합니다
(일반적으로 이를 무시하며,
예를 들어
<img sizes>가
있습니다).
이 알고리즘은 정확히 이를 수행하기 위한 간편한 훅을 제공합니다. "최상위" 쉼표로 분할된 값 목록을 반환하며, 각 값은 실패이거나 (파싱에 실패한 경우) 파싱 결과입니다 (지정되지 않은 구조이며, 파싱 알고리즘에서 설명한 것과 같습니다).
- input을 정규화하고, input을 그 결과로 설정합니다.
- input에 <whitespace-token>만 포함되어 있으면, 빈 목록을 반환합니다.
- input에서 쉼표로 구분된 구성 요소 값 목록을 파싱하고, 반환 값을 list로 둡니다.
- list의 각 item에 대해 각각, item을 grammar으로 item을 파싱한 결과로 대체합니다.
- list를 반환합니다.
5.4.3. 스타일시트를 파싱하기
- input이 스타일시트의 바이트 스트림이면, input에서 바이트를 디코딩하고, input을 그 결과로 설정합니다.
- input을 정규화하고, input을 그 결과로 설정합니다.
- 새 스타일시트를 생성하고, 그 위치를 location으로 설정합니다 (location이 전달되지 않았다면 null).
- input에서 스타일시트의 내용을 소비하고, 스타일시트의 규칙을 그 결과로 설정합니다.
- 스타일시트를 반환합니다.
5.4.4. 스타일시트의 내용을 파싱하기
- input을 정규화하고, input을 그 결과로 설정합니다.
- input에서 스타일시트의 내용을 소비하고, 그 결과를 반환합니다.
5.4.5. 블록의 내용을 파싱하기
- input을 정규화하고, input을 그 결과로 설정합니다.
- input에서 블록의 내용을 소비하고, 그 결과를 반환합니다.
5.4.6. 규칙을 파싱하기
- input을 정규화하고, input을 그 결과로 설정합니다.
- input에서 공백을 버립니다.
-
input의 다음 토큰이 <EOF-token>이면,
구문 오류를 반환합니다.
그렇지 않고, input의 다음 토큰이 <at-keyword-token>이면, input에서 at-규칙을 소비하고, 반환 값을 rule로 둡니다.
그렇지 않으면, input에서 한정 규칙을 소비하고 반환 값을 rule로 둡니다. 아무것도 반환되지 않았거나 유효하지 않은 규칙 오류가 반환되었다면, 구문 오류를 반환합니다.
- input에서 공백을 버립니다.
- input의 다음 토큰이 <EOF-token>이면, rule을 반환합니다. 그렇지 않으면 구문 오류를 반환합니다.
5.4.7. 선언을 파싱하기
참고: "선언 목록을 파싱하기"와 달리, 이는 at-규칙이 아니라 선언 하나만 파싱합니다.
5.4.8. 구성 요소 값을 파싱하기
5.4.9. 구성 요소 값 목록을 파싱하기
-
input을 정규화하고, input을 그 결과로 설정합니다.
-
input에서 구성 요소 값 목록을 소비하고, 그 결과를 반환합니다.
5.4.10. 쉼표로 구분된 구성 요소 값 목록을 파싱하기
-
input을 정규화하고, input을 그 결과로 설정합니다.
-
groups를 빈 목록으로 둡니다.
-
input이 비어 있지 않은 동안:
-
input에서 구성 요소 값 목록을 소비하고, <comma-token>을 중지 토큰으로 사용하여, 그 결과를 groups에 추가합니다.
-
input에서 토큰을 버립니다.
-
-
groups를 반환합니다.
5.5. 파서 알고리즘
다음 알고리즘들이 파서를 구성합니다. 위의 파서 진입점에서 호출되며, 일반적으로 다른 명세에서 직접 호출해서는 안 됩니다.
CSS 파싱은 대소문자를 구분하며, 주어진 컨텍스트에서 구문의 유효성을 확인하는 작업은 적어도 일부 상황에서는 파싱 중에 수행되어야 합니다. 이 명세는 의도적으로 유효성 검사를 가능하게 하기 위해 충분한 컨텍스트를 어떻게 전달해야 하는지는 지정하지 않습니다.
5.5.1. 스타일시트의 내용을 소비하기
토큰 스트림 input에서 스타일시트의 내용을 소비하려면:
rules를 처음에는 비어 있는 규칙의 목록으로 둡니다.
input을 처리합니다:
- <whitespace-token>
- input에서 토큰을 버립니다.
- <EOF-token>
- rules를 반환합니다.
- <CDO-token>
- <CDC-token>
- input에서 토큰을 버립니다.
- <at-keyword-token>
- input에서 at-규칙을 소비합니다. 무언가가 반환되면, 이를 rules에 추가합니다.
- 그 밖의 모든 것
- input에서 한정 규칙을 소비합니다. 규칙이 반환되면, 이를 rules에 추가합니다.
5.5.2. at-규칙을 소비하기
선택적 bool nested(기본값 false)가 주어졌을 때, 토큰 스트림 input에서 at-규칙을 소비하려면:
단언: 다음 토큰은 <at-keyword-token>입니다.
input에서 토큰을 소비하고, rule을 새 at-규칙으로 두며, 그 이름을 반환된 토큰의 값으로 설정하고, 프렐류드는 처음에 빈 목록으로 설정하며, 선언이나 자식 규칙은 없도록 합니다.
input을 처리합니다:
- <semicolon-token>
- <EOF-token>
- input에서 토큰을 버립니다. rule이 현재 컨텍스트에서 유효하면, 이를 반환하고; 그렇지 않으면 아무것도 반환하지 않습니다.
- <}-token>
-
nested가 true이면:
-
rule이 현재 컨텍스트에서 유효하면, 이를 반환합니다.
-
그렇지 않으면 아무것도 반환하지 않습니다.
그렇지 않으면 토큰을 소비하고 그 결과를 rule의 프렐류드에 추가합니다.
-
- <{-token>
-
input에서 블록을
소비하고,
그 결과를 rule의 자식 규칙에 할당합니다.
참고: 결과에 목록 형태의 선언이 포함된 경우, CSSOM에서 이를 어떻게 구체화하는지는 규칙에 따라 달라집니다. 일부는 모두 중첩 선언 규칙으로 만들고, 다른 일부는 모두 선언으로 처리하며, 또 다른 일부는 첫 번째 항목을 나머지와 다르게 처리합니다.
rule이 현재 컨텍스트에서 유효하면, 이를 반환합니다. 그렇지 않으면 아무것도 반환하지 않습니다.
- 그 밖의 모든 것
- input에서 구성 요소 값을 소비하고 반환된 값을 rule의 프렐류드에 추가합니다.
5.5.3. 한정 규칙을 소비하기
선택적 토큰 stop token과 선택적 bool nested(기본값 false)가 주어졌을 때, 토큰 스트림 input에서 한정 규칙을 소비하려면:
rule을 새 한정 규칙으로 두고 그 프렐류드, 선언 및 자식 규칙을 모두 처음에는 빈 목록으로 설정합니다.
input을 처리합니다:
- <EOF-token>
- stop token (전달된 경우)
- 이는 파싱 오류입니다. 아무것도 반환하지 않습니다.
- <}-token>
- 이는 파싱 오류입니다. nested가 true이면, 아무것도 반환하지 않습니다. 그렇지 않으면, 토큰을 소비하고 그 결과를 rule의 프렐류드에 추가합니다.
- <{-token>
-
rule의 프렐류드에서 처음 두 개의 비-<whitespace-token> 값이
값이 "--"로 시작하는 <ident-token>이고
그 뒤에 <colon-token>이 오면:
-
nested가 true이면, input에서 잘못된 선언의 나머지를 소비하고, nested를 true로 설정한 다음, 아무것도 반환하지 않습니다.
-
nested가 false이면, input에서 블록을 소비하고, 아무것도 반환하지 않습니다.
이 검사는 무엇을 위한 것입니까?
선언과 한정 규칙은 허용되는 구문이 일반적으로 겹치지 않습니다. 현재 정의된 어떤 CSS 속성도 값에 {}-블록을 허용하지 않으므로,
foo:bar {};는 확실히 규칙이고,foo: bar;는 확실히 속성입니다. 향후 CSS 속성이 값에 {}-블록을 허용하더라도, 허용되는 구문은 {}-블록이 전체 값인 경우로 제한됩니다, 예를 들어foo: {...};이며, 이는 유효한 규칙일 수 없도록 보장됩니다, : 뒤에 식별자나 함수가 없어 의사 클래스로 표시할 수 없기 때문입니다.이를 통해 같은 컨텍스트에서 선언과 규칙을 혼합할 수 있습니다: 먼저 무언가를 선언으로 파싱하려고 시도하고, 그 결과 유효한 선언이 되지 않으면, 대신 규칙으로 다시 파싱합니다. 실수로 유효하지 않게 된 선언은 대신 규칙으로 파싱되지만, 문제없습니다: 파서는 선언의 끝 세미콜론에서 멈추고 이를 유효하지 않은 규칙으로 간주합니다. (또는 {}-블록을 포함하는 속성의 경우, 세미콜론 바로 *앞*에서 멈추고, 여전히 유효하지 않은 규칙으로 간주하며, 그 다음 무언가를 파싱하려는 시도에서 홀로 남은 세미콜론을 유효하지 않은 것으로 버립니다.) 따라서 소비되는 전체 토큰 수는 어느 경우든 동일합니다.
그러나 사용자 정의 속성은 CSSWG가 그 구문을 신중하게 검토하지 않습니다. 작성자는 값에 {}-블록을 받는 사용자 정의 속성을 작성할 수 있으며, 다른 것과 결합할 수도 있습니다; 그 사용자 정의 속성이 이후 유효하지 않게 되면 (예를 들어 잘못 작성된 var() 함수 때문에), 규칙으로 다시 파싱될 때 {}-블록에서 일찍 멈춥니다. 그러면 사용자 정의 속성 값의 나머지 토큰은 새로운 구문으로 파싱되어, 잠재적으로 예상치 못한 선언이나 규칙이 생성될 수 있습니다.
이 (물론 매우 드문) 코너 케이스를 피하기 위해, 사용자 정의 속성의 구문을 한정 규칙의 구문에서 제외합니다; 속성과 규칙을 혼합할 수 있는 컨텍스트에서 어떤 이유로 규칙을 파싱했는데 그것이 사용자 정의 속성처럼 보인다면, 잘못 처리한 것이며, 대신 전체 사용자 정의 속성을 (끝 세미콜론까지 모두) 소비해야 합니다.
(속성을 허용하지 않는 컨텍스트에 있다면, 사용자 정의 속성처럼 보이는 경우 규칙을 그냥 버립니다. 이렇게 하면
--foo:hover { color: blue; }가 어디서나 일관되게 유효하지 않도록 하면서, 존재하지 않는 끝 세미콜론을 찾느라 스타일시트의 많은 부분을 소비하는 일을 방지합니다.)그렇지 않으면 input에서 블록을 소비하고, 그 결과를 child rules로 둡니다. child rules의 첫 번째 항목이 목록 형태의 선언이면, 이를 child rules에서 제거하고 rule의 선언에 할당합니다. child rules의 남은 항목 중 목록 형태의 선언이 있으면, 이를 중첩 선언 규칙으로 바꾸며 해당 목록을 유일한 자식으로 포함시킵니다. child rules를 rule의 자식 규칙에 할당합니다.
rule이 현재 컨텍스트에서 유효하면, 이를 반환하고; 그렇지 않으면 유효하지 않은 규칙 오류를 반환합니다.
-
- 그 밖의 모든 것
- input에서 구성 요소 값을 소비하고 그 결과를 rule의 프렐류드에 추가합니다.
5.5.4. 블록을 소비하기
토큰 스트림 input에서 블록을 소비하려면:
input에서 토큰을 버립니다. input에서 블록의 내용을 소비하고 그 결과를 rules로 둡니다. input에서 토큰을 버립니다.
rules를 반환합니다.
5.5.5. 블록의 내용을 소비하기
토큰 스트림 input에서 블록의 내용을 소비하려면:
참고: 이 알고리즘은 목록을 반환하며,
규칙과 목록 형태의 선언으로 구성됩니다.
부모 컨텍스트에 따라,
목록 형태의 선언은
CSSOM에서 다음 중 하나로 구체화될 수 있습니다
CSSStyleDeclaration,
또는 CSSNestedDeclarations
규칙으로.
rules를 빈 목록으로 두며, 규칙 또는 목록 형태의 선언을 포함합니다.
input을 처리합니다:
- <whitespace-token>
- <semicolon-token>
- input에서 토큰을 버립니다.
- <EOF-token>
- <}-token>
- rules를 반환합니다.
- <at-keyword-token>
-
decls가 비어 있지 않으면,
이를 rules에 추가하고,
decls를 새로운 빈 목록 형태의 선언으로 설정합니다.
input에서 at-규칙을 소비하고, nested를 true로 설정합니다. 규칙이 반환되었다면, 이를 rules에 추가합니다.
- 그 밖의 모든 것
-
input을 표시합니다.
input에서 선언을 소비하고, nested를 true로 설정합니다. 선언이 반환되었다면, 이를 decls에 추가하고, input에서 표시를 버립니다.
그렇지 않으면 input에서 표시를 복원하고, 그 다음 input에서 한정 규칙을 소비하며, nested를 true로 설정하고, <semicolon-token>을 stop token으로 사용합니다.
구현 참고 사항
이 명세는 많은 CSS 명세와 마찬가지로, 효율성보다 이해하기 쉬운 것을 우선하도록 작성되었습니다. 여러 알고리즘, 특히 위의 "선언으로 파싱한 다음 규칙으로 파싱"하는 동작은 설명된 그대로 순진하게 구현하면 상당히 비효율적일 수 있습니다.
그러나 이 동작은 가능한 한 "조기 종료"를 허용하도록 신중하게 작성되었습니다. 특히, 대략 종료가 발생할 수 있는 순서대로:
-
첫 번째 비공백 토큰이 인식되는 속성 이름(또는 사용자 정의 속성 이름)의 <ident-token>이 아니라면, 선언으로 파싱하는 것을 즉시 중단하고 대신 규칙으로 다시 파싱할 수 있습니다. 다음 비공백 토큰이 <colon-token>이 아니라면, 마찬가지로 선언으로 파싱하는 것을 즉시 중단할 수 있습니다.
(즉, font+ ...는 속성이 아님이 보장되며, not-a-prop-name: ...도 마찬가지입니다.)
-
처음 두 비공백 토큰이 사용자 정의 속성 이름과 콜론이면, 확실히 사용자 정의 속성이며 유효한 규칙이 될 수 없으므로, 사용자 정의 속성이 결국 유효하지 않게 되더라도 규칙으로 다시 파싱할 필요가 없습니다.
(즉, --foo:hover {...}는 규칙이 아니라 사용자 정의 속성임이 보장됩니다.)
-
처음 세 비공백 토큰이 유효한 속성 이름, 콜론, 그리고 <{-token>이 아닌 어떤 것이고, 선언 값을 파싱하는 동안 <{-token>을 만나면, 선언으로 파싱하는 것을 즉시 중단하고 대신 규칙으로 다시 파싱할 수 있습니다.
(즉, font:bar {...는 유효하지 않은 속성임이 보장됩니다.)
-
인식되는 속성 이름, 콜론 및 {}-블록을 보았지만, 그 블록 뒤의 첫 번째 비공백 토큰이 바로 마지막 세미콜론이 아니고, 또는 !important 뒤에 세미콜론이 오는 것도 아니라면, 선언으로 파싱하는 것을 즉시 중단하고 대신 규칙으로 다시 파싱할 수 있습니다.
(즉, font: {} bar ...는 유효하지 않은 속성임이 보장됩니다; 세미콜론을 만날 때까지 계속 파싱할 필요가 없습니다.)
마찬가지로, 파싱 요구 사항은 선언을 파싱하면서 그 문법을 검사하는 데 의존하도록 지정되어 있지만, 일반 CSS 구문 위에 CSS가 아닌 언어를 구현하려는 일반적인 프로세서는 선언이 식별자, 콜론으로 시작하는지만 확인하고, 그 뒤에 오직 {}-블록만 포함하거나 {}-블록을 전혀 포함하지 않는지만 확인해도 됩니다. foo:hover ... {} 같은 경우에는 첫 번째 토큰에서 조기 종료할 수 없으므로 문법을 알고 있는 구현보다 파싱에 약간 더 많은 시간을 쓸 뿐입니다.
5.5.6. 선언을 소비하기
선택적 bool nested(기본값 false)가 주어졌을 때, 토큰 스트림 input에서 선언을 소비하려면:
decl을 새 선언으로 두며, 이름은 처음에 비어 있고 값은 빈 목록으로 설정합니다.
-
다음 토큰이
<ident-token>이면,
input에서 토큰을 소비하고
decl의 이름을
해당 토큰의 값으로 설정합니다.
그렇지 않으면, input에서 잘못된 선언의 나머지를 소비하고, nested와 함께, 아무것도 반환하지 않습니다.
- input에서 공백을 버립니다.
-
다음
토큰이 <colon-token>이면,
input에서 토큰을 버립니다.
그렇지 않으면, input에서 잘못된 선언의 나머지를 소비하고, nested와 함께, 아무것도 반환하지 않습니다.
- input에서 공백을 버립니다.
- input에서 구성 요소 값 목록을 소비하고, nested와 함께, <semicolon-token>을 중지 토큰으로 사용하여, decl의 값을 그 결과로 설정합니다.
- decl의 값에서 마지막 두 비-<whitespace-token>이 값이 "!"인 <delim-token>이고 그 뒤에 값이 "important"와 ASCII 대소문자를 구분하지 않고 일치하는 <ident-token>이 오면, 이를 decl의 값에서 제거하고 decl의 important 플래그를 설정합니다.
- decl의 값에서 마지막 항목이 <whitespace-token>인 동안, 해당 토큰을 제거합니다.
-
decl의 이름이 사용자 정의 속성 이름 문자열이면,
decl의 original text를
원래 소스 텍스트 문자열에서
decl 값의 토큰에
해당하는 구간으로 설정합니다.
그렇지 않고 decl의 값에 연관된 토큰이 <{-token>인 최상위 단순 블록이 포함되어 있고 또한 다른 어떤 비-<whitespace-token> 값도 포함되어 있다면, 아무것도 반환하지 않습니다. (즉, 최상위 {}-블록은 비사용자 정의 속성의 전체 값으로만 허용됩니다.)
그렇지 않고 decl의 이름이 "unicode-range"와 ASCII 대소문자를 구분하지 않고 일치하면, unicode-range 설명자의 값을 소비하고 원래 소스 텍스트 문자열에서 구성 요소 값 목록을 소비하기 호출이 반환한 토큰에 해당하는 구간을 사용하며, decl의 값을 그 결과로 바꿉니다.
- decl이 현재 컨텍스트에서 유효하면, 이를 반환하고; 그렇지 않으면 아무것도 반환하지 않습니다.
input을 처리합니다:
- <eof-token>
- <semicolon-token>
-
input에서 토큰을 버리고, 아무것도 반환하지 않습니다.
- <}-token>
-
nested가 true이면, 아무것도 반환하지 않습니다. 그렇지 않으면, 토큰을 버립니다.
- 그 밖의 모든 것
-
input에서 구성 요소 값을 소비하고, 아무것도 하지 않습니다.
5.5.7. 구성 요소 값 목록을 소비하기
선택적 토큰 stop token과 선택적 boolean nested(기본값 false)가 주어졌을 때, 토큰 스트림 input에서 구성 요소 값 목록을 소비하려면:
input을 처리합니다:
- <eof-token>
- stop token (전달된 경우)
-
values를 반환합니다.
- <}-token>
-
nested가 true이면, values를 반환합니다.
- 그 밖의 모든 것
-
input에서 구성 요소 값을 소비하고, 그 결과를 values에 추가합니다.
5.5.8. 구성 요소 값을 소비하기
토큰 스트림 input에서 구성 요소 값을 소비하려면:
input을 처리합니다:
- <{-token>
- <[-token>
- <(-token>
- <[-token>
-
input에서 단순 블록을 소비하고 그 결과를 반환합니다.
- <function-token>
-
input에서 함수를 소비하고 그 결과를 반환합니다.
- 그 밖의 모든 것
-
input에서 토큰을 소비하고 그 결과를 반환합니다.
5.5.9. 단순 블록을 소비하기
토큰 스트림 input에서 단순 블록을 소비하려면:
단언: input의 다음 토큰은 <{-token>, <[-token>, 또는 <(-token>입니다.
ending token을 다음 토큰의 미러 변형으로 둡니다. (예를 들어 <[-token>으로 호출되었다면, ending token은 <]-token>입니다.)
block을 새 단순 블록으로 두고, 연관된 토큰을 다음 토큰으로 설정하며 그 값은 처음에 빈 목록으로 설정합니다.
input에서 토큰을 버립니다.
input을 처리합니다:
- <eof-token>
- ending token
-
input에서 토큰을 버립니다. block을 반환합니다.
- 그 밖의 모든 것
-
input에서 구성 요소 값을 소비하고 그 결과를 block의 값에 추가합니다.
5.5.10. 함수를 소비하기
토큰 스트림 input에서 함수를 소비하려면:
단언: 다음 토큰은 <function-token>입니다.
input에서 토큰을 소비하고, function을 새 함수로 두며 그 이름은 반환된 토큰의 값과 같고, 값은 빈 목록으로 설정합니다.
input을 처리합니다:
- <eof-token>
- <)-token>
-
input에서 토큰을 버립니다. function을 반환합니다.
- 그 밖의 모든 것
-
input에서 구성 요소 값을 소비하고 그 결과를 function의 값에 추가합니다.
5.5.11. unicode-range 값을 소비하기
문자열 input string에서 unicode-range 설명자의 값을 소비하려면:
-
unicode ranges allowed를 true로 설정하여 input string을 토큰화한 결과를 tokens로 둡니다.
-
tokens에서 구성 요소 값 목록을 소비하고, 그 결과를 반환합니다.
참고: 이 알고리즘이 존재하는 이유는 초기 CSS의 설계 실수 때문입니다. 절대로 이를 재현해서는 안 됩니다.
6. An+B 마이크로구문
CSS의 여러 기능은, 예를 들어 :nth-child() 의사 클래스처럼, 목록에서 인덱스를 나타내야 합니다. An+B 마이크로구문은 이를 위해 유용하며, 작성자가 개별 요소나 목록에서 일정한 간격으로 배치된 모든 요소를 쉽게 나타낼 수 있게 합니다.
An+B 표기법은 정수 단계(A)와 오프셋(B)을 정의하고, 목록에서 An+B번째 요소를 나타내며, 모든 양의 정수 또는 0인 n 값에 대해, 목록의 첫 번째 요소는 인덱스 1(0이 아님)을 가집니다.
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.
<a-n-plus-b> 타입
An+B 표기법은 원래 CSS의 나머지 부분과 약간 다른 토큰화기를 사용하여 정의되었으며, CSS 토큰의 관점에서 표현하면 다소 특이한 정의가 되었습니다. 이 절에서는 CSS 토큰의 관점에서 An+B 표기법을 인식하는 방법을 설명하고 (따라서 CSS 문법을 위한 <a-n-plus-b> 타입을 정의하며), CSS 토큰을 해석하여 A 및 B의 값을 얻는 방법을 설명합니다.
<a-n-plus-b> 타입은 (Values & Units 명세의 값 정의 구문을 사용하여) 다음과 같이 정의됩니다:
<a-n-plus-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"로 설정된 <dimension-token>이며, 단위는 "n"과 ASCII 대소문자를 구분하지 않고 일치합니다<ndash-dimension>은 유형 플래그가 "integer"로 설정된 <dimension-token>이며, 단위는 "n-"과 ASCII 대소문자를 구분하지 않고 일치합니다<ndashdigit-dimension>은 유형 플래그가 "integer"로 설정된 <dimension-token>이며, 단위는 "n-*"와 ASCII 대소문자를 구분하지 않고 일치하며, 여기서 "*"는 하나 이상의 숫자의 연속입니다<ndashdigit-ident>은 값이 "n-*"와 <ident-token>이며 ASCII 대소문자를 구분하지 않고 일치하며, 여기서 "*"는 하나 이상의 숫자의 연속입니다<dashndashdigit-ident>은 값이 "-n-*"와 <ident-token>이며 ASCII 대소문자를 구분하지 않고 일치하며, 여기서 "*"는 하나 이상의 숫자의 연속입니다<integer>는 유형 플래그가 "integer"로 설정된 <number-token>입니다<signed-integer>는 유형 플래그가 "integer"로 설정되고 <number-token>이며, 부호 문자가 있습니다<signless-integer>는 유형 플래그가 "integer"로 설정되고 <number-token>이며, 부호 문자가 없습니다
†: 위에 표시된 경우처럼 더하기 기호(+)가 "n"으로 시작하는 식별자 앞에 오는 경우, 두 토큰 사이에 공백이 없어야 하며, 그렇지 않으면 토큰이 위 문법과 일치하지 않습니다. 다른 모든 두 토큰 사이에서는 공백이 유효하며(무시됩니다).
생성 규칙의 각 절은 다음과 같이 해석됩니다:
- odd
- A는 2이고, B는 1입니다.
- even
- A는 2이고, B는 0입니다.
<integer>- A는 0이고, B는 정수의 값입니다.
<n-dimension>'+'? n-n- A는 각각 차원의 값, 1 또는 -1입니다. B는 0입니다.
<ndashdigit-dimension>'+'? <ndashdigit-ident>- A는 각각 차원의 값 또는 1입니다. B는 각각 차원의 단위 또는 식별자의 값이며, 첫 번째 코드 포인트를 제거하고 나머지를 10진수로 해석합니다. B는 음수입니다.
<dashndashdigit-ident>- A는 -1입니다. B는 식별자의 값에서 처음 두 코드 포인트를 제거하고 나머지를 10진수로 해석한 값입니다. B는 음수입니다.
<n-dimension> <signed-integer>'+'? n <signed-integer>-n <signed-integer>- A는 각각 차원의 값, 1 또는 -1입니다. B는 정수의 값입니다.
<ndash-dimension> <signless-integer>'+'? n- <signless-integer>-n- <signless-integer>- A는 각각 차원의 값, 1 또는 -1입니다. B는 정수 값의 부정입니다.
<n-dimension> ['+' | '-'] <signless-integer>'+'? n ['+' | '-'] <signless-integer>-n ['+' | '-'] <signless-integer>-
A는 각각 차원의 값, 1 또는 -1입니다.
B는 정수의 값입니다.
둘 사이에
'-'가 제공된 경우, B는 대신 정수 값의 부정입니다.
7. 규칙 및 기타 값의 문법 정의
CSS Values 4 § 2 값 정의 구문은 속성 및 기타 CSS 구문 구성의 문법을 지정하는 방법을 정의합니다.
7.1. 블록 내용 정의: <block-contents>, <declaration-list>, <qualified-rule-list>, <declaration-rule-list>, 및 <rule-list> 생성 규칙
CSS 파서는 블록의 내용에 관여하지 않습니다—모두 동일한 알고리즘으로 파싱되며, 어떤 구문이 유효한지에 의해서만 서로 구별됩니다.
규칙 문법을 작성할 때, <block-contents>는 이러한 비관여 파싱을 나타냅니다. 블록의 유일한 값으로만 사용해야 하며, 블록에 포함될 수 있는 항목에 암묵적인 제한이 없음을 나타냅니다.
함께 제공되는 산문은 이 컨텍스트에서 무엇이 유효하고 유효하지 않은지 정의해야 합니다.
선언이 유효하고,
속성
선언이라면,
캐스케이드와 상호작용하는지 여부를 정의해야 하며;
상호작용한다면 그 명시도를 정의하고
!important를 어떻게 사용하는지도 정의해야 합니다.
그러나 많은 경우, 블록은 주어진 유형의 어떤 구문도 유효하게 포함할 수 없습니다. 이러한 경우를 더 명시적으로 나타내기 위해, 다음 생성 규칙을 사용할 수 있습니다
-
<declaration-list>: 선언만 허용되며; at-규칙 및 한정 규칙은 자동으로 유효하지 않습니다.
-
<qualified-rule-list>: 한정 규칙만 허용되며; 선언 및 at-규칙은 자동으로 유효하지 않습니다.
-
<declaration-rule-list>: 선언 및 at-규칙은 허용되며; 한정 규칙은 자동으로 유효하지 않습니다.
이들은 모두 파싱 측면에서 <block-contents>와 정확히 동일하지만, 함께 제공되는 산문에서는 자동으로 유효하지 않은 범주를 제외한 범주의 유효성만 정의하면 됩니다.
-
최상위 @media는 블록에 <rule-list>를 사용하며, 중첩된 것은 [CSS-NESTING-1] <block-contents>를 사용합니다.
-
스타일 규칙은 <block-contents>를 사용합니다.
-
@font-face는 <declaration-list>를 사용합니다.
-
@page는 <declaration-rule-list>를 사용합니다.
-
@keyframes는 <qualified-rule-list>를 사용합니다
<@font-face> = @font-face { <declaration-list> }
그런 다음 함께 제공되는 산문에서 블록에 허용되는 유효한 설명자를 정의합니다.
@keyframes의 문법은 다음과 같이 작성할 수 있습니다:
<@keyframes> = @keyframes { <qualified-rule-list> } <keyframe-rule> = <keyframe-selector> { <declaration-list> }
그런 다음 함께 제공되는 산문에서 <keyframe-rule>만 @keyframes에 허용되며, <keyframe-rule>은 애니메이션 가능한 모든 CSS 속성과 animation-timing-function 속성을 허용하지만, 캐스케이드와는 상호작용하지 않는다고 정의합니다.
7.2. 임의의 내용 정의: <declaration-value> 및 <any-value> 생성 규칙
일부 문법에서는, 문법에서 합리적인 입력을 무엇이든 허용하고, 내용에 대해 더 구체적인 오류 처리를 수동으로 수행하는 것이 유용합니다 (문법 불일치가 흔히 하듯 단순히 구문을 유효하지 않게 만드는 대신).
예를 들어 사용자 정의 속성은 합리적인 값을 무엇이든 허용하는데, 다른 CSS 속성의 임의의 부분을 포함할 수 있거나, 기존 CSS의 일부가 아닌 것에 사용될 수도 있기 때문입니다. 또 다른 예로 Media Queries의 <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가 될 수 있는 모든 것을 나타냅니다.
8. CSS 스타일시트
CSS 스타일시트를 파싱하려면, 먼저 스타일시트를 파싱합니다. 결과로 나온 모든 최상위 한정 규칙을 아래에서 정의하는 스타일 규칙으로 해석합니다.
스타일 규칙이 유효하지 않거나, at-규칙이 인식되지 않거나 그 문법 또는 컨텍스트에 따라 유효하지 않으면, 이는 파싱 오류입니다. 해당 규칙을 버립니다.
8.1. 스타일 규칙
스타일 규칙은 한정 규칙으로, 선택자 목록을 속성 선언 목록 및 가능한 중첩 규칙 목록과 연결합니다. 또한 [CSS2]에서는 규칙 집합이라고도 합니다. CSS Cascading and Inheritance [CSS-CASCADE-3]은 스타일 규칙 내부의 선언이 캐스케이드에 어떻게 참여하는지 정의합니다.
한정 규칙의 프렐류드는 파싱되어 <selector-list>이 됩니다. 이것이 실패를 반환하면, 전체 스타일 규칙은 유효하지 않습니다.
한정 규칙 블록의 내용은 <declaration-list>로 파싱됩니다. 이 블록의 한정 규칙도 스타일 규칙입니다. 다른 명세나 이 명세의 미래 레벨에서 달리 정의하지 않는 한, 해당 목록의 at-규칙은 유효하지 않으며 무시해야 합니다.
참고: [CSS-NESTING-1]은 조건부 그룹 규칙과 일부 다른 at-규칙이 스타일 규칙 내부에서 허용된다고 정의합니다.
알 수 없는 CSS 속성의 선언이나 값이 해당 속성에서 정의한 구문과 일치하지 않는 선언은 유효하지 않으며 무시해야 합니다. 스타일 규칙 내용의 유효성은 스타일 규칙 자체의 유효성에 영향을 주지 않습니다. 달리 지정되지 않는 한, 속성 이름은 ASCII 대소문자를 구분하지 않습니다.
참고: 사용자 정의 속성 [CSS-VARIABLES]의 이름은 대소문자를 구분합니다.
CSS 스타일시트의 최상위에 있는 한정 규칙은 스타일 규칙입니다. 다른 컨텍스트의 한정 규칙은 스타일 규칙일 수도 있고 아닐 수도 있으며, 이는 컨텍스트에서 정의합니다.
예를 들어 @media 규칙 [CSS3-CONDITIONAL] 내부의 한정 규칙은 스타일 규칙이지만, @keyframes 규칙 [CSS3-ANIMATIONS] 내부의 한정 규칙은 그렇지 않습니다.
8.2. At-규칙
at-규칙은 at-키워드로 시작하는 규칙이므로, 동일한 컨텍스트의 스타일 규칙과 구별할 수 있습니다.
At-규칙은 다음에 사용됩니다:
-
조건부 그룹 규칙과 같이 스타일 규칙 및 기타 at-규칙을 그룹화하고 구조화
-
특정 요소와 연결되지 않은 스타일 정보를 선언, 예를 들어 카운터 스타일 정의
-
및 스타일 규칙이 제공하지 않는 기타 다양한 목적 제공
At-규칙은 특정 규칙과 목적에 따라 다양한 형태를 가지지만, 크게 말하면 두 종류가 있습니다: 문형 at-규칙은 세미콜론으로 끝나는 더 단순한 구문이며, 블록 at-규칙은 {}-블록으로 끝나며 중첩된 한정 규칙, at-규칙, 또는 선언을 포함할 수 있습니다.
블록 at-규칙은 일반적으로 (일반적이거나 at-규칙에 특화된) at-규칙, 한정 규칙 및/또는 설명자 선언의 모음을 포함하며 at-규칙에서 정의한 제한을 따릅니다. 설명자는 속성과 유사하며 (동일한 구문으로 선언되고) 트리의 요소 및 박스가 아니라 특정 유형의 at-규칙과 연결됩니다.
8.3. @charset 규칙
스타일시트의 대체 인코딩을 결정하는 데 사용되는 알고리즘은 파일의 맨 처음 몇 바이트에서 특정 바이트 시퀀스를 찾으며, 이는 이름이 "@charset"인 at-규칙의 구문 형태를 가집니다.
테스트
- page-utf16-css-bomless-utf16.html (라이브 테스트) (소스)
- page-utf16-css-bomless-utf16be.html (라이브 테스트) (소스)
- page-utf16-css-no-decl-ascii-only.html (라이브 테스트) (소스)
- page-utf16-css-no-decl.html (라이브 테스트) (소스)
- page-windows-1251-charset-attribute-bogus.html (라이브 테스트) (소스)
- page-windows-1251-charset-attribute-empty.html (라이브 테스트) (소스)
- page-windows-1251-css-at-charset-1250-charset-attribute-windows-1253.html (라이브 테스트) (소스)
- page-windows-1251-css-at-charset-bogus-charset-attribute-windows-1250.html (라이브 테스트) (소스)
- page-windows-1251-css-at-charset-bogus.html (라이브 테스트) (소스)
- page-windows-1251-css-at-charset-utf16-ascii-only.html (라이브 테스트) (소스)
- page-windows-1251-css-at-charset-utf16.html (라이브 테스트) (소스)
- page-windows-1251-css-at-charset-utf16be.html (라이브 테스트) (소스)
- page-windows-1251-css-at-charset-windows-1250-in-utf16.html (라이브 테스트) (소스)
- page-windows-1251-css-at-charset-windows-1250-in-utf16be.html (라이브 테스트) (소스)
- page-windows-1251-css-http-bogus-at-charset-windows-1250.html (라이브 테스트) (소스)
- page-windows-1251-css-http-bogus.html (라이브 테스트) (소스)
- page-windows-1251-css-http-windows-1250-at-charset-windows-1253.html (라이브 테스트) (소스)
- page-windows-1251-css-no-decl.html (라이브 테스트) (소스)
- page-windows-1251-css-utf8-bom.html (라이브 테스트) (소스)
- page-windows-1252-http-windows-1251-css-utf8-bom.html (라이브 테스트) (소스)
- xml-stylesheet-page-windows-1251-charset-attribute-windows-1250.xhtml (라이브 테스트) (소스)
그러나 실제로 이름이 @charset인 at-규칙은 없습니다. 스타일시트가 실제로 파싱될 때, @charset 규칙이 나타나면 인식되지 않는 규칙으로 처리해야 하며, 따라서 스타일시트의 문법을 검사할 때 유효하지 않은 것으로 버려야 합니다.
참고: CSS 2.1에서는 @charset이 유효한 규칙이었습니다. 일부 레거시 명세에서는 여전히 @charset 규칙을 참조하고, 스타일시트에서의 존재를 명시적으로 언급할 수 있습니다.
9. 직렬화
이 명세에서 설명하는 토큰화기는 주석에 대한 토큰을 생성하지 않으며, 다른 방식으로도 이를 보존하지 않습니다. 구현은 주석의 내용과 토큰 스트림에서의 위치를 보존할 수 있습니다. 그렇게 하는 경우, 이 보존된 정보는 파싱 단계에 영향을 주어서는 안 됩니다.
이 명세는 일반적으로 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을 나타냅니다.
| 식별자 | 함수 | URL | 잘못된 URL | - | 숫자 | 백분율 | 차원 | CDC | ( | * | % | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 식별자 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ||
| at-키워드 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| 해시 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| 차원 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| # | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| - | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| 숫자 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| @ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ||||||
| . | ✗ | ✗ | ✗ | |||||||||
| + | ✗ | ✗ | ✗ | |||||||||
| / | ✗ |
테스트
9.1. <a-n-plus-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를 반환합니다.
10. 개인정보 보호 고려사항
이 명세는 새로운 개인정보 보호 우려를 도입하지 않습니다.
11. 보안 고려사항
이 명세는 모든 입력에 대해 CSS 파싱이 이제 명확하게 정의된다는 점에서 보안을 향상시킵니다.
화이트리스트/필터와 같은 오래된 파서가 이 명세와 다르게 파싱하는 한, 어느 정도 안전하지 않지만, 이전 파싱 명세에는 브라우저가 서로 다르게 해석한 모호한 코너 케이스가 많이 남아 있었으므로, 이러한 필터는 이미 잠재적으로 안전하지 않았으며, 이 명세는 상황을 악화시키지 않습니다.
12. 변경 사항
이 절은 비규범적입니다.
12.1. 2021년 12월 24일 후보 권고안 초안 이후의 변경 사항
다음과 같은 실질적인 변경 사항이 이루어졌습니다:
-
<an+b>의 이름을 <a-n-plus-b>로 변경 (9473)
-
중복된 토큰 스트림 생성을 제거 (PR 11129)
-
valdef 구문 정의를 통합
-
@nest를 폐기하고 '중첩 선언 규칙'을 도입 (10386)
-
블록 내용 파싱을 변경하여 서로 섞인 선언과 규칙의 상대적 순서를 유지. 이를 나타내기 위해 Nesting에 @nest 추가 (8738)
-
블록은 속성의 전체 값으로만 허용됨 (9317)
-
애초에 속성을 허용하는 컨텍스트가 아니라면 탐욕적인 사용자 정의 속성 유사 동작을 적용하지 않도록 변경 (9336)
-
서로게이트는 CSS 객체 모델 연산을 통해 해당 문자를 포함하는 DOMString을 직접 할당하는 경우에만 생성될 수 있음을 명확히 함 (PR 7997)
-
비ASCII 코드 포인트의 정의를 잠재적으로 문제가 될 수 있는 일부 코드 포인트를 제외하도록 제한함. (7129)
-
<foo()>및<@foo>생성 규칙을 정의함. (5728) -
중첩 스타일 규칙을 허용함. (7961).
-
Nesting을 허용하는 과정에서, 전체 파싱 절을 대폭 다시 작성함. 특히 "규칙 목록을 파싱하기"와 "선언 목록을 파싱하기"를 제거하고 "스타일시트의 내용을 파싱하기"와 "블록의 내용을 파싱하기"로 대체함. 추가된 유일한 규범적 변경 사항은 이제 일부 컨텍스트에서 세미콜론이 약간 다른 오류 복구를 유발하여, @media 블록과 같은 것의 파싱이 중첩 여부와 관계없이 동일해졌다는 것임. (8834).
-
기존 토큰을 이용한
<urange>생성 규칙 시도를 제거하고, 대신 소스에서 특수하게 다시 파싱하는 방식에 의존하도록 변경했으며 이는 특히 unicode-range 설명자를 파싱할 때 사용됨. (8835) -
위 변경으로 토큰의 "표현" (파싱된 원래 문자열)을 보존해야 할 주된 필요성이 사라졌으므로, An+B 절에서 "표현"에 대한 나머지 참조를 제거하고 대신 필요한 몇 가지 정보만 기록함 (숫자에 명시적인 부호가 있었는지 여부).
-
일부 용도에서 (사용자 정의 속성, unicode-range 설명자) 선언 전체 값의 원래 문자열에 접근해야 함을 명시적으로 언급하고, 파서에서 해당 위치를 표시함.
-
블록의 내용을 소비할 때, 모든 선언을 다른 규칙과의 상대적 위치와 관계없이 함께 그룹화하는 대신, 이제 선언은 주변 규칙에 대한 상대적 위치를 유지함. 각 규칙이 해당 정보를 실제로 어떻게 처리할지는 개별 규칙에서 결정함.
12.2. 2019년 8월 16일 후보 권고안 이후의 변경 사항
다음과 같은 실질적인 변경 사항이 이루어졌습니다:
-
새로운 § 5.4.2 CSS 문법에 따라 쉼표로 구분된 목록을 파싱하기 알고리즘을 추가함.
-
새로운 "스타일 블록의 내용을 파싱하기" 알고리즘과 이에 대응하는 <style-block> 생성 규칙을 추가하고, 스타일 규칙이 이를 사용하도록 정의함.
-
스타일시트를 파싱하기를 Fetch 관련 처리와 일치시킴. (커밋 참조.)
input에서 스타일시트를 파싱하려면 선택적인 url location이 주어진 경우 :
- ...
- 새 스타일시트를 생성합니다 , 그 위치를 location으로 설정합니다(location이 전달되지 않았다면 null).
- ...
다음과 같은 편집상 변경 사항이 이루어졌습니다:
-
§ 8.2 At-규칙을 추가하여 at-규칙, 문형 at-규칙, 블록 at-규칙 및 설명자의 정의를 제공함. (5633)
-
때때로 “이름”이라는 용어를 사용하는 대신 식별자 시퀀스를 일관되게 참조하도록 변경함.
-
토큰화 전 프로세스 중 여러 개에 명시적으로 이름을 붙이고, 파싱 진입점에서 이를 명시적으로 참조하도록 변경함 (이 알고리즘 시작 시 X를 수행하라는 포괄적인 문장에 의존하는 대신).
-
"사이에 주석 넣기" 표에 더 많은 항목을 추가하여, 이제 식별자가
--로 시작할 수 있다는 사실을 올바르게 처리함. (6874)
12.3. 2014년 2월 20일 후보 권고안 이후의 변경 사항
다음과 같은 실질적인 변경 사항이 이루어졌습니다:
-
<unicode-range-token>을 제거하고, <urange> 생성 규칙을 만드는 것으로 대체함.
-
문자열을 포함하는 url() 함수는 이제 일반적인 <function-token>으로 파싱됨. "원시" URL을 포함하는 url() 함수는 여전히 특별히 <url-token>으로 파싱됨.
-
"URL 토큰을 소비하기" 알고리즘에서 문자열을 소비하려고 시도하기 전에 문자열을 시작하는 따옴표 문자를 소비하지 않던 버그를 수정함.
-
여러 파서 알고리즘에서 현재/다음 토큰 및 항목이 너무 일찍/늦게 소비되는 것과 관련된 버그를 수정함.
-
토큰화 및 파싱 알고리즘의 여러 버그를 수정함.
-
식별자형 토큰의 정의를 변경하여 "--"가 식별자를 시작할 수 있도록 함. 이에 따라 토큰을 소비하기의 "-" 단계 절 순서를 재배치하여 <CDC-token>이 -- <ident-token>이 되는 대신 해당 토큰으로 인식되도록 함.
-
A가 1 또는 -1일 때 <a-n-plus-b>의 숫자를 직렬화하지 않음.
-
모든 토큰에 표현이 있도록 정의함.
-
두 코드 포인트가 유효한 이스케이프인지 확인하기의 사소한 버그를 수정함—EOF 뒤에 오는
\가 이제 올바르게 유효하지 않은 이스케이프로 보고됨. 스타일시트 마지막의\는 이제 단순히 그 자체를 <delim-token>으로 방출함. -
@charset은 더 이상 유효한 CSS 규칙이 아님(이름이 @charset인 규칙처럼 보이는 인코딩 선언만 존재함)
-
파싱 중 선언 값의 시작/끝에서 공백을 제거함.
-
WG 결의에 따라 Selectors 전용 토큰을 제거함.
다음과 같은 편집상 변경 사항이 이루어졌습니다:
-
"문자열 토큰을 소비하기" 알고리즘을 명시적인 종료 토큰을 지정하지 않고 호출할 수 있도록 변경하여, 대신 현재 토큰을 사용하도록 함. 알고리즘의 세 호출 위치도 해당 형태를 사용하도록 변경함.
-
알고리즘의 사소한 편집상 구조 변경.
-
파싱하기 및 쉼표로 구분된 구성 요소 값 목록을 파싱하기 API 진입점을 추가함.
-
<declaration-value> 및 <any-value> 생성 규칙을 추가함.
-
"코드 포인트" 및 "서로게이트 코드 포인트"를 제거하고 Infra 표준의 동일한 정의를 사용하도록 함.
-
모든 범위가 양 끝을 포함함을 명확히 함.
-
숫자 토큰이 "%" 구분자 토큰 옆에 나타나는 경우를 처리하기 위해 주석 삽입 표에 열을 추가함.
12.4. 2013년 11월 5일 최종 검토 워킹 드래프트 이후의 변경 사항
- 직렬화 절을 다시 작성하여 "왕복" 요구 사항만 규범적으로 만들고, 이를 달성하는 방법의 세부 사항은 참고로 옮겼습니다. 이 세부 사항의 일부 코너 케이스도 수정되었습니다.
- [ENCODING]이 규범적 참조 목록에 추가되었습니다. 이전에도 이미 규범적 텍스트에서 참조되었지만, 해당 목록에는 포함되지 않았습니다.
-
스타일시트의 대체 인코딩을 결정하는 알고리즘에서,
@charset바이트 시퀀스를 1024바이트로 제한합니다. 이는 HTML이<meta charset>에 대해 수행하는 동작과 일치하며 시퀀스 크기가 제한되도록 보장합니다. 이는 인코딩 레이블에 선행 또는 후행 공백이 있을 때만 차이를 만듭니다:@charset " (많은 공백) utf-8";
12.5. 2013년 9월 19일 워킹 드래프트 이후의 변경 사항
- 환경 인코딩이라는 개념이 추가되었습니다. 동작은 변경되지 않지만, 일부 정의는 관련 명세로 옮겨야 합니다.
12.6. CSS 2.1 및 Selectors 레벨 3 이후의 변경 사항
참고: 이 명세의 목적은 현실과 일치하는 것입니다; CSS2.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 식별자 코드 포인트의 정의를 HTML의 유효한 사용자 정의 요소 이름과 일치하도록 변경했습니다.
- 토큰화는 더 이상 COMMENT 또는 BAD_COMMENT 토큰을 방출하지 않습니다. BAD_COMMENT는 이제 일반 토큰과 동일하게 간주됩니다(오류가 아님). 직렬화는 분리해야 하는 토큰 사이에 필요에 따라 주석을 삽입할 책임이 있습니다, 예를 들어 연속된 두 <ident-token>입니다.
-
<unicode-range-token>은
가치가 낮고 때때로 적극적으로 해로웠기 때문에 제거되었습니다.
(예를 들어 u+a { font-weight: bold; }는 유효하지 않은 선택자였습니다...)
대신 토큰 패턴을 기반으로 한 <urange> 생성 규칙이 추가되었습니다. 기술적으로는 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와 일치하도록 숫자/백분율/차원에서 과학적 표기법을 지원합니다.
- 서로게이트에 대한 16진수 이스케이프는 이제 서로게이트 대신 대체 문자를 방출합니다. 이를 통해 구현은 내부적으로 UTF-16을 안전하게 사용할 수 있습니다.
파싱 변경 사항:
- 모든 선언 목록은 이제 WG 결의에 따라 @page와 같은 at-규칙도 허용합니다. 이는 아직 그러한 at-규칙이 정의되지 않았더라도 오류 처리에 차이를 만듭니다: at-규칙은 유효 여부와 관계없이 <semicolon-token> 없이 {} 블록에서 끝나고 다음 선언이 시작될 수 있게 합니다.
-
문법의 여러 위치에 나타나는 일부 기타 "특수" 토큰의 처리
(예: 짝이 맞지 않는 <}-token>)
는 최소 하나의 브라우저에서 보이는 합리적인 동작으로 지정되었습니다.
이전에는 이러한 위치에 해당 토큰이 있는 스타일시트가 스타일시트 문법과 전혀 일치하지 않았으므로,
처리 방식이 완전히 정의되지 않았습니다.
구체적으로:
- [] 블록, () 블록 및 함수는 이제 {} 블록, <at-keyword-token> 또는 <semicolon-token>을 포함할 수 있습니다
- 한정 규칙 프렐류드는 이제 세미콜론을 포함할 수 있습니다
- 한정 규칙 및 at-규칙 프렐류드는 이제 <at-keyword-token>을 포함할 수 있습니다
Selectors 레벨 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.