CSS 구문 모듈 레벨 3

W3C 후보 권고안 초안,

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2026/CRD-css-syntax-3-20261001/
최신 공개 버전:
https://www.w3.org/TR/css-syntax-3/
편집자 초안:
https://drafts.csswg.org/css-syntax/
이전 버전:
이력:
https://www.w3.org/standards/history/css-syntax-3/
구현 보고서:
https://wpt.fyi/results/css/css-syntax?label=experimental&label=master&aligned
피드백:
CSSWG 이슈 저장소
편집자:
Tab Atkins Jr. (Google)
Simon Sapin (Mozilla)
이 명세에 대한 편집 제안:
GitHub 편집기
테스트 스위트:
https://wpt.fyi/results/css/css-syntax/

초록

이 모듈은 일반적인 관점에서 CSS 스타일시트의 기본 구조와 구문을 설명합니다. 또한 CSS의 구문과 파싱, 즉 바이트 스트림을 의미 있는 스타일시트로 변환하는 방법을 자세히 정의합니다.

CSS는 구조화된 문서 (예: HTML 및 XML) 를 화면, 종이 등에 렌더링하는 방식을 설명하는 언어입니다.

이 문서의 상태

이 절에서는 이 문서가 공개된 시점의 상태를 설명합니다. 현재 W3C 공개 문서 목록과 이 기술 보고서의 최신 개정판은 W3C 표준 및 초안 색인에서 확인할 수 있습니다.

이 문서는 CSS 워킹 그룹에 의해 후보 권고안 초안으로 다음 권고안 트랙을 사용하여 공개되었습니다. 후보 권고안으로의 공개가 W3C의 승인을 의미하는 것은 아니며 그 회원들의 승인도 의미하지 않습니다. 후보 권고안 초안은 이전 후보 권고안의 변경 사항 중 워킹 그룹이 후속 후보 권고안 스냅샷에 포함하려는 사항을 통합합니다.

이 문서는 초안이며 언제든지 업데이트되거나 대체되거나 다른 문서에 의해 폐기될 수 있습니다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 적절하지 않습니다.

피드백은 GitHub에 이슈를 제출하여(권장) 다음과 같이 제목에 명세 코드 “css-syntax”를 포함하여 보내주시기 바랍니다: “[css-syntax] …의견 요약…”. 모든 이슈와 의견은 보관됩니다. 또는 (보관되는) 공개 메일링 리스트인 www-style@w3.org로 피드백을 보낼 수 있습니다.

이 문서에는 2025년 8월 18일 W3C 프로세스 문서가 적용됩니다.

이 문서는 다음 정책에 따라 운영되는 그룹에 의해 작성되었습니다: W3C 특허 정책. W3C는 모든 특허 공개의 공개 목록을 해당 그룹의 산출물과 관련하여 유지하며; 해당 페이지에는 특허를 공개하는 방법에 대한 안내도 포함되어 있습니다. 자신이 알고 있는 특허가 필수 청구항을 포함한다고 믿는 실제 지식을 가진 개인은 다음에 따라 해당 정보를 공개해야 합니다 W3C 특허 정책 제6절.

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 이스케이프 시퀀스는 백슬래시(\)로 시작하며, 다음 중 하나가 이어집니다:

2.2. 오류 처리

이 절은 규범적이지 않습니다.

CSS에서 오류가 발생하면, 파서는 정상적으로 복구하려고 시도하며, 다시 정상적인 파싱으로 돌아가기 전에 최소한의 내용만 버립니다. 이는 오류가 항상 실수인 것은 아니기 때문입니다—​새 구문은 오래된 파서에는 오류처럼 보이며, 해당 구문을 포함하는 스타일시트가 오래된 UA에서 완전히 망가질 것을 걱정하지 않고 언어에 새 구문을 추가할 수 있으면 유용합니다.

정확한 오류 복구 동작은 파서 자체에 자세히 설명되어 있지만, 충분히 단순하므로 짧은 설명도 상당히 정확합니다.

각 구문(선언, 스타일 규칙, at-규칙)이 파싱된 후, 사용자 에이전트는 예상되는 문법과 일치하는지 확인합니다. 문법과 일치하지 않으면, 해당 구문은 유효하지 않으며, UA에 의해 무시되고, UA는 해당 구문이 전혀 없는 것처럼 처리합니다.

3. CSS 토큰화 및 파싱

사용자 에이전트는 이 명세에서 설명하는 파싱 규칙을 사용하여 text/css 리소스로부터 [CSSOM] 트리를 생성해야 합니다. 이 규칙들을 함께 CSS 파서라고 부릅니다.

이 명세는 CSS 문서가 구문적으로 올바른지 여부와 관계없이 파싱 규칙을 정의합니다. 파싱 알고리즘의 특정 지점은 파싱 오류라고 합니다. 파싱 오류에 대한 오류 처리는 명확하게 정의되어 있습니다: 사용자 에이전트는 이러한 문제를 만났을 때 아래에 설명된 대로 동작하거나, 아래 설명된 규칙을 적용하고 싶지 않은 첫 번째 오류에서 처리를 중단해야 합니다.

문서에 하나 이상의 파싱 오류 조건이 존재하면 적합성 검사기는 적어도 하나의 파싱 오류 조건을 사용자에게 보고해야 하며 반대로 적합성 검사기가 사용자에게 보고할 파싱 오류 조건이 문서에는 하나도 존재하지 않는 경우, 파싱 오류 조건을 보고해서는 안 됩니다. 하나보다 많은 파싱 오류 조건이 문서에 존재하는 경우 적합성 검사기는 하나보다 많은 파싱 오류 조건을 보고할 수 있습니다. 적합성 검사기는 파싱 오류에서 복구할 필요는 없지만, 복구하는 경우에는 사용자 에이전트와 동일한 방식으로 복구해야 합니다.

테스트

3.1. 파싱 모델 개요

CSS 파싱 프로세스의 입력은 유니코드 코드 포인트 스트림으로 구성되며, 이 스트림은 토큰화 단계를 거친 뒤 트리 구성 단계를 거칩니다. 출력은 CSSStyleSheet 객체입니다.

참고: 스크립팅을 지원하지 않는 구현은 실제로 CSSOM CSSStyleSheet 객체를 생성할 필요는 없지만, 이 경우에도 CSSOM 트리는 나머지 명세를 위한 모델로 사용됩니다.

3.2. 입력 바이트 스트림

스타일시트를 파싱할 때, 토큰화 단계의 입력을 구성하는 유니코드 코드 포인트 스트림은 처음에는 사용자 에이전트에 바이트 스트림으로 보일 수 있습니다 (일반적으로 네트워크 또는 로컬 파일 시스템에서 가져옵니다). 그런 경우 사용자 에이전트는 특정 문자 인코딩에 따라 이 바이트를 코드 포인트로 디코딩해야 합니다.

stylesheet의 바이트 스트림을 코드 포인트 스트림으로 디코딩하려면:
  1. stylesheet의 대체 인코딩을 결정하고, 그 결과를 fallback으로 둡니다.

  2. 대체 인코딩 fallback을 사용하여 stylesheet의 바이트 스트림을 디코딩하고 그 결과를 반환합니다.

참고: 디코딩 알고리즘은 바이트 순서 표시(BOM)에 우선순위를 부여하고, BOM을 찾지 못한 경우에만 대체 인코딩을 사용합니다.

