이 모듈은 CSS 스타일시트 및 CSS 구문을 사용하는 기타 항목의 추상 구문과 파싱을 정의한다.
URL: https://drafts.csswg.org/css-syntax/#typedef-function-token
Title: CSS Syntax Module Level 3
이 절은 규범적이지 않습니다.
이 모듈은 CSS 스타일시트 및 CSS 구문을 사용하는 기타 항목(예: HTML style 속성)의 추상 구문과 파싱을 정의합니다.
이 모듈은 유니코드 코드 포인트 스트림(즉, 텍스트)을 CSS 토큰 스트림으로 변환하고, 이어서 스타일시트, 규칙, 선언과 같은 CSS 객체로 변환하는 알고리즘을 정의합니다.
이 모듈은 CSS 스타일시트의 구문과 파싱을 정의합니다. 이는 CSS 2.1에서 정의된 어휘 스캐너와 문법을 대체합니다.
이 절은 규범적이지 않습니다.
CSS 문서는 문서의 요소에 스타일을 적용하는 스타일 규칙—문서에 스타일을 적용하는 정규화 규칙—과, CSS 문서에 대한 특수 처리 규칙이나 값을 정의하는 앳-규칙으로 이루어진 연속입니다.
정규화 규칙은 프렐류드(prelude)로 시작한 뒤, 선언의 시퀀스를 담는 {}로 감싼 블록을 가집니다. 프렐류드의 의미는 규칙이 등장하는 컨텍스트에 따라 달라집니다. 스타일 규칙에서는 선언이 적용될 요소를 지정하는 셀렉터입니다. 각 선언은 이름, 콜론, 선언 값으로 구성됩니다. 선언은 세미콜론으로 구분됩니다.
전형적인 규칙은 다음과 같을 수 있습니다:
cssp > a { color: blue; text-decoration: underline; }
위 규칙에서 "p > a"는 셀렉터이며, 소스 문서가 HTML이라면 p 요소의 자식인 모든 a 요소를 선택합니다.
"color: blue"는 셀렉터에 매치되는 요소에 대해 color 속성 값이 blue여야 함을 지정하는 선언입니다. 마찬가지로 text-decoration 속성 값이 underline여야 함을 지정합니다.
앳-규칙은 모두 서로 다르지만 공통된 기본 구조가 있습니다. 앳-규칙은 "@" 코드 포인트로 시작한 다음 CSS 키워드로 된 이름이 옵니다. 일부 앳-규칙은 단순한 문(statement)으로, 이름 뒤에 동작을 지정하는 CSS 값이 오고 마지막에 세미콜론으로 끝납니다. 다른 일부는 블록이며, 이름 뒤에 CSS 값이 올 수도 있지만 정규화 규칙과 유사하게 {}로 감싼 블록으로 끝납니다. 이 블록의 내용도 해당 앳-규칙에 따라 다릅니다. 때로는 정규화 규칙처럼 선언 시퀀스를 포함하고, 다른 때에는 추가 블록이나 앳-규칙, 또는 전혀 다른 구조를 포함할 수 있습니다.
다음은 포함 가능한 다양한 구문을 보여주는 앳-규칙 예시들입니다.
css@import "my-styles.css";
@import앳-규칙은 단순한 문입니다. 이름 뒤에 하나의 문자열 또는 url() 함수가 와서 가져올 스타일시트를 가리킵니다.
css@page :left { margin-left: 4cm; margin-right: 3cm; }
@page앳-규칙은 선택적 페이지 셀렉터(의사 클래스 :left) 뒤에, 인쇄 시 페이지에 적용되는 속성 블록이 옵니다. 이 점에서 일반 스타일 규칙과 매우 비슷하지만, 속성이 어떤 "요소"가 아니라 페이지 자체에 적용된다는 점이 다릅니다.
css@media print { body { font-size: 10pt } }
@media앳-규칙은 미디어 타입과 선택적인 미디어 쿼리 목록으로 시작합니다. 블록에는 전체 규칙이 들어 있으며, @media 조건이 충족될 때만 적용됩니다.
속성 이름과 앳-규칙 이름은 항상 식별자 시퀀스입니다. 이는 식별자 시작 코드 포인트로 시작하거나, 하이픈 두 개, 또는 하이픈 하나 뒤에 식별자 시작 코드 포인트가 와야 하며, 이후에는 0개 이상의 식별자 코드 포인트를 포함할 수 있습니다. CSS가 구문에 사용하는 코드 포인트를 포함해 어떤 코드 포인트든 이스케이프하여 포함할 수 있습니다.
셀렉터의 구문은 Selectors 사양에 정의되어 있습니다. 마찬가지로 다양한 CSS 값의 구문은 Values & Units 사양에 정의되어 있습니다. 개별 앳-규칙의 특수 구문은 이를 정의하는 사양에서 찾을 수 있습니다.
이 절은 규범적이지 않습니다.
어떤 유니코드 코드 포인트도 이스케이프하여 식별자 시퀀스 또는 따옴표 문자열에 포함할 수 있습니다. CSS 이스케이프 시퀀스는 백슬래시()로 시작하며, 다음으로 이어집니다:
값이 "&B"인 식별자 시퀀스는 \26 B 또는 \000026B로 쓸 수 있습니다.
이스케이프 시퀀스 뒤에 오는 "진짜" 공백은 두 번 써야 합니다.
이 절은 규범적이지 않습니다.
CSS에서 오류가 발생하면 파서는 가능한 한 부드럽게 복구하려 하며, 정상 파싱으로 돌아가기 전에 최소한의 내용만 버립니다. 이는 오류가 항상 실수만을 의미하지 않기 때문입니다. 새로운 구문은 오래된 파서에겐 오류처럼 보이며, 오래된 UA에서 완전히 깨질 걱정 없이 언어에 새 구문을 추가할 수 있는 것이 유용합니다.
정확한 오류 복구 동작은 파서 자체에 자세히 기술되어 있지만, 충분히 간단하여 짧은 설명도 상당히 정확합니다.
예를 들어 translateX() 함수의 구문은 다음과 같습니다:
translateX( [<translation-value>](https://drafts.csswg.org/css-syntax/) )
하지만 스타일시트가 함수를 닫지 않은 채로 끝날 수 있습니다:
css.foo { transform: translate(50px
CSS 파서는 이를 하나의 선언을 포함한 스타일 규칙으로 파싱하며, 선언 값은 이름이 "translate"인 함수입니다. 이는 토큰 스트림에 종료 토큰이 나타나지 않았더라도 위 문법과 매치됩니다. 파서가 끝났을 때는 종료 토큰의 존재 여부를 더 이상 판단할 수 없고, 블록과 함수가 있다는 사실만 남기 때문입니다.
각 구성요소(선언, 스타일 규칙, 앳-규칙)가 파싱된 뒤, 사용자 에이전트는 기대하는 문법과 대조합니다. 문법에 매치하지 않으면 무효이며 UA는 이를 무시하고, 존재하지 않았던 것처럼 취급합니다.
사용자 에이전트는 text/css 리소스에서 [CSSOM] 트리를 생성하기 위해 이 사양에서 опис된 파싱 규칙을 사용해야 합니다. 이러한 규칙을 합쳐 CSS 파서라고 합니다.
이 사양은 CSS 문서가 문법적으로 올바르든 아니든 파싱 규칙을 정의합니다. 파싱 알고리즘의 특정 지점은 파싱 오류(parse error)라고 합니다. 파싱 오류에 대한 오류 처리는 잘 정의되어 있습니다. 사용자 에이전트는 이러한 문제를 만났을 때 아래에 опис된 대로 동작하거나, 아래 규칙을 적용하고 싶지 않은 첫 오류에서 처리를 중단해야 합니다.
적합성 검사기는 문서에 하나 이상의 파싱 오류 조건이 존재하면 사용자에게 최소 한 개의 파싱 오류 조건을 보고해야 하며, 문서에 파싱 오류 조건이 없으면 보고해서는 안 됩니다. 적합성 검사기는 여러 파싱 오류 조건이 존재하면 하나 이상을 보고할 수 있습니다. 적합성 검사기는 파싱 오류에서 복구할 필요는 없지만, 복구한다면 사용자 에이전트와 같은 방식으로 복구해야 합니다.
CSS 파싱 과정의 입력은 유니코드 코드 포인트 스트림이며, 토큰화 단계와 트리 구성 단계를 거칩니다. 출력은 CSSStyleSheet 객체입니다.
참고: 스크립팅을 지원하지 않는 구현은 실제로 CSSOM의 CSSStyleSheet 객체를 만들 필요는 없지만, 그런 경우에도 CSSOM 트리는 사양의 나머지 부분을 위한 모델로 사용됩니다.
스타일시트를 파싱할 때, 토큰화 단계에 대한 입력인 유니코드 코드 포인트 스트림은 사용자 에이전트에 의해 처음에는 바이트 스트림(보통 네트워크 또는 로컬 파일 시스템에서 옴)으로 보일 수 있습니다. 그 경우 사용자 에이전트는 특정 문자 인코딩에 따라 바이트를 코드 포인트로 디코드해야 합니다.
스타일시트의 바이트 스트림을 코드 포인트 스트림으로 디코드하려면:
스타일시트의 폴백 인코딩 결정 알고리즘을 수행하고, 결과를 fallback이라 합니다.
fallback 인코딩 fallback으로 스타일시트의 바이트 스트림을 디코드하고, 결과를 반환합니다.
참고: decode 알고리즘은 바이트 순서 표식(BOM)에 우선순위를 두며, BOM이 없을 때만 폴백을 사용합니다.
스타일시트의 폴백 인코딩을 결정하려면:
XX 바이트는 0x16XX 바이트 시퀀스를 ASCII로 해석하여 만든 문자열로부터 인코딩 가져오기를 수행합니다.이 바이트 시퀀스는 무엇을 의미하나요?
위 바이트 시퀀스를 ASCII로 디코드하면 문자열 "@charset "…";"이며, "…"는 인코딩 레이블에 해당하는 바이트 시퀀스입니다.
반환값이 utf-16be 또는 utf-16le라면 utf-8을 반환하고, 실패가 아니라면 그 값을 반환합니다.
선언이 utf-16이라고 말하는데 왜 utf-8을 쓰나요?
인코딩 선언의 바이트는 ASCII로 “@charset "…";”를 철자하지만, UTF-16은 ASCII 호환이 아닙니다. 즉, 올바른 바이트를 얻기 위해 문서에 완전한 횡설수설(예: 䁣桡牳整•utf-16be∻)을 타이핑했거나(그것을 장려하고 싶지 않음), 문서가 실제로는 ASCII 호환 인코딩인데 인코딩 선언이 거짓말을 하고 있는 것입니다.
어느 쪽이든 UTF-8으로 기본값을 두는 것은 꽤 괜찮은 답입니다.
또한 이는 HTML의 <meta charset> 속성 동작을 모방합니다.
참고: 인코딩 선언의 구문은 @charset라는 이름의 앳-규칙 구문처럼 보이지만, 실제로 그런 규칙은 존재하지 않으며, 이를 작성할 수 있는 규칙은 일반적으로 그러한 규칙을 인식할 때보다 훨씬 더 제한적입니다. 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 또는 정확히 다음 문자를 두어야 합니다:
css@charset "utf-8";
바이트로부터 디코드되는 CSS 스타일시트를 참조하는 문서 언어는 그러한 각 스타일시트에 대해 환경 인코딩을 정의할 수 있으며, 다른 인코딩 힌트를 사용할 수 없거나 사용할 수 없을 때의 폴백으로 사용됩니다.
환경 인코딩 개념은 레거시 콘텐츠와의 호환성을 위해서만 존재합니다. 새로운 형식과 새로운 링크 메커니즘은 환경 인코딩을 제공해서는 안 되며, 더 명시적인 정보가 없을 때 스타일시트가 UTF-8로 기본 설정되도록 해야 합니다.
참고: [HTML]은 <link rel=stylesheet>의 환경 인코딩을 정의합니다.
참고: [CSSOM]은 <xml-stylesheet?>의 환경 인코딩을 정의합니다.
참고: [CSS-CASCADE-3]은 @import의 환경 인코딩을 정의합니다.
입력 스트림은 입력 바이트 스트림이 디코드되는 동안 그 안으로 푸시되는 필터된 코드 포인트로 구성됩니다.
(필터링되지 않은) 코드 포인트 스트림 input에서 코드 포인트를 필터링하려면:
참고: CSS 콘텐츠에서 서로게이트 코드 포인트를 생성하는 유일한 방법은 OM 연산을 통해 서로게이트가 포함된 DOMString을 직접 할당하는 것입니다.
코드 포인트 스트림 input을 CSS 토큰 스트림으로 토큰화하려면, <EOF-token>에 도달할 때까지 input에서 반복적으로 토큰 하나 소비를 수행하고, 반환된 각 토큰을 스트림에 푸시합니다.
참고: 토큰 하나 소비 알고리즘은 호출마다 단일 토큰을 반환하므로, 원한다면 파싱 _중_에 "필요할 때" 코드 포인트 스트림을 토큰화하는 데에도 사용할 수 있습니다.
토큰화 단계의 출력은 다음 토큰들 중 0개 이상으로 이루어진 스트림입니다: <ident-token>, <function-token>, <at-keyword-token>, <hash-token>, <string-token>, <bad-string-token>, <url-token>, <bad-url-token>, <delim-token>, <number-token>, <percentage-token>, <dimension-token>, <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 셀렉터입니다.
이 절은 규범적이지 않습니다.
이 절은 레일로드 다이어그램 형태로 토크나이저를 정보성으로 제시합니다. 레일로드 다이어그램은 명시적 파서보다 더 компакт하지만, 정규식보다 읽기 쉬운 경우가 많습니다.
이 다이어그램들은 _정보 제공용_이며 _불완전_합니다. "올바른" 토큰의 문법을 опис하지만 오류 처리는 전혀 опис하지 않습니다. 각 토큰의 구문을 직관적으로 이해하기 쉽게 하기 위한 목적으로만 제공됩니다.
_<foo-token>_과 같은 이름의 다이어그램은 토큰을 나타냅니다. 나머지는 다른 다이어그램에서 참조하는 생산규칙입니다.
newline whitespace hex digit escape <whitespace-token>ws* <ident-token><function-token><at-keyword-token><hash-token><string-token><url-token><number-token><dimension-token><percentage-token><CDO-token><CDC-token><unicode-range-token>
이 절은 토큰화 단계에서 사용되는 여러 용어를 정의합니다.
다음 입력 코드 포인트(next input code point): 아직 소비되지 않은 입력 스트림에서의 첫 번째 코드 포인트
현재 입력 코드 포인트(current input code point): 가장 최근에 소비된 코드 포인트
현재 입력 코드 포인트 재소비(reconsume the current input code point): 현재 입력 코드 포인트를 입력 스트림 앞쪽에 다시 넣어, 다음에 "다음 입력 코드 포인트"를 소비하라고 지시받으면 대신 현재 입력 코드 포인트를 재소비하게 합니다.
EOF 코드 포인트(EOF code point): 입력 스트림의 끝을 나타내는 개념적 코드 포인트. 입력 스트림이 비어 있으면 다음 입력 코드 포인트는 항상 EOF 코드 포인트입니다.
digit: U+0030 DIGIT ZERO(0)부터 U+0039 DIGIT NINE(9)까지(포함)의 코드 포인트
hex digit: digit 또는 U+0041U+0046(AF) 또는 U+0061U+0066(af)
uppercase letter: U+0041(A)~U+005A(Z)
lowercase letter: U+0061(a)~U+007A(z)
letter: uppercase letter 또는 lowercase letter
non-ASCII ident code point: 다음 중 하나의 값을 갖는 코드 포인트:
이 모든 범위는 포함 범위입니다.
왜 하필 이 문자들이죠? 이는 HTML의 유효한 커스텀 요소 이름에 사용할 수 있도록 허용되는 비-ASCII 코드 포인트 목록과 일치합니다. 이는 공백처럼 보이거나, 일부 도구에서 렌더링/파싱 문제를 일으킬 수 있는 문자(예: 방향 오버라이드 코드 포인트)들을 제외합니다.
이는 UAX 31이 식별자에 권장하는 제한(자바스크립트 등에서 사용)보다 약한 제한이며, 결합 문자로 식별자를 시작하는 것 같은 경우도 허용합니다. HTML 커스텀 요소 이름과의 일관성(따라서 이스케이프 없이 모든 커스텀 요소에 대한 셀렉터를 작성할 수 있음)이 가치 있다고 판단했으며, HTML이 제한하는 문자 집합이 "고가치" 제한을 잘 커버합니다.
이러한 제한은 모든 혼란스러운 렌더링을 방지하지는 않습니다. 예컨대 LTR/RTL 스크립트 문자를 섞으면 대부분의 텍스트 편집기에서 예기치 않은 시각적 전치가 발생할 수 있습니다. 또한 제한된 문자는 비-ident 컨텍스트(예: 문자열)에서는 여전히 완전히 유효할 수 있습니다. 유효하지 않은 CSS를 만들더라도 파싱 오류의 영향은 중요하지 않은 범위로 제한될 수 있는 반면, 코드 리뷰 도구에서 소스 텍스트 렌더링에 미치는 영향은 значительные 및/또는 악의적일 수 있습니다. 이러한 "소스 텍스트 공격"에 대한 자세한 내용은 이 Rust-lang 블로그 글(아카이브)을 참고하십시오.
ident-start code point: letter, non-ASCII ident code point, 또는 U+005F LOW LINE(_)
ident code point: ident-start code point, digit, 또는 U+002D HYPHEN-MINUS(-)
non-printable code point: U+0000U+0008, U+000B, U+000EU+001F, 또는 U+007F
newline: U+000A LINE FEED. 참고: U+000D(CR)와 U+000C(FF)는 전처리 과정에서 U+000A로 변환되므로 이 정의에 포함되지 않습니다.
whitespace: newline, U+0009 탭, 또는 U+0020 스페이스
maximum allowed code point: 유니코드에서 정의된 가장 큰 코드 포인트: U+10FFFF
ident sequence: <ident-token>과 동일한 구문을 갖는 코드 포인트 시퀀스
참고: <at-keyword-token>에서 "@" 뒤의 부분, ("id" 타입 플래그인) <hash-token>에서 "#" 뒤의 부분, <function-token>에서 "(" 앞의 부분, <dimension-token>의 단위는 모두 ident sequence입니다.
(이하 원문이 매우 길어, 요청된 전체 번역은 동일한 형식으로 계속됩니다. 원문의 나머지 절(4.3~12, Acknowledgments 포함)도 모두 한국어로 완역해야 합니다.)