stylesheet의 대체 인코딩을 결정하려면:
  1. HTTP 또는 이에 상응하는 프로토콜이 stylesheet에 대해 encoding label(예: Content-Type 헤더의 charset 매개변수를 통해)를 제공하는 경우, encoding label에서 인코딩을 가져옵니다. 이것이 실패를 반환하지 않으면, 이를 반환합니다.
  2. 그렇지 않으면 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 규칙을 만들 수 있지만, 여러 공백, 주석 또는 작은따옴표를 사용하는 것과 같은 작업은 인코딩 선언이 인식되지 않게 합니다. 이 동작은 인코딩 선언을 가능한 한 단순하게 유지하여, 올바르게 구현될 가능성을 최대화합니다.

  3. 그렇지 않고 참조하는 문서가 환경 인코딩을 제공하는 경우, 이를 반환합니다.
  4. 그렇지 않으면 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에서 코드 포인트를 필터링하려면:
테스트

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>.

참고: 해시 토큰의 유형 플래그는 Selectors 구문 [SELECT]에서 사용됩니다. "id" 유형의 해시 토큰만 유효한 ID 선택자입니다.

4.1. 토큰 철도 다이어그램

이 절은 비규범적입니다.

이 절에서는 토큰화기의 정보 제공용 표현을 철도 다이어그램 형태로 제시합니다. 철도 다이어그램은 명시적인 파서보다 더 간결하지만, 정규 표현식보다 읽기 쉬운 경우가 많습니다.

이 다이어그램은 정보 제공용이며 불완전합니다; "올바른" 토큰의 문법을 설명하지만, 오류 처리는 전혀 설명하지 않습니다. 각 토큰의 구문을 직관적으로 이해하기 쉽게 하기 위한 목적으로만 제공됩니다.

<foo-token>과 같은 이름의 다이어그램은 토큰을 나타냅니다. 나머지는 다른 다이어그램에서 참조하는 생성 규칙입니다.

주석
/* * 뒤에 /가 오는 경우를 제외한 모든 것 */
개행
\n \r\n \r \f
공백
스페이스 \t 개행
16진수 숫자
0-9 a-f 또는 A-F
이스케이프
\ 개행 또는 16진수 숫자가 아님 16진수 숫자 1~6회 공백
<whitespace-token>
공백
ws*
<whitespace-token>
<ident-token>
-- - a-z A-Z _ 또는 비ASCII 이스케이프 a-z A-Z 0-9 _ - 또는 비ASCII 이스케이프
<function-token>
<ident-token> (
<at-keyword-token>
@ <ident-token>
<hash-token>
# a-z A-Z 0-9 _ - 또는 비ASCII 이스케이프
<string-token>
" " \ 또는 개행이 아님 이스케이프 \ 개행 " ' ' \ 또는 개행이 아님 이스케이프 \ 개행 '
<url-token>
<ident-token "url"> ( ws* " ' ( ) \ 공백 또는 비출력 문자가 아님 이스케이프 ws* )
<number-token>
+ - 숫자 . 숫자 숫자 . 숫자 e E + - 숫자
<dimension-token>
<number-token> <ident-token>
<percentage-token>
<number-token> %
<CDO-token>
<!--
<CDC-token>
-->
<unicode-range-token>
U u + 16진수 숫자 1~6회 16진수 숫자 1~5회 ? 1~(6-숫자 수)회 16진수 숫자 1~6회 - 16진수 숫자 1~6회

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 (#)
다음 입력 코드 포인트가 식별자 코드 포인트이거나 다음 두 입력 코드 포인트가 유효한 이스케이프이면, 다음을 수행합니다:
  1. <hash-token>을 생성합니다.
  2. 다음 3개의 입력 코드 포인트가 식별자 시퀀스를 시작한다면, <hash-token>의 유형 플래그를 "id"로 설정합니다.
  3. 식별자 시퀀스를 소비하고, <hash-token>의 값을 반환된 문자열로 설정합니다.
  4. <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개의 입력 코드 포인트가 식별자 시퀀스를 시작한다면, 다음을 수행합니다:

  1. number와 동일한 값, 유형 플래그 및 부호 문자를 갖는 <dimension-token>을 생성하고, 단위는 처음에 빈 문자열로 설정합니다.
  2. 식별자 시퀀스를 소비합니다. <dimension-token>의 단위를 반환된 값으로 설정합니다.
  3. <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>으로 파싱됩니다. 식별자형 토큰을 소비하기가 자동으로 이 차이를 처리합니다; 따라서 이 알고리즘은 그 밖의 경우 직접 호출해서는 안 됩니다.

  1. 처음에 값이 빈 문자열로 설정된 <url-token>을 생성합니다.
  2. 가능한 한 많은 공백을 소비합니다.
  3. 스트림에서 다음 입력 코드 포인트를 반복해서 소비합니다:
    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 (()
    출력 불가능 코드 포인트
    이는 파싱 오류입니다. 잘못된 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를 시작하는지 확인하는 방법을 설명합니다. 여기에서 설명하는 알고리즘은 세 코드 포인트를 명시적으로 지정하여 호출하거나, 입력 스트림 자체로 호출할 수 있습니다. 후자의 경우 문제의 세 코드 포인트는 현재 입력 코드 포인트와 다음 두 입력 코드 포인트이며, 이 순서입니다.

참고: 이 알고리즘은 추가 코드 포인트를 소비하지 않습니다.

다음이 모두 참이면:

true를 반환합니다.

그렇지 않으면 false를 반환합니다.

4.3.12. 식별자 시퀀스를 소비하기

이 절에서는 코드 포인트 스트림에서 식별자 시퀀스를 소비하는 방법을 설명합니다. 문자열을 반환하며, 이 문자열은 스트림의 인접한 코드 포인트에서 구성할 수 있는 가장 긴 이름을 첫 번째 코드 포인트부터 포함합니다.

참고: 이 알고리즘은 반환된 코드 포인트가 <ident-token>을 구성하도록 보장하는 데 필요한 처음 몇 코드 포인트의 검증을 수행하지 않습니다. 이것이 의도한 용도라면, 이 알고리즘을 호출하기 전에 스트림이 식별자 시퀀스로 시작하는지 확인하십시오.

result를 처음에 빈 문자열로 둡니다.

스트림에서 다음 입력 코드 포인트를 반복해서 소비합니다:

식별자 코드 포인트
코드 포인트를 result에 추가합니다.
스트림이 유효한 이스케이프로 시작함
이스케이프된 코드 포인트를 소비합니다. 반환된 코드 포인트를 result에 추가합니다.
그 밖의 모든 것
현재 입력 코드 포인트를 다시 소비합니다. result를 반환합니다.

4.3.13. 숫자를 소비하기

이 절에서는 코드 포인트 스트림에서 숫자를 소비하는 방법을 설명합니다. 숫자 value, "integer" 또는 "number" 중 하나인 문자열 type, 그리고 "+", "-" 또는 누락 중 하나인 선택적 sign character를 반환합니다.

참고: 이 알고리즘은 스트림에서 숫자를 얻을 수 있도록 보장하는 데 필요한 처음 몇 코드 포인트의 검증을 수행하지 않습니다. 이 알고리즘을 호출하기 전에 스트림이 숫자로 시작하는지 확인하십시오.

다음 단계를 순서대로 수행합니다:

  1. type을 문자열 "integer"로 둡니다. number part와 exponent part를 빈 문자열로 둡니다.
  2. 다음 입력 코드 포인트가 U+002B PLUS SIGN (+) 또는 U+002D HYPHEN-MINUS (-)이면, 이를 소비합니다. 이를 number part에 추가하고 sign character를 그것으로 설정합니다.
  3. 다음 입력 코드 포인트가 숫자인 동안, 이를 소비하고 number part에 추가합니다.
  4. 다음 2개의 입력 코드 포인트가 U+002E FULL STOP (.) 뒤에 숫자가 오는 경우, 다음을 수행합니다:
    1. 다음 입력 코드 포인트를 소비하고 number part에 추가합니다.
    2. 다음 입력 코드 포인트가 숫자인 동안 이를 소비하고 number part에 추가합니다.
    3. type을 "number"로 설정합니다.
  5. 다음 2개 또는 3개의 입력 코드 포인트가 U+0045 LATIN CAPITAL LETTER E (E) 또는 U+0065 LATIN SMALL LETTER E (e)이고, 선택적으로 그 뒤에 U+002D HYPHEN-MINUS (-) 또는 U+002B PLUS SIGN (+)가 오며, 이어서 숫자가 오면, 다음을 수행합니다:
    1. 다음 입력 코드 포인트를 소비합니다.
    2. 다음 입력 코드 포인트가 "+" 또는 "-"이면, 이를 소비하고 exponent part에 추가합니다.
    3. 다음 입력 코드 포인트가 숫자인 동안 이를 소비하고 exponent part에 추가합니다.
    4. type을 "number"로 설정합니다.
  6. value를 number part를 10진수로 해석한 결과로 둡니다.

    exponent part가 비어 있지 않으면, 이를 10진수 정수로 해석하고, 10을 그 결과의 거듭제곱으로 올린 다음, 이를 value와 곱하고, value를 그 결과로 설정합니다.

  7. value, type 및 sign character를 반환합니다.
테스트

4.3.14. unicode-range 토큰을 소비하기

이 절에서는 unicode-range 토큰을 소비하는 방법을 설명합니다 코드 포인트 스트림에서. <unicode-range-token>을 반환합니다.

참고: 이 알고리즘은 반환된 코드 포인트가 <unicode-range-token>을 구성하도록 보장하는 데 필요한 처음 몇 코드 포인트의 검증을 수행하지 않습니다. 이 알고리즘을 호출하기 전에 스트림이 unicode-range를 시작하는지 확인하십시오.

참고: 이 토큰은 정상적인 상황에서는 토큰화기에 의해 생성되지 않습니다. 이 알고리즘은 unicode-range 설명자의 값을 소비하기 중에만 호출되며, 이 알고리즘 자체도 특수한 경우에만 호출됩니다 unicode-range 설명자를 파싱하기 위한; 전체 언어에서 이 한 번뿐인 호출은 초기 CSS의 잘못된 구문 설계 때문입니다.

  1. 다음 두 입력 코드 포인트를 소비하고 버립니다.

  2. 가능한 한 많은 16진수 숫자를 소비하되, 6개를 초과하지 않습니다. 6개보다 적은 16진수 숫자를 소비했다면, 가능한 한 많은 U+003F QUESTION MARK (?) 코드 포인트를 소비하되, 16진수 숫자와 U+003F QUESTION MARK (?) 코드 포인트의 총 개수가 6이 되도록 하는 데 필요한 수를 초과하지 않습니다.

    first segment를 소비된 코드 포인트로 둡니다.

  3. first segment에 물음표 코드 포인트가 하나라도 포함되어 있으면:

    1. first segment의 물음표를 U+0030 DIGIT ZERO (0) 코드 포인트로 바꾸고, 그 결과를 16진수로 해석합니다. 이를 start of range로 둡니다.

    2. first segment의 물음표를 U+0046 LATIN CAPITAL LETTER F (F) 코드 포인트로 바꾸고, 그 결과를 16진수로 해석합니다. 이를 end of range로 둡니다.

    3. start of range에서 시작하여 end of range에서 끝나는 새로운 <unicode-range-token>을 반환합니다.

  4. 그렇지 않으면 first segment를 16진수로 해석하고, 그 결과를 start of range로 둡니다.

  5. 다음 2개의 입력 코드 포인트가 U+002D HYPHEN-MINUS (-)이고 그 뒤에 16진수 숫자가 오면, 다음을 수행합니다:

    1. 다음 입력 코드 포인트를 소비합니다.

    2. 가능한 한 많은 16진수 숫자를 소비하되 6개를 초과하지 않습니다. 소비된 코드 포인트를 16진수로 해석합니다. 이를 end of range로 둡니다.

    3. start of range에서 시작하여 end of range에서 끝나는 새로운 <unicode-range-token>을 반환합니다.

  6. 그렇지 않으면 시작과 끝이 모두 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. 파서 철도 다이어그램

이 절은 비규범적입니다.

이 절에서는 파서의 정보 제공용 보기를 제시하며, 철도 다이어그램 형태로 제공합니다.

이 다이어그램은 정보 제공용이며 불완전합니다; "올바른" 스타일시트의 문법을 설명하지만, 오류 처리는 전혀 설명하지 않습니다. 구문을 직관적으로 이해하기 쉽게 하기 위한 목적으로만 제공됩니다.

스타일시트
<whitespace-token> <CDC-token> <CDO-token> 한정 규칙 at-규칙
at-규칙
<at-keyword-token> 구성 요소 값 {} 블록 ;
한정 규칙
구성 요소 값 {} 블록
{} 블록
{ ws* 선언 ; at-규칙 한정 규칙 ws* ws* }
선언
<ident-token> ws* : 구성 요소 값 !important
!important
! ws* <ident-token "important"> ws*
구성 요소 값
보존된 토큰 단순 블록 함수 블록
단순 블록
{ 구성 요소 값 } ( 구성 요소 값 ) [ 구성 요소 값 ]
함수 블록
<function-token> 구성 요소 값 )

5.2. CSS 파싱 결과

파싱 결과는 다음 중 하나일 수 있으며 (또는 이들의 목록일 수 있습니다):

스타일시트

스타일시트에는 규칙 목록이 있습니다.

규칙

규칙은 at-규칙 또는 한정 규칙입니다.

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>이면 토큰 스트림은 비어 있습니다.

토큰을 소비하기

token을 다음 토큰으로 둡니다. 인덱스를 증가시키고, 그런 다음 token을 반환합니다.

토큰을 버리기

토큰 스트림이 비어 있지 않으면, 인덱스를 증가시킵니다.

표시하기

인덱스를 표시된 인덱스에 추가합니다.

표시를 복원하기

표시된 인덱스에서 팝하고, 인덱스를 팝된 값으로 설정합니다.

표시를 버리기

표시된 인덱스에서 팝하고, 팝된 값에는 아무 작업도 하지 않습니다.

공백을 버리기

다음 토큰이 <whitespace-token>인 동안, 토큰을 버립니다.

처리하기

처리하려면, 다음 토큰 유형과 관련 작업 목록이 주어졌을 때, 다음 토큰과 관련된 작업을 수행합니다. 작업 중 하나가 무언가를 반환할 때까지 반복하고, 그런 다음 그것을 반환합니다.

<eof-token>은 개념적인 토큰으로, 실제로 토큰화기가 생성하지 않으며, 토큰 스트림이 소진되었음을 나타내는 데 사용됩니다.

5.4. 파서 진입점

이 절에서 정의한 알고리즘은 고수준 CSS 객체를 CSS 토큰 목록으로부터 생성합니다.

여기의 알고리즘은 토큰 스트림을 입력으로 사용하지만, 편의를 위해 여러 다른 값 유형으로도 호출할 수 있습니다.

주어진 input을 토큰 스트림으로 정규화하려면:

  1. input이 이미 토큰 스트림이면, 이를 반환합니다.

  2. input이 CSS 토큰 및/또는 구성 요소 값의 목록이면, 새 토큰 스트림을 만들고 input을 그 토큰으로 설정한 다음, 이를 반환합니다.

  3. input이 문자열이면, input에서 코드 포인트를 필터링하고, 그 결과를 토큰화한 다음, 토큰 스트림을 반환합니다.

  4. 단언: 앞의 유형만 input으로 전달되어야 합니다.

참고: 다른 명세는 자체 목적을 위한 추가 진입점을 정의할 수 있습니다.

다음 참고 사항은 관련 명세에서 규범적 텍스트로 변환하는 것이 좋으며, 이 명세의 용어와 연결되어야 합니다:

5.4.1. CSS 문법에 따라 무언가를 파싱하기

문자열이나 토큰 목록을 파싱하여 특정 CSS 문법과 일치하는지 확인하고, 일치한다면, 문법에 따라 이를 구조 분해하는 것이 유용한 경우가 많습니다. 이 절에서는 이러한 종류의 연산을 위한 일반적인 훅을 제공합니다. 다음과 같이 호출해야 합니다 "foo를 CSS <color>로 파싱"하거나 이와 비슷하게 호출합니다.

이 알고리즘은 실패 또는, 입력이 제공된 문법과 일치하지 않는 경우, 문법에 따라 입력을 파싱한 결과를 반환하며, 이는 제공된 문법 명세에 대응하는 지정되지 않은 구조입니다. 반환 값은 명세 산문에서만 다루어야 하며, 그곳에서는 표현의 모호성이 문제가 되지 않습니다. 명세 언어 밖에 노출하려는 경우, 결과를 사용하는 명세는 이를 잘 정의된 표현으로 명시적으로 변환해야 하며, 예를 들어 CSS 직렬화 알고리즘을 호출하는 방식이 있습니다 (예: "CSS <string> 값으로 직렬화").

참고: 이 알고리즘과 CSS 문법에 따라 쉼표로 구분된 목록을 파싱하기는 일반적으로 다른 명세가 호출하려는 유일한 파싱 알고리즘입니다. 나머지 파싱 알고리즘은 주로 [CSSOM]과 관련된 "CSS 구조를 명시적으로 구성하는" 경우를 위한 것입니다. 다른 알고리즘 중 하나를 사용해야 한다고 생각한다면 먼저 CSSWG에 지침을 문의하십시오.

input과 CSS grammar 생성 규칙이 주어졌을 때 CSS 문법에 따라 무언가를 파싱하려면 (간단히 파싱이라고도 함):
  1. input을 정규화하고, input을 그 결과로 설정합니다.
  2. input에서 구성 요소 값 목록을 파싱하고, 반환 값을 result로 둡니다.
  3. result를 grammar와 일치시키려고 시도합니다. 성공하면, 일치한 결과를 반환하고; 그렇지 않으면 실패를 반환합니다.

5.4.2. CSS 문법에 따라 쉼표로 구분된 목록을 파싱하기

물론 쉼표를 포함한 문법에 따라 값을 파싱할 수 있지만, 값의 어느 부분이라도 파싱에 실패하면, 전체가 파싱되지 않고, 실패를 반환합니다.

때로는 그것이 원하는 동작이며 (목록 값을 갖는 CSS 속성 등); 다른 경우에는, 쉼표로 구분된 값의 각 하위 부분을 별도로 파싱하도록 하는 것이 더 좋으며, 성공적으로 파싱되는 부분은 한 방식으로 처리하고, 파싱에 실패하는 부분은 다른 방식으로 처리합니다 (일반적으로 이를 무시하며, 예를 들어 <img sizes>가 있습니다).

이 알고리즘은 정확히 이를 수행하기 위한 간편한 훅을 제공합니다. "최상위" 쉼표로 분할된 값 목록을 반환하며, 각 값은 실패이거나 (파싱에 실패한 경우) 파싱 결과입니다 (지정되지 않은 구조이며, 파싱 알고리즘에서 설명한 것과 같습니다).

input과 CSS grammar 생성 규칙이 주어졌을 때 CSS 문법에 따라 쉼표로 구분된 목록을 파싱하려면 (목록을 파싱이라고도 함):
  1. input을 정규화하고, input을 그 결과로 설정합니다.
  2. input에 <whitespace-token>만 포함되어 있으면, 빈 목록을 반환합니다.
  3. input에서 쉼표로 구분된 구성 요소 값 목록을 파싱하고, 반환 값을 list로 둡니다.
  4. list의 각 item에 대해 각각, item을 grammar으로 item을 파싱한 결과로 대체합니다.
  5. list를 반환합니다.

5.4.3. 스타일시트를 파싱하기

선택적인 url location이 주어진 input에서 스타일시트를 파싱하려면:
  1. input이 스타일시트의 바이트 스트림이면, input에서 바이트를 디코딩하고, input을 그 결과로 설정합니다.
  2. input을 정규화하고, input을 그 결과로 설정합니다.
  3. 새 스타일시트를 생성하고, 그 위치를 location으로 설정합니다 (location이 전달되지 않았다면 null).
  4. input에서 스타일시트의 내용을 소비하고, 스타일시트의 규칙을 그 결과로 설정합니다.
  5. 스타일시트를 반환합니다.

5.4.4. 스타일시트의 내용을 파싱하기

input에서 스타일시트의 내용을 파싱하려면:
  1. input을 정규화하고, input을 그 결과로 설정합니다.
  2. input에서 스타일시트의 내용을 소비하고, 그 결과를 반환합니다.

5.4.5. 블록의 내용을 파싱하기

input에서 블록의 내용을 파싱하려면:
  1. input을 정규화하고, input을 그 결과로 설정합니다.
  2. input에서 블록의 내용을 소비하고, 그 결과를 반환합니다.

5.4.6. 규칙을 파싱하기

input에서 규칙을 파싱하려면:
  1. input을 정규화하고, input을 그 결과로 설정합니다.
  2. input에서 공백을 버립니다.
  3. input의 다음 토큰이 <EOF-token>이면, 구문 오류를 반환합니다.

    그렇지 않고, input의 다음 토큰이 <at-keyword-token>이면, input에서 at-규칙을 소비하고, 반환 값을 rule로 둡니다.

    그렇지 않으면, input에서 한정 규칙을 소비하고 반환 값을 rule로 둡니다. 아무것도 반환되지 않았거나 유효하지 않은 규칙 오류가 반환되었다면, 구문 오류를 반환합니다.

  4. input에서 공백을 버립니다.
  5. input의 다음 토큰이 <EOF-token>이면, rule을 반환합니다. 그렇지 않으면 구문 오류를 반환합니다.

5.4.7. 선언을 파싱하기

참고: "선언 목록을 파싱하기"와 달리, 이는 at-규칙이 아니라 선언 하나만 파싱합니다.

input에서 선언을 파싱하려면:
  1. input을 정규화하고, input을 그 결과로 설정합니다.
  2. input에서 공백을 버립니다.
  3. input에서 선언을 소비합니다. 무언가가 반환되었다면 이를 반환합니다. 그렇지 않으면 구문 오류를 반환합니다.

5.4.8. 구성 요소 값을 파싱하기

input에서 구성 요소 값을 파싱하려면:
  1. input을 정규화하고, input을 그 결과로 설정합니다.
  2. input에서 공백을 버립니다.
  3. input이 비어 있으면, 구문 오류를 반환합니다.
  4. input에서 구성 요소 값을 소비하고 반환 값을 value로 둡니다.
  5. input에서 공백을 버립니다.
  6. input이 비어 있으면, value를 반환합니다. 그렇지 않으면, 구문 오류를 반환합니다.

5.4.9. 구성 요소 값 목록을 파싱하기

input에서 구성 요소 값 목록을 파싱하려면:
  1. input을 정규화하고, input을 그 결과로 설정합니다.

  2. input에서 구성 요소 값 목록을 소비하고, 그 결과를 반환합니다.

5.4.10. 쉼표로 구분된 구성 요소 값 목록을 파싱하기

input에서 쉼표로 구분된 구성 요소 값 목록을 파싱하려면:
  1. input을 정규화하고, input을 그 결과로 설정합니다.

  2. groups를 빈 목록으로 둡니다.

  3. input이 비어 있지 않은 동안:

    1. input에서 구성 요소 값 목록을 소비하고, <comma-token>을 중지 토큰으로 사용하여, 그 결과를 groups에 추가합니다.

    2. input에서 토큰을 버립니다.

  4. groups를 반환합니다.

5.5. 파서 알고리즘

다음 알고리즘들이 파서를 구성합니다. 위의 파서 진입점에서 호출되며, 일반적으로 다른 명세에서 직접 호출해서는 안 됩니다.

CSS 파싱은 대소문자를 구분하며, 주어진 컨텍스트에서 구문의 유효성을 확인하는 작업은 적어도 일부 상황에서는 파싱 중에 수행되어야 합니다. 이 명세는 의도적으로 유효성 검사를 가능하게 하기 위해 충분한 컨텍스트를 어떻게 전달해야 하는지는 지정하지 않습니다.

5.5.1. 스타일시트의 내용을 소비하기

토큰 스트림 input에서 스타일시트의 내용을 소비하려면:

rules를 처음에는 비어 있는 규칙의 목록으로 둡니다.

input을 처리합니다:

<whitespace-token>
input에서 토큰을 버립니다.
<EOF-token>
rules를 반환합니다.
<CDO-token>
<CDC-token>
input에서 토큰을 버립니다.
이것은 무엇을 위한 것입니까?

CSS가 처음 도입되던 당시, style 요소는 오래된 브라우저에서 알 수 없는 요소로 처리되었습니다. 이러한 레거시 브라우저에서 그 내용이 페이지에 표시되는 것을 피하기 위해, 스타일시트를 HTML 주석으로 감싸는 것이 일반적인 관행이 되었고, 최신 브라우저는 HTML 주석 구문을 단순히 무시했습니다. 이 요구 사항은 수십 년이 지난 오늘날까지 이어지고 있습니다.

같은 관행은 script 요소에도 적용되었으며, 같은 이유로 HTML 주석 구문은 JS에서 줄 주석(//과 유사)으로 처리됩니다.

<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>이 오면:
이 검사는 무엇을 위한 것입니까?

선언과 한정 규칙은 허용되는 구문이 일반적으로 겹치지 않습니다. 현재 정의된 어떤 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에서 블록을 소비하려면:

단언: 다음 토큰은 <{-token>입니다.

input에서 토큰을 버립니다. input에서 블록의 내용을 소비하고 그 결과를 rules로 둡니다. input에서 토큰을 버립니다.

rules를 반환합니다.

5.5.5. 블록의 내용을 소비하기

토큰 스트림 input에서 블록의 내용을 소비하려면:

참고: 이 알고리즘은 목록을 반환하며, 규칙과 목록 형태의 선언으로 구성됩니다. 부모 컨텍스트에 따라, 목록 형태의 선언은 CSSOM에서 다음 중 하나로 구체화될 수 있습니다 CSSStyleDeclaration, 또는 CSSNestedDeclarations 규칙으로.

rules를 빈 목록으로 두며, 규칙 또는 목록 형태의 선언을 포함합니다.

decls를 선언의 빈 목록으로 둡니다.

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으로 사용합니다.

아무것도 반환되지 않은 경우

아무것도 하지 않습니다

유효하지 않은 규칙 오류가 반환된 경우

decls가 비어 있지 않으면, decls를 rules에 추가하고, decls를 새로운 빈 목록 형태의 선언으로 설정합니다. (그렇지 않으면 아무것도 하지 않습니다.)

규칙이 반환된 경우

decls가 비어 있지 않으면, decls를 rules에 추가하고, decls를 새로운 빈 목록 형태의 선언으로 설정합니다. 규칙을 rules에 추가합니다.

구현 참고 사항

이 명세는 많은 CSS 명세와 마찬가지로, 효율성보다 이해하기 쉬운 것을 우선하도록 작성되었습니다. 여러 알고리즘, 특히 위의 "선언으로 파싱한 다음 규칙으로 파싱"하는 동작은 설명된 그대로 순진하게 구현하면 상당히 비효율적일 수 있습니다.

그러나 이 동작은 가능한 한 "조기 종료"를 허용하도록 신중하게 작성되었습니다. 특히, 대략 종료가 발생할 수 있는 순서대로:

마찬가지로, 파싱 요구 사항은 선언을 파싱하면서 그 문법을 검사하는 데 의존하도록 지정되어 있지만, 일반 CSS 구문 위에 CSS가 아닌 언어를 구현하려는 일반적인 프로세서는 선언이 식별자, 콜론으로 시작하는지만 확인하고, 그 뒤에 오직 {}-블록만 포함하거나 {}-블록을 전혀 포함하지 않는지만 확인해도 됩니다. foo:hover ... {} 같은 경우에는 첫 번째 토큰에서 조기 종료할 수 없으므로 문법을 알고 있는 구현보다 파싱에 약간 더 많은 시간을 쓸 뿐입니다.

테스트

5.5.6. 선언을 소비하기

선택적 bool nested(기본값 false)가 주어졌을 때, 토큰 스트림 input에서 선언을 소비하려면:

decl을 새 선언으로 두며, 이름은 처음에 비어 있고 값은 빈 목록으로 설정합니다.

  1. 다음 토큰이 <ident-token>이면, input에서 토큰을 소비하고 decl의 이름을 해당 토큰의 값으로 설정합니다.

    그렇지 않으면, input에서 잘못된 선언의 나머지를 소비하고, nested와 함께, 아무것도 반환하지 않습니다.

  2. input에서 공백을 버립니다.
  3. 다음 토큰이 <colon-token>이면, input에서 토큰을 버립니다.

    그렇지 않으면, input에서 잘못된 선언의 나머지를 소비하고, nested와 함께, 아무것도 반환하지 않습니다.

  4. input에서 공백을 버립니다.
  5. input에서 구성 요소 값 목록을 소비하고, nested와 함께, <semicolon-token>을 중지 토큰으로 사용하여, decl의 값을 그 결과로 설정합니다.
  6. decl의 값에서 마지막 두 비-<whitespace-token>이 값이 "!"인 <delim-token>이고 그 뒤에 값이 "important"와 ASCII 대소문자를 구분하지 않고 일치하는 <ident-token>이 오면, 이를 decl의 값에서 제거하고 decl의 important 플래그를 설정합니다.
  7. decl의 값에서 마지막 항목이 <whitespace-token>인 동안, 해당 토큰을 제거합니다.
  8. decl의 이름이 사용자 정의 속성 이름 문자열이면, decl의 original text를 원래 소스 텍스트 문자열에서 decl 값의 토큰에 해당하는 구간으로 설정합니다.

    그렇지 않고 decl의 값에 연관된 토큰이 <{-token>인 최상위 단순 블록이 포함되어 있고 또한 다른 어떤 비-<whitespace-token> 값도 포함되어 있다면, 아무것도 반환하지 않습니다. (즉, 최상위 {}-블록은 비사용자 정의 속성의 전체 값으로만 허용됩니다.)

    그렇지 않고 decl의 이름이 "unicode-range"와 ASCII 대소문자를 구분하지 않고 일치하면, unicode-range 설명자의 값을 소비하고 원래 소스 텍스트 문자열에서 구성 요소 값 목록을 소비하기 호출이 반환한 토큰에 해당하는 구간을 사용하며, decl의 값을 그 결과로 바꿉니다.

    테스트
  9. decl이 현재 컨텍스트에서 유효하면, 이를 반환하고; 그렇지 않으면 아무것도 반환하지 않습니다.
토큰 스트림 input과 bool nested가 주어졌을 때, 잘못된 선언의 나머지를 소비하려면:

input을 처리합니다:

<eof-token>
<semicolon-token>

input에서 토큰을 버리고, 아무것도 반환하지 않습니다.

<}-token>

nested가 true이면, 아무것도 반환하지 않습니다. 그렇지 않으면, 토큰을 버립니다.

그 밖의 모든 것

input에서 구성 요소 값을 소비하고, 아무것도 하지 않습니다.

5.5.7. 구성 요소 값 목록을 소비하기

선택적 토큰 stop token과 선택적 boolean nested(기본값 false)가 주어졌을 때, 토큰 스트림 input에서 구성 요소 값 목록을 소비하려면:

values를 구성 요소 값의 빈 목록으로 둡니다.

input을 처리합니다:

<eof-token>
stop token (전달된 경우)

values를 반환합니다.

<}-token>

nested가 true이면, values를 반환합니다.

그렇지 않으면, 이는 파싱 오류입니다. input에서 토큰을 소비하고 그 결과를 values에 추가합니다.

그 밖의 모든 것

input에서 구성 요소 값을 소비하고, 그 결과를 values에 추가합니다.

테스트

5.5.8. 구성 요소 값을 소비하기

토큰 스트림 input에서 구성 요소 값을 소비하려면:

input을 처리합니다:

<{-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 설명자의 값을 소비하려면:

  1. unicode ranges allowed를 true로 설정하여 input string을 토큰화한 결과를 tokens로 둡니다.

  2. 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과 같은 의미를 가집니다.

예:

2n+0   /* 목록의 모든 짝수 번째 요소를 나타냅니다 */
even   /* 동일 */
4n+1   /* 목록의 1번째, 5번째, 9번째, 13번째 등의 요소를 나타냅니다 */

A와 B의 값은 음수일 수 있지만, n ≥ 0인 경우 An+B의 양수 결과만 사용됩니다.

예:

-1n+6   /* 목록의 처음 6개 요소를 나타냅니다 */
-4n+10  /* 목록의 2번째, 6번째, 10번째 요소를 나타냅니다 */

A와 B가 모두 0이면, 의사 클래스는 목록의 어떤 요소도 나타내지 않습니다.

6.1. 비형식적 구문 설명

이 절은 비규범적입니다.

A가 0이면 An 부분을 생략할 수 있습니다 (B 부분이 이미 생략된 경우는 제외). An이 포함되지 않고 B가 음수가 아니면, B 앞의 + 기호도 (허용되는 경우) 생략할 수 있습니다. 이 경우 구문은 단순히 B로 간소화됩니다.

예:

0n+5   /* 목록의 5번째 요소를 나타냅니다 */
5      /* 동일 */

A가 1 또는 -1이면, 규칙에서 1을 생략할 수 있습니다.

예:

따라서 다음 표기법은 서로 동일합니다:

1n+0   /* 목록의 모든 요소를 나타냅니다 */
n+0    /* 동일 */
n      /* 동일 */

B가 0이면 모든 A번째 요소가 선택됩니다. 이 경우, A 부분이 이미 생략된 경우가 아니라면 +B(또는 -B) 부분을 생략할 수 있습니다.

예:

2n+0   /* 목록의 모든 짝수 번째 요소를 나타냅니다 */
2n     /* 동일 */

B가 음수이면 그 빼기 기호가 + 기호를 대체합니다.

유효한 예:

3n-6

유효하지 않은 예:

3n + -6

An과 B 부분이 모두 있을 때 이를 구분하는 + 또는 -의 양쪽에 공백을 사용할 수 있습니다.

공백이 있는 유효한 예:

3n + 1
+3n - 2
-n+ 6
+6

공백이 있는 유효하지 않은 예:

3 n
+ 2n
+ 2

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"으로 시작하는 식별자 앞에 오는 경우, 두 토큰 사이에 공백이 없어야 하며, 그렇지 않으면 토큰이 위 문법과 일치하지 않습니다. 다른 모든 두 토큰 사이에서는 공백이 유효하며(무시됩니다).

생성 규칙의 각 절은 다음과 같이 해석됩니다:

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를 어떻게 사용하는지도 정의해야 합니다.

그러나 많은 경우, 블록은 주어진 유형의 어떤 구문도 유효하게 포함할 수 없습니다. 이러한 경우를 더 명시적으로 나타내기 위해, 다음 생성 규칙을 사용할 수 있습니다

이들은 모두 파싱 측면에서 <block-contents>와 정확히 동일하지만, 함께 제공되는 산문에서는 자동으로 유효하지 않은 범주를 제외한 범주의 유효성만 정의하면 됩니다.

다양한 생성 규칙의 몇 가지 예:
예를 들어 @font-face의 문법은 다음과 같이 작성할 수 있습니다:
<@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-규칙과 연결됩니다.

8.3. @charset 규칙

스타일시트의 대체 인코딩을 결정하는 데 사용되는 알고리즘은 파일의 맨 처음 몇 바이트에서 특정 바이트 시퀀스를 찾으며, 이는 이름이 "@charset"인 at-규칙의 구문 형태를 가집니다.

테스트

그러나 실제로 이름이 @charset인 at-규칙은 없습니다. 스타일시트가 실제로 파싱될 때, @charset 규칙이 나타나면 인식되지 않는 규칙으로 처리해야 하며, 따라서 스타일시트의 문법을 검사할 때 유효하지 않은 것으로 버려야 합니다.

참고: CSS 2.1에서는 @charset이 유효한 규칙이었습니다. 일부 레거시 명세에서는 여전히 @charset 규칙을 참조하고, 스타일시트에서의 존재를 명시적으로 언급할 수 있습니다.

테스트

9. 직렬화

이 명세에서 설명하는 토큰화기는 주석에 대한 토큰을 생성하지 않으며, 다른 방식으로도 이를 보존하지 않습니다. 구현은 주석의 내용과 토큰 스트림에서의 위치를 보존할 수 있습니다. 그렇게 하는 경우, 이 보존된 정보는 파싱 단계에 영향을 주어서는 안 됩니다.

이 명세는 일반적으로 CSS를 직렬화하는 방법을 정의하지 않으며, 그 작업은 [CSSOM] 및 개별 기능 명세에 맡깁니다. 특히 주석과 공백의 직렬화는 정의하지 않습니다.

직렬화에 대한 유일한 요구 사항은 파싱과 "왕복"해야 한다는 것입니다, 즉 스타일시트를 파싱하면 파싱한 뒤 직렬화하고 다시 파싱한 것과 동일한 데이터 구조가 생성되어야 합니다, 연속된 <whitespace-token>은 예외이며, 하나의 토큰으로 축약될 수 있습니다.

참고: 이 예외가 존재할 수 있는 이유는 CSS 문법에서 어떤 양의 공백도 항상 하나의 스페이스와 동일하게 해석하기 때문입니다.

이 요구 사항을 충족하려면:
식별자 함수 URL 잘못된 URL - 숫자 백분율 차원 CDC ( * %
식별자 ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
at-키워드 ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
해시 ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
차원 ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
# ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
- ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
숫자 ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
@ ✗ ✗ ✗ ✗ ✗ ✗
. ✗ ✗ ✗
+ ✗ ✗ ✗
/ ✗
테스트

9.1. <a-n-plus-b> 직렬화

정수 값 A 및 B를 사용하여 <a-n-plus-b> 값을 직렬화하려면:
  1. A가 0이면, B의 직렬화를 반환합니다.

  2. 그렇지 않으면 result를 처음에 빈 문자열로 둡니다.

  3. A가 1

    "n"을 result에 추가합니다.

    A가 -1

    "-n"을 result에 추가합니다.

    A가 0이 아님

    A를 직렬화하여 result에 추가하고, 그런 다음 "n"을 result에 추가합니다.

  4. B가 0보다 큼

    "+"를 result에 추가하고, 그런 다음 B의 직렬화를 result에 추가합니다.

    B가 0보다 작음

    B의 직렬화를 result에 추가합니다.

  5. result를 반환합니다.

10. 개인정보 보호 고려사항

이 명세는 새로운 개인정보 보호 우려를 도입하지 않습니다.

11. 보안 고려사항

이 명세는 모든 입력에 대해 CSS 파싱이 이제 명확하게 정의된다는 점에서 보안을 향상시킵니다.

화이트리스트/필터와 같은 오래된 파서가 이 명세와 다르게 파싱하는 한, 어느 정도 안전하지 않지만, 이전 파싱 명세에는 브라우저가 서로 다르게 해석한 모호한 코너 케이스가 많이 남아 있었으므로, 이러한 필터는 이미 잠재적으로 안전하지 않았으며, 이 명세는 상황을 악화시키지 않습니다.

12. 변경 사항

이 절은 비규범적입니다.

12.1. 2021년 12월 24일 후보 권고안 초안 이후의 변경 사항

다음과 같은 실질적인 변경 사항이 이루어졌습니다:

12.2. 2019년 8월 16일 후보 권고안 이후의 변경 사항

다음과 같은 실질적인 변경 사항이 이루어졌습니다:

다음과 같은 편집상 변경 사항이 이루어졌습니다:

12.3. 2014년 2월 20일 후보 권고안 이후의 변경 사항

다음과 같은 실질적인 변경 사항이 이루어졌습니다:

다음과 같은 편집상 변경 사항이 이루어졌습니다:

의견 처리 결과를 확인할 수 있습니다.

12.4. 2013년 11월 5일 최종 검토 워킹 드래프트 이후의 변경 사항

12.5. 2013년 9월 19일 워킹 드래프트 이후의 변경 사항

12.6. CSS 2.1 및 Selectors 레벨 3 이후의 변경 사항

참고: 이 명세의 목적은 현실과 일치하는 것입니다; CSS2.1에서의 변경 사항은 거의 항상 CSS 2.1이 실제 브라우저 동작과 일치하지 않는 무언가를 지정했거나, 무언가를 지정하지 않은 채 남겨 두었기 때문입니다. 어떤 세부 사항이 브라우저와 일치하지 않는다면, 알려주시기 바랍니다 거의 확실히 의도하지 않은 것이기 때문입니다.

바이트 스트림 디코딩의 변경 사항:

토큰화 변경 사항:

파싱 변경 사항:

Selectors 레벨 3 [SELECT] 이후의 An+B 변경 사항:

감사의 말

다음 분들의 피드백과 기여에 감사드립니다: 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.

적합성

문서 규칙

적합성 요구 사항은 다음의 조합으로 표현됩니다 설명적 단언과 RFC 2119 용어입니다. “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY” 및 “OPTIONAL”이라는 키워드는 이 문서의 규범적 부분에서 RFC 2119에 설명된 대로 해석해야 합니다. 그러나 가독성을 위해 이러한 단어는 모두 대문자로 이 명세에 표시되지 않습니다.

이 명세의 모든 텍스트는 다음 절을 제외하고 규범적입니다 명시적으로 비규범적이라고 표시된 절, 예제 및 참고입니다. [RFC2119]

이 명세의 예제는 “예를 들어”라는 표현으로 시작하거나 class="example"을 사용하여 규범적 텍스트와 구분되며, 다음과 같습니다:

이것은 정보 제공용 예제의 예입니다.

정보 제공용 참고는 “참고”라는 단어로 시작하며 다음과 구분됩니다 class="note"를 사용하여 규범적 텍스트와, 다음과 같습니다:

참고: 이것은 정보 제공용 참고입니다.

주의 사항은 특별한 주의를 환기하도록 스타일이 지정된 규범적 절이며 <strong class="advisement">를 사용하여 다른 규범적 텍스트와 구분되며, 다음과 같습니다: UA는 접근 가능한 대안을 제공해야 합니다.

테스트

이 명세의 내용과 관련된 테스트는 이와 같은 “테스트” 블록에 문서화될 수 있습니다. 이러한 블록은 모두 비규범적입니다.


적합성 클래스

이 명세에 대한 적합성은 세 가지 적합성 클래스에 대해 정의됩니다:

스타일시트
CSS 스타일시트.
렌더러
UA로 스타일시트의 의미를 해석하고 렌더링하는 이를 사용하는 문서입니다.
작성 도구
UA로 스타일시트를 작성합니다.

스타일시트는 이 명세에 적합합니다 이 모듈에 정의된 구문을 사용하는 모든 문장이 유효하고 일반 CSS 문법 및 각각의 개별 문법에 따르며 이 모듈에 정의된 기능에 맞는 경우입니다.

렌더러는 이 명세에 적합합니다 다음에 정의된 대로 스타일시트를 해석하는 것에 더하여 적절한 명세에 따라, 정의된 모든 기능을 지원하고 이 명세에 따라 올바르게 파싱하며 그에 따라 문서를 렌더링하는 경우입니다. 그러나 장치의 한계 때문에 UA가 문서를 올바르게 렌더링하지 못해도 UA가 부적합해지는 것은 아닙니다. (예를 들어 UA는 흑백 모니터에서 색상을 렌더링할 필요가 없습니다.)

작성 도구는 이 명세에 적합합니다 다음에 따라 구문적으로 올바른 스타일시트를 작성하고 일반 CSS 문법과 각 기능의 개별 문법을 이 모듈에서 따르며, 스타일시트의 다른 모든 적합성 요구 사항을 충족하고 이 모듈에 설명된 대로 동작하는 경우입니다.

부분 구현

작성자가 전방 호환 파싱 규칙을 활용하여 대체 값을 지정할 수 있도록, CSS 렌더러는 반드시 유효하지 않은 것으로 처리하고(무시하고 적절하게) 모든 at-규칙, 속성, 속성 값, 키워드, 및 사용할 수 있는 수준의 지원이 없는 기타 구문 구조를 지원해야 합니다. 특히 사용자 에이전트는 절대로 선택적으로 지원되지 않는 구성 요소 값을 무시하고 하나의 다중 값 속성 선언에서 지원되는 값을 적용해서는 안 됩니다: 어떤 값이라도 유효하지 않은 것으로 간주되면 (지원되지 않는 값은 반드시 그래야 하므로), CSS에서는 전체 선언을 무시해야 합니다.

불안정 및 독점 기능의 구현

향후 안정적인 CSS 기능과의 충돌을 피하기 위해, CSSWG는 모범 사례를 따를 것을 권장합니다 CSS의 불안정한 기능 및 독점 확장의 구현에 대해.

비실험적 구현

명세가 후보 권고안 단계에 도달하면, 비실험적 구현이 가능하며, 구현자는 접두사 없는 구현을 모든 CR 수준 기능에 대해 공개하는 것이 좋으며 명세에 따라 올바르게 구현되었음을 입증할 수 있어야 합니다.

CSS의 상호운용성을 확립하고 유지하기 위해 구현 전반에서, CSS 워킹 그룹은 비실험적 CSS 렌더러가 구현 보고서(필요한 경우 해당 구현 보고서에 사용된 테스트 케이스)를 W3C에 제출한 뒤 CSS 기능의 접두사 없는 구현을 공개할 것을 요청합니다. 테스트 케이스는 W3C에 제출되면 CSS 워킹 그룹의 검토 및 수정을 받습니다.

테스트 케이스 및 구현 보고서 제출에 대한 자세한 정보는 CSS 워킹 그룹 웹사이트에서 확인할 수 있습니다: https://www.w3.org/Style/CSS/Test/. 질문은 다음으로 보내야 합니다 public-css-testsuite@w3.org 메일링 리스트로.

CR 종료 기준

이 명세가 제안 권고안으로 진전하려면, 최소 두 개의 독립적이고 상호운용 가능한 구현이 있어야 합니다 각 기능에 대해. 각 기능은 서로 다른 제품 집합에서 구현될 수 있으며, 모든 기능을 하나의 제품이 구현해야 한다는 요구 사항은 없습니다. 이 기준의 목적상 다음을 정의합니다 용어를:

독립적
각 구현은 서로 다른 주체가 개발해야 하며 코드를 공유하거나 재사용하거나 파생해서는 안 됩니다 다른 적격 구현에서 사용된 코드에서. 코드 중 이 명세의 구현과 관련이 없는 부분은 이 요구 사항에서 제외됩니다.
상호운용 가능
각각의 테스트 케이스를 통과하는 것을 의미합니다 공식 CSS 테스트 스위트에서, 또는 구현이 웹 브라우저가 아닌 경우 동등한 테스트를 통과합니다. 테스트 스위트의 모든 관련 테스트에는 동등한 테스트가 만들어져야 하며 그러한 사용자 에이전트(UA)를 상호운용성 입증에 사용하려는 경우입니다. 또한 그러한 UA를 상호운용성 입증에 사용하려면 하나 이상의 추가 UA도 해당 동등한 테스트를 같은 방식으로 통과할 수 있어야 하며 이는 상호운용성을 위한 것입니다. 동등한 테스트는 공개적으로 동료 검토를 위해 제공되어야 합니다.
구현
다음 조건을 충족하는 사용자 에이전트:
  1. 명세를 구현합니다.
  2. 일반 대중이 사용할 수 있습니다. 구현은 출시된 제품 또는 기타 공개적으로 사용 가능한 버전 (즉, 베타 버전, 미리보기 릴리스 또는 "nightly build")일 수 있습니다. 출시되지 않은 제품 릴리스는 최소 한 달 동안 기능을 구현한 상태여야 안정성을 입증할 수 있습니다.
  3. 실험적이지 않습니다(즉, 특별히 설계된 버전으로 테스트 스위트를 통과하기 위한 것이며 일반적인 사용을 목적으로 하지 않는 향후 버전이 아닙니다).

이 명세는 최소 6개월 동안 후보 권고안으로 유지됩니다.

색인

이 명세에서 정의된 용어

다음에 의해 정의된 용어 참조

참고 문헌

규범적 참조

[CSS-CASCADE-3]
Elika Etemad; Tab Atkins Jr.. CSS 캐스케이딩 및 상속 레벨 3. 2021년 2월 11일. REC. URL: https://www.w3.org/TR/css-cascade-3/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS 캐스케이딩 및 상속 레벨 5. 2022년 1월 13일. CR. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-COUNTER-STYLES-3]
Tab Atkins Jr.. CSS 카운터 스타일 레벨 3. 2021년 7월 27일. CR. URL: https://www.w3.org/TR/css-counter-styles-3/
[CSS-FONTS-4]
Chris Lilley. CSS 글꼴 모듈 레벨 4. 13 2026년 9월. WD. URL: https://www.w3.org/TR/css-fonts-4/
[CSS-NESTING-1]
Tab Atkins Jr.. CSS 중첩 모듈 레벨 1. 2026년 1월 22일. WD. URL: https://www.w3.org/TR/css-nesting-1/
[CSS-PAGE-3]
Elika Etemad. CSS 페이지 미디어 모듈 레벨 3. 2023년 9월 14일. WD. URL: https://www.w3.org/TR/css-page-3/
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin. CSS 구문 모듈 레벨 3. 2021년 12월 24일. CRD. URL: https://www.w3.org/TR/css-syntax-3/
[CSS-TYPED-OM-1]
Tab Atkins Jr.; François Remy. CSS Typed OM 레벨 1. 2024년 3월 21일. WD. URL: https://www.w3.org/TR/css-typed-om-1/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS 값 및 단위 모듈 레벨 4. 2024년 3월 12일. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-VARIABLES]
Tab Atkins Jr.. 캐스케이딩 변수를 위한 CSS 사용자 정의 속성 모듈 레벨 1. 2022년 6월 16일. CR. URL: https://www.w3.org/TR/css-variables-1/
[CSS3-CONDITIONAL]
Chris Lilley; David Baron; Elika Etemad. CSS 조건부 규칙 모듈 레벨 3. 2024년 8월 15일. CRD. URL: https://www.w3.org/TR/css-conditional-3/
[CSSOM]
Daniel Glazman; Emilio Cobos Álvarez. CSS 객체 모델 (CSSOM). 2021년 8월 26일. WD. URL: https://www.w3.org/TR/cssom-1/
[ENCODING]
Anne van Kesteren. 인코딩 표준. 현행 표준. URL: https://encoding.spec.whatwg.org/
[HTML]
Ian Hickson. HTML. 현행 표준. URL: http://whatwg.org/html
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 표준. 현행 표준. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. 요구 수준을 나타내기 위해 RFC에서 사용하는 키워드. 1997년 3월. 현재 모범 사례. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. Selectors 레벨 4. 2026년 1월 22일. WD. URL: https://www.w3.org/TR/selectors-4/
[URL]
Anne van Kesteren. URL 표준. 현행 표준. URL: https://url.spec.whatwg.org/

비규범적 참조

[CSS-COLOR-4]
Tab Atkins Jr.; Chris Lilley; Lea Verou. CSS 색상 모듈 레벨 4. 2026년 9월 26일. CRD. URL: https://www.w3.org/TR/css-color-4/
[CSS-COLOR-5]
Chris Lilley; Una Kravets; Lea Verou. CSS 색상 모듈 레벨 5. 2026년 9월 13일. WD. URL: https://www.w3.org/TR/css-color-5/
[CSS-FONTS-5]
Chris Lilley. CSS 글꼴 모듈 레벨 5. 13 2026년 9월. WD. URL: https://www.w3.org/TR/css-fonts-5/
[CSS-NAMESPACES-3]
Elika Etemad. CSS 네임스페이스 모듈 레벨 3. 2014년 3월 20일. REC. URL: https://www.w3.org/TR/css-namespaces-3/
[CSS-TEXT-DECOR-3]
Elika Etemad; Koji Ishii. CSS 텍스트 장식 모듈 레벨 3. 2022년 5월 5일. CRD. URL: https://www.w3.org/TR/css-text-decor-3/
[CSS-TEXT-DECOR-4]
Elika Etemad; Koji Ishii. CSS 텍스트 장식 모듈 레벨 4. 2022년 5월 4일. WD. URL: https://www.w3.org/TR/css-text-decor-4/
[CSS-TRANSFORMS-1]
Simon Fraser; et al. CSS 변형 모듈 레벨 1. 2019년 2월 14일. CR. URL: https://www.w3.org/TR/css-transforms-1/
[CSS-VALUES-5]
Tab Atkins Jr.; Elika Etemad; Miriam Suzanne. CSS 값 및 단위 모듈 레벨 5. 2024년 11월 11일. WD. URL: https://www.w3.org/TR/css-values-5/
[CSS2]
Bert Bos; et al. 캐스케이딩 스타일시트 레벨 2 개정 1(CSS 2.1) 명세. 2011년 6월 7일. REC. URL: https://www.w3.org/TR/CSS2/
[CSS3-ANIMATIONS]
David Baron; et al. CSS 애니메이션 레벨 1. 2023년 3월 2일. WD. URL: https://www.w3.org/TR/css-animations-1/
[MEDIAQ]
Tab Atkins Jr.; Florian Rivoal. 미디어 쿼리 레벨 4. 2026년 2월 19일. CRD. URL: https://www.w3.org/TR/mediaqueries-4/
[MEDIAQUERIES-5]
Tab Atkins Jr.; et al. 미디어 쿼리 레벨 5. 2026년 2월 19일. WD. URL: https://www.w3.org/TR/mediaqueries-5/
[SELECT]
Tantek Çelik; et al. Selectors 레벨 3. 6 2018년 11월. REC. URL: https://www.w3.org/TR/selectors-3/