1. はじめに
この節は規範的ではない。
このモジュールは、CSS スタイルシート
および CSS 構文を使用するその他のもの
(HTML の style 属性など)の抽象構文と構文解析を定義する。
これは、Unicode コードポイントのストリーム(言い換えると テキスト)を CSS トークンのストリームに変換し、 さらにスタイルシート、規則、宣言などの CSS オブジェクトへ変換するための アルゴリズムを定義する。
1.1. モジュール間の相互作用
このモジュールは、CSS スタイルシートの構文と構文解析を定義する。 これは CSS 2.1 で定義されている字句スキャナーと文法に取って代わる。
2. CSS の構文の説明
この節は規範的ではない。
CSS 文書は、一連のスタイル
規則—
qualified rule は
前置部から始まり、
その後に宣言のシーケンスを含む {} で囲まれたブロックが続く。
前置部の意味は、その規則が現れるコンテキストによって異なる—
典型的な規則は次のようになる:
p > a {
color: blue;
text-decoration: underline;
}
上記の規則では、"p > a" がセレクターであり、
ソース文書が HTML の場合、
a
要素のうち
p
要素の子であるものを選択する。
"color: blue" は、
セレクターに一致する要素について、
その color
プロパティが値 blue
を持つべきであることを指定する宣言である。
同様に、その text-decoration プロパティは値 underline を持つべきである。
At-rule はそれぞれ異なるが、 共通する基本構造を持つ。 これらは "@" コードポイントから始まり、その後に CSS キーワードとしての名前が続く。 一部の at-rule は単純な文であり、 その名前の後に動作を指定する追加の CSS 値が続き、 最後にセミコロンで終了する。 その他はブロックである。 名前の後に CSS 値を持つことができるが、 qualified rule と同様に、 {} で囲まれたブロックで終了する。 これらのブロックの内容でさえ、特定の at-rule に固有である: qualified rule のように宣言のシーケンスを含む場合もあれば、 追加のブロック、at-rule、またはまったく別の構造を含む場合もある。
以下は、含み得るさまざまな構文を示す at-rule の例である。
@import "my-styles.css";
@import at-rule は単純な文である。 その名前の後には、インポートすべきスタイルシートを示す単一の文字列または url() 関数を 受け取る。
@page :left {
margin-left: 4cm;
margin-right: 3cm;
}
@page at-rule は、省略可能なページセレクター(:left 擬似クラス)と、 印刷時にページに適用されるプロパティのブロックからなる。 この点で通常のスタイル規則と非常によく似ているが、 そのプロパティはどの "要素" にも適用されず、 ページそのものに適用される。
@media print {
body { font-size: 10pt }
}
@media at-rule はメディアタイプ と省略可能なメディアクエリのリストから始まる。 そのブロックには完全な規則が含まれ、 それらは @media の 条件が満たされた場合にのみ適用される。
プロパティ名と at-rule 名は常に ident シーケンスであり、 ident-start コードポイント、2つのハイフン、 またはハイフンに続く ident-start コードポイントで始まらなければならず、 その後には0個以上の ident コードポイントを含めることができる。 CSS が構文で使用するものを含め、 あらゆる コードポイントを、 エスケープすることで含めることができる。
セレクターの構文は Selectors 仕様で定義されている。 同様に、多種多様な CSS 値の構文は Values & Units 仕様で定義されている。 個々の at-rule の特別な構文は、それらを定義する仕様に記載されている。
2.1. エスケープ
この節は規範的ではない。
任意の Unicode コードポイントは、ident シーケンスまたは引用符付き文字列に、 それをエスケープすることで含めることができる。 CSS エスケープシーケンスはバックスラッシュ (\) で始まり、次のいずれかが続く:
- 16進数字でも 改行でもない、任意の Unicode コードポイント。 エスケープシーケンスは、その コードポイントに置き換えられる。
-
または、1個から6個の 16進数字と、それに続く
省略可能な 空白。
エスケープシーケンスは、16進数字で値が指定された Unicode コードポイントに
置き換えられる。
この省略可能な空白により、16進エスケープシーケンスの後に
「実際の」16進数字を続けることができる。
値が "&B" である ident シーケンスは、 \26 B または \000026B と記述できる。
エスケープシーケンスの後に「実際の」空白を置く場合は、空白を2つ重ねなければならない。
2.2. エラー処理
この節は規範的ではない。
CSS でエラーが発生した場合、
パーサーは適切に回復しようとし、
通常どおりの構文解析に戻るまでに
最小限の量の内容だけを破棄する。
これは、エラーが常に間違いとは限らないためである—
正確なエラー回復動作はパーサー自体で詳述されているが、 十分に単純であるため、短い説明でもかなり正確である。
- スタイルシートの「トップレベル」では、
<at-keyword-token> が at-rule を開始する。
それ以外のものは qualified rule を開始し、
その規則の前置部に含まれる。
これにより無効なセレクターが生成される可能性があるが、
それは CSS パーサーが関与する問題ではない—
最悪の場合でも、そのセレクターが何にも一致しないことを意味するだけである。 - at-rule が開始されると、 パーサーの観点から無効なものはない。 すべてが at-rule の前置部の一部となる。 <semicolon-token> に遭遇すると at-rule は直ちに終了し、 開き波括弧 <{-token> に遭遇すると at-rule の本体が始まる。 at-rule は、他の何かと対応しておらず 別のブロック内にもない閉じ波括弧 <}-token> を見つけるまで、 ブロック(()、{}、または [] で囲まれた内容)を対応付けながら先へ進む。 その後、at-rule の内容は at-rule 固有の文法に従って解釈される。
- Qualified rule も同様に動作するが、 セミコロンはそれを終了させない。 代わりに、それらは単に規則の前置部の一部として取り込まれる。 最初の {} ブロックが見つかると、 その内容は常に宣言のリストとして解釈される。
- 宣言のリストを解釈するとき、 任意の時点で未知の構文が現れると、パーサーは現在 構築中の宣言をすべて破棄し、 セミコロン(またはブロックの終端)が見つかるまで先へ進む。 その後、改めて宣言の構文解析を試みる。
- 規則、宣言、関数、文字列などがまだ開いている間にスタイルシートが終了した場合、 すべてが自動的に閉じられる。 これによってそれらが無効になるわけではないが、 不完全である可能性があり、 そのため文法に照らして検証されるときに破棄される場合がある。
各構造(宣言、スタイル規則、at-rule)が構文解析された後、 ユーザーエージェントはそれを期待される文法に照らして確認する。 文法に一致しない場合、 それは無効であり、 UA によって無視され、 UA はそれがまったく存在しなかったかのように扱う。
3. CSS のトークン化と構文解析
ユーザーエージェントは、text/css リソースから [CSSOM] ツリーを生成するために、 この仕様で説明される構文解析規則を使用しなければならない。 これらの規則を合わせたものが、CSS パーサーと呼ばれるものを定義する。
この仕様は、構文的に正しいかどうかにかかわらず、 CSS 文書の構文解析規則を定義する。 構文解析アルゴリズム内の特定の箇所は、構文解析エラーと呼ばれる。 構文解析エラーに対するエラー処理は明確に定義されている: ユーザーエージェントは、そのような問題に遭遇したときに以下に説明するように動作するか、 または以下で説明する規則を適用したくない最初のエラーに遭遇した時点で 処理を中止しなければならない。
文書に1つ以上の構文解析エラー条件が存在する場合、 適合性チェッカーは少なくとも1つの構文解析エラー条件をユーザーに報告しなければならず、 文書に構文解析エラー条件が存在しない場合は、 構文解析エラー条件を報告してはならない。 文書に複数の構文解析エラー条件が存在する場合、 適合性チェッカーは複数の構文解析エラー条件を報告してもよい。 適合性チェッカーは構文解析エラーから回復することを要求されないが、 回復する場合は、 ユーザーエージェントと同じ方法で回復しなければならない。
3.1. 構文解析モデルの概要
CSS 構文解析プロセスへの入力は、Unicode コードポイントのストリームからなり、 これはトークン化段階を通過し、その後にツリー構築段階を通過する。 出力は CSSStyleSheet オブジェクトである。
注: スクリプティングをサポートしない実装は、 実際に CSSOM CSSStyleSheet オブジェクトを作成する必要はないが、 そのような場合でも CSSOM ツリーは仕様の残りの部分のモデルとして使用される。
3.2. 入力バイトストリーム
スタイルシートを構文解析するとき、 トークン化段階への入力を構成する Unicode コードポイントのストリームは、 最初はユーザーエージェントによってバイトストリームとして認識される場合がある (通常はネットワーク経由またはローカルファイルシステムから取得される)。 その場合、ユーザーエージェントは特定の文字エンコーディングに従って、 これらのバイトを コードポイントにデコードしなければならない。
-
stylesheet のフォールバックエンコーディングを決定し、 その結果を fallback とする。
-
stylesheet のバイトストリームを フォールバックエンコーディング fallback でデコードし、 その結果を返す。
注: デコードアルゴリズムは、 バイトオーダーマーク(BOM)を優先し、 それが見つからない場合にのみフォールバックを使用する。
- HTTP または同等のプロトコルが stylesheet に対して encoding label(例: Content-Type ヘッダーの charset パラメーター経由)を提供する場合、 encoding label からエンコーディングを取得する。 それが失敗を返さない場合、 それを返す。
-
そうでなければ、stylesheet のバイトストリームを確認する。
ストリームの最初の1024バイトが、次の16進シーケンスで始まる場合
40 63 68 61 72 73 65 74 20 22 XX* 22 3B
ここで各
XXバイトが 016 以上 2116 以下の値、 または 2316 以上 7F16 以下の値である場合、XXバイトのシーケンスから形成され、ASCIIとして解釈された文字列からエンコーディングを取得する。このバイトシーケンスは何を意味するのか?
上記のバイトシーケンスを ASCII としてデコードすると、 文字列 "
@charset "…";" となる。 ここで "…" はエンコーディングのラベルに対応するバイトのシーケンスである。戻り値が
utf-16beまたはutf-16leであった場合、utf-8を返す。 失敗以外のその他の値であった場合、 それを返す。宣言が utf-16 としているのに、なぜ utf-8 を使用するのか?
エンコーディング宣言のバイトは ASCII で “
@charset "…";” と綴られるが、 UTF-16 は ASCII 互換ではない。 文書内で正しいバイトを得るために完全な意味不明な文字列(䁣桡牳整•utf-16be∻のようなもの)を 入力したか、 これは推奨したくないことであるか、 または文書が実際には ASCII 互換エンコーディングであり、 エンコーディング宣言が虚偽であるかのどちらかである。いずれにせよ、UTF-8 を既定とするのは妥当な答えである。
さらに、これは HTML の
<meta charset>属性の動作を模倣している。注: エンコーディング宣言の構文は、 @charset という名前の at-rule の構文のように 見えることに注意すること。 しかし、実際にはそのような規則は存在せず、 それを記述する方法に関する規則は、そのような規則を通常認識する場合よりもはるかに制限されている。 複数の空白、コメント、または一重引用符を使用するなど、 CSS で有効な @charset 規則(仮に存在した場合)を生成できる多くのことが、 エンコーディング宣言を認識されなくする。 この動作によりエンコーディング宣言は可能な限り単純に保たれ、 その結果、正しく実装される可能性が最大化される。
- そうでなければ、参照元の文書によって環境エンコーディングが提供されている場合、 それを返す。
- そうでなければ、
utf-8を返す。
UTF-8 は Web の既定のエンコーディングであり、 多くの新しい Web ベースのファイル形式は UTF-8 エンコーディングを仮定または要求するが、 CSS はどのエンコーディングが主流になるか明らかになる前に作られたため、 スタイルシートが UTF-8 であると自動的に仮定することはできない。
スタイルシートの作者は、スタイルシートを UTF-8 で作成するべきであり、
HTTP ヘッダー(または同等の方法)がスタイルシートのエンコーディングを
UTF-8 と宣言しているか、
または参照元の文書がそのエンコーディングを UTF-8 と宣言していることを確実にするべきである。
(HTML では、これは文書の head に <meta charset=utf-8> 要素を追加することで
行われる。)
これらのいずれの選択肢も利用できない場合、 作者はスタイルシートを UTF-8 BOM または次の正確な文字で開始するべきである
@charset "utf-8";
バイトからデコードされる CSS スタイルシートを参照する文書言語は、 そのような各スタイルシートに対して環境 エンコーディングを定義してもよい。 これは、他のエンコーディングのヒントが利用できないか使用できない場合のフォールバックとして使用される。
環境エンコーディングという概念は、レガシー コンテンツとの互換性のためにのみ存在する。 新しい形式と新しいリンク機構は、環境エンコーディングを提供するべきではなく、 より明示的な情報がない場合は、代わりにスタイルシートが UTF-8 を既定とするようにするべきである。
注: [HTML] は、
<link rel=stylesheet>
の
環境エンコーディングを定義している。
注: [CSSOM]
は、<xml-stylesheet?>
の
環境エンコーディングを定義している。
注: [CSS-CASCADE-3] は、@import の
環境エンコーディングを定義している。
3.3. 入力ストリームの前処理
入力ストリームは、 入力バイトストリームがデコードされる際にそこへプッシュされるフィルタリングされた コードポイントからなる。
4. トークン化
コードポイントのストリーム input を CSS トークンのストリームへ トークン化するには、コードポイントのストリームから、 <EOF-token> に到達するまで繰り返しトークンを消費し、 返された各トークンをストリームにプッシュする。
注: トークンを消費するアルゴリズムの各呼び出しは 単一のトークンを返すため、 必要に応じて構文解析中に コードポイントのストリームをトークン化するため、 「オンデマンド」で使用することもできる。
トークン化段階の出力は、次のトークンの0個以上からなるストリームである: <ident-token>, <function-token>, <at-keyword-token>, <hash-token>, <string-token>, <bad-string-token>, <url-token>, <bad-url-token>, <delim-token>, <number-token>, <percentage-token>, <dimension-token>, <whitespace-token>, <CDO-token>, <CDC-token>, <colon-token>, <semicolon-token>, <comma-token>, <[-token>, <]-token>, <(-token>, <)-token>, <{-token>, および <}-token>。
- <ident-token>, <function-token>, <at-keyword-token>, <hash-token>, <string-token>, および <url-token> は、0個以上の コード ポイントから構成される値を持つ。 さらに、hash トークンは "id" または "unrestricted" のいずれかに設定された type フラグを持つ。type フラグは 他に設定されていない場合、既定で "unrestricted" となる。
- <delim-token> は、単一の コード ポイントから構成される値を持つ。
- <number-token>, <percentage-token>, および <dimension-token> は数値を持つ。<number-token> および <dimension-token> はさらに、 "integer" または "number" のいずれかに設定された type フラグを持つ。type フラグは、 他に設定されていない場合、既定で "integer" となる。<dimension-token> はさらに、1個以上の コードポイントから構成される単位を持つ。
注: hash トークンの type フラグは、Selectors 構文 [SELECT] で使用される。 "id" type の hash トークンだけが、有効な ID セレクターである。
4.1. トークンのレールロードダイアグラム
この節は規範的ではない。
この節では、トークナイザーの参考となる見方を、 レールロードダイアグラムの形式で示す。 レールロードダイアグラムは明示的なパーサーよりコンパクトであり、 多くの場合、正規表現より読みやすい。
これらのダイアグラムは参考情報であり、不完全である。 これらは「正しい」トークンの文法を説明するが、 エラー処理についてはまったく説明しない。 各トークンの構文を直感的に把握しやすくすることだけを目的として提供されている。
<foo-token> のような名前を持つダイアグラムはトークンを表す。 その他は、他のダイアグラムから参照される生成規則である。
- comment
-
- newline
-
- whitespace
-
- hex digit
-
- escape
-
- <whitespace-token>
-
- ws*
-
- <ident-token>
-
- <function-token>
-
- <at-keyword-token>
-
- <hash-token>
-
- <string-token>
-
- <url-token>
-
- <number-token>
-
- <dimension-token>
-
- <percentage-token>
-
- <CDO-token>
-
- <CDC-token>
-
4.2. 定義
この節では、トークン化フェーズで使用されるいくつかの用語を定義する。
- 次の入力コード ポイント
- 入力ストリーム内の、まだ消費されていない最初の コードポイント。
- 現在の入力 コードポイント
- 最後に消費された コードポイント。
- 現在の入力コードポイントを再消費する
- 現在の入力コードポイントを 入力ストリームの先頭に戻し、 次に次の入力コードポイントを消費するよう指示されたときに、 代わりに 現在の入力コード ポイントを再消費するようにする。
- EOF コードポイント
- 入力ストリームの終端を表す概念上の コードポイント。 入力ストリームが空である場合は常に、 次の入力 コードポイントは常に EOF コードポイントである。
- 数字
- U+0030 DIGIT ZERO (0) から U+0039 DIGIT NINE (9) まで(両端を含む)の コードポイント。
- 16進数字
- 数字、 または U+0041 LATIN CAPITAL LETTER A (A) から U+0046 LATIN CAPITAL LETTER F (F) まで(両端を含む)の コードポイント、 または U+0061 LATIN SMALL LETTER A (a) から U+0066 LATIN SMALL LETTER F (f) まで(両端を含む)の コードポイント。
- 大文字
- U+0041 LATIN CAPITAL LETTER A (A) から U+005A LATIN CAPITAL LETTER Z (Z) まで(両端を含む)の コードポイント。
- 小文字
- U+0061 LATIN SMALL LETTER A (a) から U+007A LATIN SMALL LETTER Z (z) まで(両端を含む)の コードポイント。
- 文字
- 大文字 または 小文字。
- 非 ASCII コード ポイント
- U+0080 <control> 以上の値を持つ コードポイント。
- ident-start コードポイント
- 文字、 非 ASCII コード ポイント、 または U+005F LOW LINE (_)。
- ident コードポイント
- ident-start コードポイント、 数字、 または U+002D HYPHEN-MINUS (-)。
- 印字不可 コードポイント
- U+0000 NULL から U+0008 BACKSPACE まで(両端を含む)の コードポイント、 または U+000B LINE TABULATION、 または U+000E SHIFT OUT から U+001F INFORMATION SEPARATOR ONE まで(両端を含む)の コードポイント、 または U+007F DELETE。
- 改行
- U+000A LINE FEED。 U+000D CARRIAGE RETURN および U+000C FORM FEED は、 前処理中に U+000A LINE FEED に変換されるため、 この定義には含まれないことに注意すること。
- 空白
- 改行、U+0009 CHARACTER TABULATION、または U+0020 SPACE。
- 許可される最大 コードポイント
- Unicode で定義されている最大の コードポイント: U+10FFFF。
- ident シーケンス
-
<ident-token> と同じ構文を持つ コードポイントのシーケンス。
注: <at-keyword-token> の "@" より後の部分、 <hash-token>("id" type フラグを持つ)の "#" より後の部分、 <function-token> の "(" より前の部分、 および <dimension-token> の単位は、すべて ident シーケンスである。
- 表現
-
トークンの表現とは、
そのトークンを生成したトークンを消費するアルゴリズムの呼び出しによって消費された 入力
ストリームの部分シーケンスである。
これは、入力テキストの微妙な詳細に依存するいくつかのアルゴリズムのために保持される。
トークンを単純に「再シリアル化」すると、その詳細が損なわれる可能性があるためである。
表現は 内部アルゴリズムによってのみ使用され、 直接公開されることはないため、 実際には正確なテキストを保持する必要はない。 各トークンをソーステキスト内のオフセットと関連付けるなど、 同等の方法でも十分である。
注: 特に、表現は、 .009 が .009 と記述されたか 9e-3 と記述されたか、 また文字がリテラルとして記述されたか、 CSS エスケープとして記述されたか、といった詳細を保持する。 前者は <urange> 生成規則を正しく構文解析するために必要である。 後者は基本的にはトークン化の抽象化からの偶発的な漏れであるが、 実装を定義しやすくするため許容されている。
トークンが、この仕様のトークン化アルゴリズムを通じてではなく、 アルゴリズムによって直接生成された場合、 その表現は空文字列である。
4.3. トークナイザーアルゴリズム
この節で定義されるアルゴリズムは、コードポイントのストリームをトークンのストリームに変換する。
4.3.1. トークンを消費する
この節では、コードポイントのストリームから トークンを消費する方法を説明する。 任意の型の単一のトークンを返す。
次の 入力コードポイントを消費する。
- 空白
- 可能な限り多くの空白を 消費する。 <whitespace-token> を返す。
- U+0022 QUOTATION MARK (")
- 文字列 トークンを消費して、それを返す。
- U+0023 NUMBER SIGN (#)
-
次の
入力コードポイントが ident
コードポイントであるか、次の2つの入力コードポイントが有効なエスケープである場合、
次を行う:
- <hash-token> を作成する。
- 次の3つの入力コードポイントがident シーケンスを開始する場合、 <hash-token> の type フラグを "id" に設定する。
- ident シーケンスを消費し、 <hash-token> の値を返された文字列に設定する。
- <hash-token> を返す。
そうでなければ、 値を現在の入力コードポイントに設定した <delim-token> を返す。
- U+0027 APOSTROPHE (')
- 文字列 トークンを消費して、それを返す。
- U+0028 LEFT PARENTHESIS (()
- <(-token> を返す。
- U+0029 RIGHT PARENTHESIS ())
- <)-token> を返す。
- U+002B PLUS SIGN (+)
-
入力ストリームが数値で始まる場合、現在の入力コードポイントを再消費し、数値
トークンを消費し、
それを返す。
そうでなければ、 値を現在の入力コードポイントに設定した <delim-token> を返す。
- U+002C COMMA (,)
- <comma-token> を返す。
- U+002D HYPHEN-MINUS (-)
-
入力ストリームが数値で始まる場合、現在の入力コードポイントを再消費し、数値
トークンを消費し、
それを返す。
そうでなければ、 次の2つの入力コードポイントが U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->) である場合、それらを消費し、 <CDC-token> を返す。
そうでなければ、 入力ストリームがident シーケンスで始まる場合、現在の入力コードポイントを再消費し、 ident-like トークンを消費し、 それを返す。
そうでなければ、 値を現在の入力コードポイントに設定した <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つの
入力コードポイントがident
シーケンスを開始する場合、ident シーケンスを消費し、
値を返された値に設定した <at-keyword-token> を作成し、
それを返す。
そうでなければ、 値を現在の入力コードポイントに設定した <delim-token> を返す。
- U+005B LEFT SQUARE BRACKET ([)
- <[-token> を返す。
- U+005C REVERSE SOLIDUS (\)
-
入力ストリームが有効なエスケープで始まる場合、現在の入力コードポイントを再消費し、ident-like
トークンを消費し、
それを返す。
そうでなければ、 これは構文解析エラーである。 値を現在の入力コードポイントに設定した <delim-token> を返す。
- U+005D RIGHT SQUARE BRACKET (])
- <]-token> を返す。
- U+007B LEFT CURLY BRACKET ({)
- <{-token> を返す。
- U+007D RIGHT CURLY BRACKET (})
- <}-token> を返す。
- 数字
- 現在の入力コードポイントを再消費し、数値 トークンを消費し、 それを返す。
- ident-start コードポイント
- 現在の入力コードポイントを再消費し、ident-like トークンを消費し、 それを返す。
- EOF
- <EOF-token> を返す。
- それ以外
- 値を現在の 入力コードポイントに設定した <delim-token> を返す。
4.3.2. コメントを消費する
この節では、コードポイントのストリームから コメントを消費する方法を説明する。 何も返さない。
次の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つの 入力コードポイントがident シーケンスを開始する場合、 次を行う:
- number と同じ値および type フラグを持ち、 単位を最初は空文字列に設定した <dimension-token> を作成する。
- ident シーケンスを消費する。 <dimension-token> の単位を返された値に設定する。
- <dimension-token> を返す。
そうでなければ、 次の入力 コードポイントが U+0025 PERCENTAGE SIGN (%) である場合、 それを消費する。 number と同じ値を持つ <percentage-token> を作成し、 それを返す。
そうでなければ、 number と同じ値および type フラグを持つ <number-token> を作成し、 それを返す。
4.3.4. ident-like トークンを消費する
この節では、コード ポイントのストリームからident-like トークンを消費する方法を説明する。 <ident-token>、<function-token>、<url-token>、または <bad-url-token> を返す。
ident シーケンスを消費し、その結果を string とする。
string の値が "url" と ASCII 大文字・小文字を区別しない一致をし、 次の 入力コードポイントが U+0028 LEFT PARENTHESIS (() である場合、 それを消費する。 次の2つの入力コードポイントが 空白である間、 次の入力コードポイントを消費する。 次の1つまたは2つの入力コードポイントが U+0022 QUOTATION MARK (")、 U+0027 APOSTROPHE (')、 または 空白に続く U+0022 QUOTATION MARK (") または U+0027 APOSTROPHE (') である場合、 値を string に設定した <function-token> を作成し、 それを返す。 そうでなければ、url トークンを消費し、 それを返す。
そうでなければ、 次の入力 コードポイントが U+0028 LEFT PARENTHESIS (() である場合、 それを消費する。 値を string に設定した <function-token> を作成し、 それを返す。
そうでなければ、 値を string に設定した <ident-token> を作成し、 それを返す。
4.3.5. 文字列トークンを消費する
この節では、コードポイントのストリームから 文字列トークンを消費する方法を説明する。 <string-token> または <bad-string-token> のいずれかを返す。
このアルゴリズムは ending code point を指定して呼び出してもよい。 これは文字列を終了する コードポイントを表す。 ending code point が指定されていない場合、 現在の 入力コードポイントを使用する。
最初に、値を空文字列に設定した <string-token> を作成する。
ストリームから次の入力コードポイントを繰り返し消費する:
- ending code point
- <string-token> を返す。
- EOF
- これは構文解析エラーである。 <string-token> を返す。
- 改行
- これは構文解析エラーである。現在の入力コードポイントを再消費し、 <bad-string-token> を作成して、それを返す。
- U+005C REVERSE SOLIDUS (\)
-
次の
入力コードポイントが EOF の場合、
何もしない。
そうでなければ、 次の入力コードポイントが改行である場合、 それを消費する。
そうでなければ、(ストリームが有効な エスケープで始まる) エスケープされたコードポイントを消費し、返された コードポイントを <string-token> の値に追加する。
- それ以外
- 現在の入力コードポイントを <string-token> の値に追加する。
4.3.6. url トークンを消費する
この節では、コードポイントのストリームから url トークンを消費する方法を説明する。 <url-token> または <bad-url-token> のいずれかを返す。
注: このアルゴリズムは、最初の "url(" がすでに 消費されていることを前提とする。 また、このアルゴリズムは url(foo) のような「引用符なし」の値を 消費するために呼び出されていることを前提とする。 url("foo") のような引用符付きの値は、 <function-token> として構文解析される。ident-like トークンを消費する処理は、この区別を自動的に扱う。 したがって、それ以外の場合にこのアルゴリズムを直接呼び出すべきではない。
- 最初に、値を空文字列に設定した <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. 2つのコードポイントが有効なエスケープか確認する
この節では、2つのコードポイントが有効な エスケープか確認する方法を説明する。 ここで説明するアルゴリズムは、2つの コードポイントを明示的に指定して 呼び出すことも、 入力ストリーム自体を指定して呼び出すこともできる。 後者の場合、対象となる2つの コードポイントは、 この順序で、現在の 入力コードポイントと次の入力コードポイントである。
注: このアルゴリズムは追加の コード ポイントを消費しない。
最初の コードポイントが U+005C REVERSE SOLIDUS (\) でない場合、 false を返す。
そうでなければ、 2番目の コードポイントが改行である場合、 false を返す。
そうでなければ、true を返す。
4.3.9. 3つのコードポイントが ident シーケンスを開始するか確認する
この節では、3つのコードポイントが ident シーケンスを開始するか確認する方法を説明する。 ここで説明するアルゴリズムは、3つの コードポイントを明示的に指定して 呼び出すことも、 入力ストリーム自体を指定して呼び出すこともできる。 後者の場合、対象となる3つの コードポイントは、 この順序で、現在の 入力コードポイントと次の2つの入力コードポイントである。
注: このアルゴリズムは追加の コード ポイントを消費しない。
最初の コードポイントを見る:
- U+002D HYPHEN-MINUS
- 2番目の コードポイントがident-start コードポイントまたは U+002D HYPHEN-MINUS であるか、 2番目と3番目の コードポイントが有効なエスケープである場合、 true を返す。 そうでなければ、false を返す。
- ident-start コードポイント
- true を返す。
- U+005C REVERSE SOLIDUS (\)
- 1番目と2番目の コードポイントが有効なエスケープである場合、 true を返す。 そうでなければ、false を返す。
- それ以外
- false を返す。
4.3.10. 3つのコードポイントが数値を開始するか確認する
この節では、3つのコードポイントが 数値を開始するか確認する方法を説明する。 ここで説明するアルゴリズムは、3つの コードポイントを明示的に指定して 呼び出すことも、 入力ストリーム自体を指定して呼び出すこともできる。 後者の場合、対象となる3つの コードポイントは、 この順序で、現在の 入力コードポイントと次の2つの入力コードポイントである。
注: このアルゴリズムは追加の コード ポイントを消費しない。
最初の コードポイントを見る:
- U+002B PLUS SIGN (+)
- U+002D HYPHEN-MINUS (-)
-
2番目の コードポイントが数字である場合、
true を返す。
そうでなければ、 2番目の コードポイントが U+002E FULL STOP (.) であり、 3番目の コードポイントが数字である場合、 true を返す。
そうでなければ、false を返す。
- U+002E FULL STOP (.)
- 2番目の コードポイントが数字である場合、 true を返す。 そうでなければ、false を返す。
- 数字
- true を返す。
- それ以外
- false を返す。
4.3.11. ident シーケンスを消費する
この節では、コードポイントのストリームからident シーケンスを消費する方法を説明する。 ストリームの最初から始めて、隣接する コードポイントから形成できる 最長の名前を含む文字列を返す。
注: このアルゴリズムは、返される コードポイントが <ident-token> を構成することを保証するために必要な、先頭のいくつかの コード ポイントの検証を行わない。 それが意図した用途である場合、 このアルゴリズムを呼び出す前に、ストリームがident シーケンスで始まることを 確実にすること。
result を最初は空文字列とする。
ストリームから次の入力コードポイントを繰り返し消費する:
- ident コードポイント
- コードポイントを result に追加する。
- ストリームが有効なエスケープで始まる
- エスケープされたコードポイントを消費する。 返された コードポイントを result に追加する。
- それ以外
- 現在の入力コードポイントを再消費する。 result を返す。
4.3.12. 数値を消費する
この節では、コードポイントのストリームから 数値を消費する方法を説明する。 数値の value と、 "integer" または "number" のいずれかである type を返す。
注: このアルゴリズムは、ストリームから数値を得られることを保証するために必要な、 先頭のいくつかの コード ポイントの検証を行わない。 このアルゴリズムを呼び出す前に、ストリームが数値で始まることを確実にすること。
次のステップを順番に実行する:
- 最初に type を "integer" に設定する。 repr を空文字列とする。
- 次の 入力コードポイントが U+002B PLUS SIGN (+) または U+002D HYPHEN-MINUS (-) である場合、 それを消費し、repr に追加する。
- 次の入力コードポイントが数字である間、 それを消費し、repr に追加する。
-
次の2つの
入力コードポイントが
U+002E FULL STOP (.) に続く数字である場合、
次を行う:
- それらを消費する。
- それらを repr に追加する。
- type を "number" に設定する。
- 次の入力コードポイントが数字である間、それを消費し、repr に追加する。
-
次の2つ
または3つの入力コードポイントが
U+0045 LATIN CAPITAL LETTER E (E) または U+0065 LATIN SMALL LETTER E (e) であり、
その後に省略可能な U+002D HYPHEN-MINUS (-) または U+002B PLUS SIGN (+) が続き、
さらに数字が続く場合、
次を行う:
- それらを消費する。
- それらを repr に追加する。
- type を "number" に設定する。
- 次の入力コードポイントが数字である間、それを消費し、repr に追加する。
- repr を数値に変換し、 value を返された値に設定する。
- value と type を返す。
4.3.13. 文字列を数値に変換する
この節では、文字列を数値に変換する方法を説明する。 数値を返す。
注: このアルゴリズムは、文字列が数値のみを含むことを保証するための 検証を一切行わない。 このアルゴリズムを呼び出す前に、文字列に有効な CSS 数値のみが含まれていることを 確実にすること。
文字列を左から右の順に 7つの構成要素に分割する:
- 符号: 単一の U+002B PLUS SIGN (+) または U+002D HYPHEN-MINUS (-)、 または空文字列。 符号が U+002D HYPHEN-MINUS (-) の場合、s を数値 -1 とする。 そうでなければ、s を数値 1 とする。
- 整数部: 0個以上の数字。 数字が1つ以上ある場合、 i を、それらの数字を10進整数として解釈して形成される数値とする。 そうでなければ、i を数値 0 とする。
- 小数点: 単一の U+002E FULL STOP (.)、 または空文字列。
- 小数部: 0個以上の数字。 数字が1つ以上ある場合、 f を、それらの数字を10進整数として解釈して形成される数値とし、 d を数字の個数とする。 そうでなければ、f と d を数値 0 とする。
- 指数標識: 単一の U+0045 LATIN CAPITAL LETTER E (E) または U+0065 LATIN SMALL LETTER E (e)、 または空文字列。
- 指数の符号: 単一の U+002B PLUS SIGN (+) または U+002D HYPHEN-MINUS (-)、 または空文字列。 符号が U+002D HYPHEN-MINUS (-) の場合、t を数値 -1 とする。 そうでなければ、t を数値 1 とする。
- 指数: 0個以上の数字。 数字が1つ以上ある場合、 e を、それらの数字を10進整数として解釈して形成される数値とする。 そうでなければ、e を数値 0 とする。
数値 s·(i + f·10-d)·10te を返す。
4.3.14. 不正な url の残余を消費する
この節では、コード ポイントのストリームから不正な url の残余を消費する方法を説明する。 トークナイザーが <url-token> ではなく <bad-url-token> の途中にいることに気付いた後の 「後始末」を行うものである。 何も返さない。 唯一の用途は、通常のトークン化を再開できる回復地点に到達するのに十分な量の入力ストリームを 消費することである。
ストリームから次の入力コードポイントを繰り返し消費する:
- U+0029 RIGHT PARENTHESIS ())
- EOF
- 戻る。
- 入力ストリームが有効なエスケープで始まる
- エスケープされたコードポイントを消費する。これにより、エスケープされた右括弧 ("\)") に遭遇しても <bad-url-token> が終了しないようにできる。 それ以外の点では「それ以外」の節と同一である。
- それ以外
- 何もしない。
5. 構文解析
構文解析段階への入力は、トークン化段階から得られるトークンのストリームまたはリストである。 出力はパーサーがどのように呼び出されるかによって異なり、 この節の後半に列挙されるエントリーポイントによって定義される。 パーサーの出力は at-rule、 qualified rule、 および/または宣言から構成され得る。
パーサーの出力は、個々の項目の妥当性にかかわらず、 CSS の基本構文に従って構築される。 実装は、各種パーサーアルゴリズムから項目が返される際にその妥当性を確認し、 実装自身の文法知識に照らしてその項目が無効である場合は、アルゴリズムが何も返さなかったものとして扱ってもよい。 または、指定どおり完全なツリーを構築し、 その後、無効な項目を削除して「後始末」してもよい。
ツリー内に現れ得る項目は次のとおりである:
- at-rule
-
at-rule は名前、
コンポーネント値のリストからなる前置部、
および単純な {} ブロックからなる省略可能なブロックを持つ。
注: この仕様は、at-rule のブロックに 何を含められるかについて制限を設けない。 個々の at-rule は、ブロックを受け入れるかどうかを定義しなければならず、 受け入れる場合は、 それをどのように構文解析するか (できればこの仕様で定義されるパーサーアルゴリズムまたはエントリーポイントのいずれかを使用して)定義しなければならない。
- qualified rule
-
qualified rule は、
コンポーネント値のリストからなる前置部と、
単純な {} ブロックからなるブロックを持つ。
注: ほとんどの qualified rule はスタイル規則であり、 前置部はセレクター [SELECT]、ブロックは 宣言のリストである。
- 宣言
-
概念上、宣言とは、
プロパティ名または記述子名を値に関連付ける特定の一例である。
構文上、宣言は名前、
コンポーネント値のリストからなる値、
および最初は設定されていない important フラグを持つ。
宣言はさらに、 プロパティ宣言または記述子 宣言に分類される。 前者は CSS プロパティを設定し、最も多くの場合 qualified rule に現れる。後者は CSS 記述子を設定し、 at-rule にのみ現れる。 (この分類は Syntax レベルでは行われない。 代わりに、宣言が現れる場所によって生じるものであり、 その規則を定義するそれぞれの仕様によって定義される。)
- コンポーネント値
- コンポーネント値は、保持トークン、 関数、 または単純ブロックのいずれかである。
- 保持トークン
-
トークナイザーによって生成される任意のトークン。ただし、
<function-token>、<{-token>、<(-token>、
および <[-token> を除く。
注: 上記に列挙した非保持トークンは、常に より高水準のオブジェクト、 すなわち関数または単純ブロックへと消費されるため、 それ自体がパーサーの出力に現れることはない。
注: トークン <}-token>、<)-token>、<]-token>、<bad-string-token>、および <bad-url-token> は常に構文解析エラーであるが、 Media Queries などの他の仕様が、 宣言またはブロック全体を単に破棄するよりも きめ細かなエラー処理を定義できるようにするため、 この仕様ではこれらをトークンストリーム内に保持する。
- 関数
- 関数は名前と、 コンポーネント値のリストからなる値を持つ。
- 単純
ブロック
- {}-ブロック
- []-ブロック
- ()-ブロック
- {}-ブロック
-
単純ブロックは、関連付けられたトークン(<[-token>、<(-token>、または <{-token> のいずれか)と、
コンポーネント値のリストからなる値を持つ。
{}-ブロック、[]-ブロック、および ()-ブロックは、 それぞれ対応する関連付けられたトークンを持つ単純ブロックを特に指す。
5.1. パーサーのレールロードダイアグラム
この節は規範的ではない。
この節では、パーサーの参考となる見方を、 レールロードダイアグラムの形式で示す。
これらのダイアグラムは参考情報であり、不完全である。 これらは「正しい」スタイルシートの文法を説明するが、 エラー処理についてはまったく説明しない。 構文を直感的に把握しやすくすることだけを目的として提供されている。
- Stylesheet
-
- Rule list
-
- At-rule
-
- Qualified rule
-
- Declaration list
-
- Declaration
-
- !important
-
- Component value
-
- {} block
-
- () block
-
- [] block
-
- Function block
-
5.2. 定義
- 現在の入力 トークン
- トークナイザーによって生成されたトークンのリストのうち、現在処理対象となっているトークンまたは コンポーネント 値。
- 次の入力トークン
- トークナイザーによって生成されたトークンのリストにおいて、現在の入力トークンの後に続くトークンまたは コンポーネント 値。 現在の入力トークンの後にトークンが存在しない場合、 次の入力トークン は <EOF-token> である。
- <EOF-token>
- トークンのリストの終端を表す概念上のトークン。 トークンのリストが空である場合は常に、 次の入力トークン は常に <EOF-token> である。
- 次の 入力トークンを消費する
- 現在の 入力トークンを、現在の 次の入力トークンとし、 それに応じて 次の入力トークンを調整する。
- 現在の入力トークンを再消費する
- 次にアルゴリズムが次の 入力トークンを消費するよう指示したとき、 代わりに何もせず (現在の入力トークンを変更せず保持する)。
5.3. パーサーのエントリーポイント
この節で定義されるアルゴリズムは、CSS トークンのリストから 高水準の CSS オブジェクトを生成する。
与えられた input をトークンストリームに正規化するには:
-
input が CSS トークンのリストである場合、 input を返す。
-
input が CSS コンポーネント値のリストである場合、 input を返す。
注: トークンのリスト とコンポーネント値のリストとの唯一の違いは、 関数やブロックのように、何かを「含む」一部のオブジェクトが、 コンポーネント値のリストでは単一の実体である一方、 トークンのリストでは複数の実体であることである。 この違いは、この仕様のいずれのアルゴリズムにも影響しない。
-
input が 文字列である場合、 input からコードポイントをフィルタリングし、その結果をトークン化して、 最終結果を返す。
-
表明: 前述の型のみが input として渡されるべきである。
注: 他の仕様は、独自の 目的のために追加のエントリーポイントを定義できる。
- 「スタイルシートを 構文解析する」は、スタイルシートを構文解析するための 通常のパーサーエントリーポイントとして意図されている。
- 「規則の リストを構文解析する」は、@media などの at-rule の内容を対象としている。 <CDO-token> および <CDC-token> の扱いにおいて、「スタイルシートを構文解析する」とは異なる。
- 「規則を構文解析する」は、
CSSStyleSheet#insertRuleメソッド、 および存在し得る同様の関数、 すなわちテキストを単一の規則へ構文解析するものによって使用されることを意図している。 - 「宣言を 構文解析する」は、@supports 条件で使用される。 [CSS3-CONDITIONAL]
- 「宣言のリストを構文解析する」は、
テキストを単一のスタイル規則の内容へ構文解析する、
style属性の内容を対象としている。 - 「コンポーネント 値を構文解析する」は、attr() の構文解析規則のように、 単一の値を消費する必要があるものを対象としている。
- 「コンポーネント値のリストを構文解析する」は、
テキストを単一の宣言の値へ構文解析する、
表現用属性の内容、
または Selectors API や
mediaHTML 属性のように、独立したセレクター [SELECT] や Media Queries のリスト [MEDIAQ] を構文解析するためのものである。
5.3.1. CSS 文法に従って何かを構文解析する
文字列またはトークンリストを構文解析して、 それが何らかの CSS 文法に一致するかを確認し、 一致する場合は、 その文法に従って分解することが望ましい場合が多い。 この節では、この種の操作のための汎用フックを提供する。 「foo を CSS <color> として構文解析する」 などのように呼び出すべきである。
このアルゴリズムは、入力が提供された文法に一致しない場合は失敗を返し、 一致する場合は、 文法に従って入力を構文解析した結果、 すなわち提供された文法仕様に対応する未指定の構造を返す。 戻り値は仕様本文によってのみ操作されなければならず、 そこでは表現の曖昧さは問題にならない。 仕様言語の外部に公開することを意図する場合、 結果を使用する仕様は、明確に規定された表現へ明示的に変換しなければならない。 たとえば CSS シリアル化アルゴリズムを呼び出すことによって行える。(「CSS <string> 値としてシリアル化する」など)。
注: このアルゴリズムと、 CSS 文法に従ってコンマ区切りリストを 構文解析するは、 通常、他の仕様が呼び出したい唯一の構文解析アルゴリズムである。 残りの構文解析アルゴリズムは、主に [CSSOM] および関連する「CSS 構造を明示的に構築する」場合を対象としている。 他のアルゴリズムのいずれかを使用する必要があると思う場合は、 まず CSSWG に指針を求めること。
- input を正規化し、 input をその結果に設定する。
- input からコンポーネント値のリストを構文解析し、 戻り値を result とする。
- result を grammar に対して照合する。 成功した場合、 一致した結果を返す。 そうでなければ、失敗を返す。
5.3.2. CSS 文法に従ってコンマ区切りリストを構文解析する
コンマを含む文法に従って値を構文解析することはもちろん可能であるが、 値のいずれかの部分の構文解析に失敗した場合、 全体が構文解析されず、 失敗を返す。
それが望ましい場合もある
(リスト値の CSS プロパティなど)。
一方で、
値のコンマ区切りの各部分を個別に構文解析し、
構文解析に成功した部分をある方法で処理し、
失敗した部分を別の方法で処理する
(通常は無視する。
たとえば
<img sizes>)
方がよい場合もある。
このアルゴリズムは、まさにそれを実現するための簡単なフックを提供する。 「トップレベル」のコンマで分割された値のリストを返し、 各値は失敗 (構文解析に失敗した場合) または構文解析結果 (構文解析アルゴリズムで説明されている 未指定の構造) のいずれかである。
- input を正規化し、 input をその結果に設定する。
- input が <whitespace-token> のみを含む場合、 空の リストを返す。
- input からコンポーネント値のコンマ区切りリストを 構文解析し、 戻り値を list とする。
- list の各 item についてそれぞれ、 item を grammar で構文解析した結果で置き換える。
- list を返す。
5.3.3. スタイルシートを構文解析する
5.3.4. 規則のリストを構文解析する
- input を正規化し、 input をその結果に設定する。
- top-level flag を設定せずに、input から規則のリストを消費する。
- 返されたリストを返す。
5.3.5. 規則を構文解析する
- input を正規化し、 input をその結果に設定する。
- input の次の 入力トークンが <whitespace-token> である間、input から次の 入力トークンを消費する。
-
input の次の入力
トークンが <EOF-token> である場合、
構文エラーを返す。
そうでなければ、 input の次の 入力トークンが <at-keyword-token> である場合、input からat-rule を消費し、 戻り値を rule とする。
そうでなければ、input からqualified rule を消費し、 戻り値を rule とする。 何も返されなかった場合、 構文エラーを返す。
- input の次の 入力トークンが <whitespace-token> である間、input から次の 入力トークンを消費する。
- input の次の入力 トークンが <EOF-token> である場合、 rule を返す。 そうでなければ、構文エラーを返す。
5.3.6. 宣言を構文解析する
注: 「宣言のリストを 構文解析する」とは異なり、 これは宣言のみを構文解析し、at-rule は構文解析しない。
- input を正規化し、 input をその結果に設定する。
- input の次の 入力トークンが <whitespace-token> である間、次の 入力トークンを消費する。
- input の次の入力 トークンが <ident-token> でない場合、 構文エラーを返す。
- input から宣言を 消費する。 何かが返された場合、それを返す。 そうでなければ、構文エラーを返す。
5.3.7. スタイルブロックの内容を構文解析する
注: このアルゴリズムはスタイル規則の内容を構文解析する。 スタイル規則ではネストされたスタイル規則 および他の at-rule を許可する必要がある。 @page や @keyframes の子規則のように、 ネストされた スタイル規則が不要である場合は、 宣言のリストを構文解析するを使用する。
- input を正規化し、 input をその結果に設定する。
- input からスタイルブロックの内容を消費し、 その結果を返す。
5.3.8. 宣言のリストを構文解析する
注: 名前とは異なり、 これは実際には、CSS 2.1 が @page に対して行うように、 宣言と at-rule が混在したリストを構文解析する。 予期しない at-rule(特定のコンテキストではすべての at-rule が該当し得る)は 無効であり、利用側によって無視される。
注: このアルゴリズムはネストされた スタイル規則を扱わない。 用途でそれが必要な場合は、 スタイルブロックの内容を構文解析するを使用する。
5.3.9. コンポーネント値を構文解析する
- input を正規化し、 input をその結果に設定する。
- input の次の 入力トークンが <whitespace-token> である間、input から次の 入力トークンを消費する。
- input の次の入力 トークンが <EOF-token> である場合、 構文エラーを返す。
- input からコンポーネント値を消費し、 戻り値を value とする。
- input の次の 入力トークンが <whitespace-token> である間、次の 入力トークンを消費する。
- input の次の入力 トークンが <EOF-token> である場合、 value を返す。 そうでなければ、 構文エラーを返す。
5.3.10. コンポーネント値のリストを構文解析する
- input を正規化し、 input をその結果に設定する。
- <EOF-token> が返されるまで、input から繰り返しコンポーネント値を消費し、 返された値(最後の <EOF-token> を除く)をリストに追加する。 そのリストを返す。
5.3.11. コンポーネント値のコンマ区切りリストを構文解析する
- input を正規化し、 input をその結果に設定する。
- list of cvls を、最初は空のコンポーネント値リストのリストとする。
-
<EOF-token> または <comma-token> が返されるまで、input から繰り返しコンポーネント値を消費し、
返された値(最後の <EOF-token> または <comma-token> を除く)をリストに追加する。
そのリストを list of cvls に追加する。
返されたものが <comma-token> であった場合、 このステップを繰り返す。
- list of cvls を返す。
5.4. パーサーアルゴリズム
次のアルゴリズムがパーサーを構成する。 これらは上記のパーサーエントリーポイントから呼び出される。
これらのアルゴリズムは、トークンまたはコンポーネント値のいずれかのリストを指定して呼び出すことができる。 (違いは、コンポーネント値のリストでは、一部のトークンが関数および単純ブロックに置き換えられていることである。) トークン化段階で、入力ストリームが空であることを表すために EOF コードポイントを返したのと同様に、 この段階のリストは、次のトークンが要求されたときに空であれば <EOF-token> を返さなければならない。
アルゴリズムは特定のリストを指定して呼び出すことができ、 その場合はそのリストだけを消費する (そしてそのリストを使い切ると、 <EOF-token> を返し始める)。 そうでなければ、 呼び出し元のアルゴリズムと同じリストを暗黙に指定して呼び出される。
5.4.1. 規則のリストを消費する
top-level flag が与えられたとき、 規則のリストを 消費するには:
最初は空の規則のリストを作成する。
次の 入力トークンを繰り返し消費する:
- <whitespace-token>
- 何もしない。
- <EOF-token>
- 規則のリストを返す。
- <CDO-token>
- <CDC-token>
-
top-level flag が設定されている場合、
何もしない。
そうでなければ、現在の入力トークンを再消費する。qualified rule を消費する。 何かが返された場合、 それを規則のリストに追加する。
- <at-keyword-token>
- 現在の入力トークンを再消費する。at-rule を 消費する。 返された値を規則のリストに追加する。
- それ以外
- 現在の入力トークンを再消費する。qualified rule を消費する。 何かが返された場合、 それを規則のリストに追加する。
5.4.2. at-rule を消費する
at-rule を 消費するには:
次の入力トークンを消費する。 新しい at-rule を作成し、 その名前を現在の入力トークンの値に設定し、 前置部を最初は空の リストに設定し、 値を最初は何もない状態に設定する。
次の 入力トークンを繰り返し消費する:
- <semicolon-token>
- at-rule を返す。
- <EOF-token>
- これは構文解析エラーである。 at-rule を返す。
- <{-token>
- 単純 ブロックを消費し、それを at-rule のブロックに割り当てる。 at-rule を返す。
- 単純ブロックで、関連付けられた トークンが <{-token> であるもの
- そのブロックを at-rule のブロックに割り当てる。 at-rule を返す。
- それ以外
- 現在の入力トークンを再消費する。コンポーネント値を消費する。 返された値を at-rule の前置部に追加する。
5.4.3. qualified rule を消費する
qualified rule を消費するには:
新しい qualified rule を作成し、 前置部を最初は空の リストに設定し、 値を最初は何もない状態に設定する。
次の 入力トークンを繰り返し消費する:
- <EOF-token>
- これは構文解析エラーである。 何も返さない。
- <{-token>
- 単純 ブロックを消費し、それを qualified rule のブロックに割り当てる。 qualified rule を返す。
- 単純ブロックで、関連付けられた トークンが <{-token> であるもの
- そのブロックを qualified rule のブロックに割り当てる。 qualified rule を返す。
- それ以外
- 現在の入力トークンを再消費する。コンポーネント値を消費する。 返された値を qualified rule の前置部に追加する。
5.4.4. スタイルブロックの内容を消費する
スタイル ブロックの内容を消費するには:
最初は空の宣言の リスト decls と、 最初は空の規則の リスト rules を作成する。
次の 入力トークンを繰り返し消費する:
- <whitespace-token>
- <semicolon-token>
- 何もしない。
- <EOF-token>
- decls を rules で拡張し、その後 decls を返す。
- <at-keyword-token>
- 現在の入力トークンを再消費する。at-rule を 消費するし、 その結果を rules に追加する。
- <ident-token>
- 最初に現在の入力トークンを格納した一時リストを初期化する。 次の 入力トークンが <semicolon-token> または <EOF-token> 以外である限り、コンポーネント 値を消費して、一時リストに追加する。 一時リストから宣言を消費する。 何かが返された場合、 それを decls に追加する。
- <delim-token> で、値が "&" (U+0026 AMPERSAND) であるもの
- 現在の入力トークンを再消費する。qualified rule を消費する。 何かが返された場合、 それを rules に追加する。
- それ以外
- これは構文解析エラーである。現在の入力トークンを再消費する。 次の 入力トークンが <semicolon-token> または <EOF-token> 以外である限り、コンポーネント 値を消費して、返された値を破棄する。
5.4.5. 宣言のリストを消費する
宣言の リストを消費するには:
最初は空の宣言のリストを作成する。
次の 入力トークンを繰り返し消費する:
- <whitespace-token>
- <semicolon-token>
- 何もしない。
- <EOF-token>
- 宣言のリストを返す。
- <at-keyword-token>
- 現在の入力トークンを再消費する。at-rule を 消費する。 返された規則を宣言のリストに追加する。
- <ident-token>
- 最初に現在の入力トークンを格納した一時リストを初期化する。 次の 入力トークンが <semicolon-token> または <EOF-token> 以外である限り、コンポーネント 値を消費して、一時リストに追加する。 一時リストから宣言を消費する。 何かが返された場合、 それを宣言のリストに追加する。
- それ以外
- これは構文解析エラーである。現在の入力トークンを再消費する。 次の 入力トークンが <semicolon-token> または <EOF-token> 以外である限り、コンポーネント 値を消費して、返された値を破棄する。
5.4.6. 宣言を消費する
注: このアルゴリズムは、次の入力トークンが <ident-token> であることがすでに確認されていることを前提とする。
宣言を 消費するには:
次の入力トークンを消費する。 新しい宣言を作成し、 その名前を現在の入力トークンの値に設定し、その値を最初は空の リストに設定する。
- 次の入力 トークンが <whitespace-token> である間、次の 入力トークンを消費する。
-
次の入力
トークンが <colon-token> 以外である場合、
これは構文解析エラーである。
何も返さない。
そうでなければ、次の入力トークンを消費する。
- 次の入力 トークンが <whitespace-token> である間、次の 入力トークンを消費する。
- 次の 入力トークンが <EOF-token> 以外である限り、コンポーネント値を消費して、宣言の値に追加する。
- 宣言の値に含まれる最後の2つの非 <whitespace-token> が、 値 "!" を持つ <delim-token> と、 その後に続く、値が "important" と ASCII 大文字・小文字を区別しない一致をする <ident-token> である場合、 それらを宣言の値から削除し、 宣言の important フラグを true に設定する。
- 宣言の値の最後のトークンが <whitespace-token> である間、 そのトークンを削除する。
- 宣言を返す。
5.4.7. コンポーネント値を消費する
コンポーネント 値を消費するには:
現在の入力 トークンが <{-token>、<[-token>、または <(-token> である場合、単純ブロックを消費し、 それを返す。
そうでなければ、現在の入力トークンが <function-token> である場合、関数を消費して、それを返す。
そうでなければ、現在の入力トークンを返す。
5.4.8. 単純ブロックを消費する
注: このアルゴリズムは、現在の入力トークンが <{-token>、<[-token>、または <(-token> であることがすでに確認されていることを前提とする。
単純 ブロックを消費するには:
終了トークンは、 現在の入力トークンの対になる種類である。 (たとえば <[-token> を指定して呼び出された場合、終了トークンは <]-token> である。)
単純ブロックを作成し、 関連付けられたトークンを現在の入力トークンに設定し、その値を最初は空の リストに設定する。
次の 入力トークンを繰り返し消費し、次のように処理する:
- 終了トークン
- ブロックを返す。
- <EOF-token>
- これは構文解析エラーである。 ブロックを返す。
- それ以外
- 現在の入力トークンを再消費する。コンポーネント値を消費し、それを ブロックの値に追加する。
注: CSS には、宣言を含めることのできるブロック と qualified rule を含めることのできるブロックとの間に不都合な構文上の曖昧さがあるため、 規則を扱う「consume」アルゴリズムは、 より具体的な 宣言のリストを消費するまたは 規則の リストを消費するアルゴリズムではなく、 最初はこのより汎用的なアルゴリズムを使用する。 これらのより具体的なアルゴリズムは、 文法が適用される際に、 <declaration-list> または <rule-list>/<stylesheet> のどちらを含むかに応じて呼び出される。
5.4.9. 関数を消費する
注: このアルゴリズムは、現在の入力トークンが <function-token> であることがすでに確認されていることを前提とする。
関数を 消費するには:
関数を作成し、その名前を現在の入力トークンの値と等しくし、その値を最初は空の リストに設定する。
次の 入力トークンを繰り返し消費し、次のように処理する:
- <)-token>
- 関数を返す。
- <EOF-token>
- これは構文解析エラーである。 関数を返す。
- それ以外
- 現在の入力トークンを再消費する。コンポーネント値を消費し、返された値を 関数の値に追加する。
6. An+B マイクロ構文
CSS のいくつかのもの、 たとえば :nth-child() 擬似クラスは、 リスト内のインデックスを示す必要がある。 An+B マイクロ構文はこの目的に有用であり、 作者が単一の要素、 またはリスト内で一定間隔に並ぶすべての要素を簡単に指定できる。
An+B 記法は、 整数のステップ(A)とオフセット(B)を定義し、 n のすべての正の整数値または0について、 リスト内の An+B 番目の要素を表す。 リスト内の最初の要素のインデックスは 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. <an+b> 型
An+B 記法は元々、CSS の他の部分とはわずかに異なるトークナイザーを使用して定義されていたため、 CSS トークンの観点で表すとやや奇妙な定義になる。 この節では、CSS トークンの観点から An+B 記法を認識する方法 (したがって CSS 文法上の <an+b> 型を定義する方法)、 および CSS トークンを解釈して A と B の値を得る方法を説明する。
<an+b> 型は、 (Values & Units 仕様の値定義構文を使用して) 次のように定義される:
<an+b> = odd | even | <integer> | <n-dimension> | '+'?† n | -n | <ndashdigit-dimension> | '+'?† <ndashdigit-ident> | <dashndashdigit-ident> | <n-dimension> <signed-integer> | '+'?† n <signed-integer> | -n <signed-integer> | <ndash-dimension> <signless-integer> | '+'?† n- <signless-integer> | -n- <signless-integer> | <n-dimension> ['+' | '-'] <signless-integer> '+'?† n ['+' | '-'] <signless-integer> | -n ['+' | '-'] <signless-integer>
ここで:
<n-dimension>は、type フラグが "integer" に設定され、単位が "n" と ASCII 大文字・小文字を区別しない一致をする <dimension-token> である<ndash-dimension>は、type フラグが "integer" に設定され、単位が "n-" と ASCII 大文字・小文字を区別しない一致をする <dimension-token> である<ndashdigit-dimension>は、type フラグが "integer" に設定され、 単位が "n-*" と ASCII 大文字・小文字を区別しない一致をする <dimension-token> であり、ここで "*" は1つ以上の数字の連続である<ndashdigit-ident>は、値が "n-*" と ASCII 大文字・小文字を区別しない一致をする <ident-token> であり、ここで "*" は1つ以上の数字の連続である<dashndashdigit-ident>は、値が "-n-*" と ASCII 大文字・小文字を区別しない一致をする <ident-token> であり、ここで "*" は1つ以上の数字の連続である<integer>は、type フラグが "integer" に設定された <number-token> である<signed-integer>は、type フラグが "integer" に設定され、その表現が "+" または "-" で始まる <number-token> である<signless-integer>は、type フラグが "integer" に設定され、その表現が数字で始まる <number-token> である
†: 上記で印を付けた場合のように、プラス記号 (+) が "n" で始まる ident に先行する場合、 2つのトークンの間に空白があってはならない。 そうでなければ、そのトークンは上記の文法に一致しない。 その他の任意の2つのトークン間では空白は有効であり(無視される)。
生成規則の各節は次のように解釈される:
- odd
- A は 2、B は 1。
- even
- A は 2、B は 0。
<integer>- A は 0、B は整数の値。
<n-dimension>'+'? n-n- A はそれぞれ、dimension の値、1、または -1。B は 0。
<ndashdigit-dimension>'+'? <ndashdigit-ident>- A はそれぞれ dimension の値または 1。B はそれぞれ dimension の単位または ident の値から最初の コードポイントを除去し、残りを10進数として解釈した値。 B は負である。
<dashndashdigit-ident>- A は -1。B は ident の値から最初の2つの コードポイントを除去し、 残りを10進数として解釈した値。B は負である。
<n-dimension> <signed-integer>'+'? n <signed-integer>-n <signed-integer>- A はそれぞれ、dimension の値、1、または -1。B は整数の値。
<ndash-dimension> <signless-integer>'+'? n- <signless-integer>-n- <signless-integer>- A はそれぞれ、dimension の値、1、または -1。B は 整数の値を反転したもの。
<n-dimension> ['+' | '-'] <signless-integer>'+'? n ['+' | '-'] <signless-integer>-n ['+' | '-'] <signless-integer>- A はそれぞれ、dimension の値、1、または -1。B は整数の値。
2つの間に
'-'が指定されていた場合、B は代わりに 整数の値を反転したものとなる。
7. Unicode-Range マイクロ構文
一部の構造、たとえば @font-face 規則の unicode-range 記述子などは、1つ以上の Unicode コードポイントを記述する方法を必要とする。 <urange> 生成規則は、1つ以上の Unicode コードポイントの範囲を表す。
非形式的には、<urange> 生成規則には3つの形式がある:
- U+0001
- 単一のコードポイントからなる範囲を定義する。 この場合はコードポイント "1"。
- U+0001-00ff
- 最初の値と2番目の値の間(両端を含む)のコードポイントの範囲を定義する。 この場合は "1" から "ff"(10進数で255)までの範囲(両端を含む)。
- U+00??
- "?" 文字がすべての16進数字にわたるコードポイントの範囲を定義する。 この場合は値 U+0000-00ff と同じものを定義する。
各形式では、各16進数について最大6桁までが許可される ("?" を16進数字として扱う場合)。
7.1. <urange> 型
<urange> 記法は元々 CSS の原始トークンとして定義されていたが、 使用されることは非常にまれであり、 正当な <ident-token> と紛らわしい形で衝突する。 この節では、既存の CSS トークンの観点から <urange> 記法を認識する方法、 およびそれを Unicode コードポイントの範囲として解釈する方法を説明する。
紛らわしい衝突とは何か?
たとえば CSS u + a { color: green;
} では、
意図された意味は、u 要素の後に続く
a 要素を
緑色にすることである。
通常、結合子と
その周囲のセレクターとの間に空白は必要ないため、
これを次のように縮小しても同等であるべきである
他の結合子であれば、この2つの CSS は同等だが、 以前は特殊な unicode-range トークンが存在していたため、 縮小されたコードのセレクター部分には、 2つの ident と結合子ではなく unicode-range が含まれることになる。 そのため Selectors 文法との一致に失敗し、 規則は無効として破棄される。
(この例は Firefox に報告された実際のバグから取られている。)
注: ここで説明される構文は意図的に非常に低水準であり、 実装者向けである。 作者は代わりに前節の非形式的な構文説明を読むべきである。 そこには <urange> を使用するために必要なすべての情報が含まれており、 実際に読みやすい。
<urange> 型は、 (Values & Units 仕様の値定義構文を使用して)次のように定義される:
<urange> = u '+' <ident-token> '?'* | u <dimension-token> '?'* | u <number-token> '?'* | u <number-token> <dimension-token> | u <number-token> <number-token> | u '+' '?'+
この生成規則では、 いずれのトークン間にも空白を置くことはできない。
<urange> 生成規則は、1つ以上の連続した Unicode コードポイントの範囲を、 非負整数である start value と end value として表す。 上記の生成規則を範囲として解釈するには、 次のステップを順番に実行する:
-
最初の u トークンを飛ばし、 生成規則内のすべてのトークンの表現を連結する。 これを text とする。
-
text の最初の文字が U+002B PLUS SIGN である場合、 それを消費する。 そうでなければ、 これは無効な <urange> であり、 このアルゴリズムを終了しなければならない。
-
text から可能な限り多くの16進数字を消費する。 次に、可能な限り多くの U+003F QUESTION MARK (?) コードポイントを 消費する。 コードポイントが1つも消費されなかった場合、 または6つを超える コードポイントが消費された場合、 これは無効な <urange> であり、 このアルゴリズムを終了しなければならない。
U+003F QUESTION MARK (?) コードポイントが 1つでも消費された場合、次を行う:
-
text に コードポイントが残っている場合、 これは無効な <urange> であり、 このアルゴリズムを終了しなければならない。
-
消費された コード ポイントを16進数として解釈し、 U+003F QUESTION MARK (?) コードポイントを U+0030 DIGIT ZERO (0) コードポイントに置き換える。 これを start value とする。
-
消費された コード ポイントを再び16進数として解釈し、 U+003F QUESTION MARK (?) コードポイントを U+0046 LATIN CAPITAL LETTER F (F) コード ポイントに置き換える。 これを end value とする。
-
このアルゴリズムを終了する。
そうでなければ、消費された コードポイントを 16進数として解釈する。 これを start value とする。
-
-
text に コードポイントが残っていない場合、 end value は start value と同じである。 このアルゴリズムを終了する。
-
text 内の次の コードポイントが U+002D HYPHEN-MINUS (-) である場合、 それを消費する。 そうでなければ、 これは無効な <urange> であり、 このアルゴリズムを終了しなければならない。
-
text から可能な限り多くの16進数字を 消費する。
16進数字が1つも 消費されなかった場合、 または6つを超える 16進数字が消費された場合、 これは無効な <urange> であり、 このアルゴリズムを終了しなければならない。 text に コードポイントが残っている場合、 これは無効な <urange> であり、 このアルゴリズムを終了しなければならない。
-
消費された コードポイントを16進数として解釈する。 これを end value とする。
<urange> が表すコードポイントを決定するには:
-
end value が許可される最大コード ポイントより大きい場合、 <urange> は無効であり、構文エラーである。
-
start value が end value より大きい場合、 <urange> は無効であり、構文エラーである。
-
そうでなければ、<urange> は start value から end value まで(両端を含む)の連続したコードポイントの範囲を表す。
注: <urange> の構文は意図的にかなり広く、 そのパターンは、非形式的な構文が生成し得るすべてのトークンシーケンスを捉える。 ただし、その構成トークン間に空白がないことを要求するため、 実際にはかなり安全に使用できる。 <urange> の後に <number> または <dimension> が続く文法でさえ(作者が <urange> を ''u <number>'' 節で指定すると曖昧に見えるかもしれないが)、 実際にはかなり安全である。 曖昧にするには、作者が意図的に <urange> と <number>/<dimension> を空白ではなくコメントで区切る必要があるためである。 したがって、作者が紛らわしい方法で構文解析されるものを書くことは可能ではあるが、 その混乱を引き起こすために実際に書かなければならないコード自体が、紛らわしく、まれである。
8. 規則およびその他の値の文法の定義
Values 仕様は、プロパティの文法を指定する方法を定義している。 この節では同じことを規則に対して行う。
プロパティ文法と同様に、
<foo> という表記は、別の場所で定義されていると想定される
"foo" 文法用語を参照する。
<foo> をその定義に置き換えると、意味的に同一の文法になる。
いくつかの種類のトークンは、引用符なしで文字どおり記述される:
- <ident-token>(
auto、discなど)は、その値をそのまま記述する。 - <at-keyword-token> は、
@mediaのように @ 文字の後にトークンの値を続けて記述する。 - <function-token> は、
translate(のように関数 名の後に ( 文字を続けて記述する。 - <colon-token>(
:と記述)、<comma-token>(,と記述)、<semicolon-token>(;と記述)、<(-token>、<)-token>、<{-token>、および <}-token>。
トークンの値が文法で定義された値と一致する場合、トークンは一致する。 特に指定がない限り、すべての一致はASCII 大文字・小文字を区別しない。
注: エスケープを使用して、
値が ( で終わる、または @ で始まる <ident-token> を構築することは可能だが、
そのようなトークンは <function-token> または <at-keyword-token> ではなく、対応する
文法定義には一致しない。
<delim-token> は、その値を一重引用符で囲んで記述する。
たとえば、"+" コードポイントを含む <delim-token>
は '+' と記述する。
同様に、<[-token> および <]-token> も
一重引用符で記述しなければならない。
これらは文法自体の構文で節をグループ化するために使用されるためである。<whitespace-token>
は文法内で示されることはない。
<whitespace-token> は、
本文の定義で明示的に別途指定されていない限り、
任意の2つのトークンの前、後、および間で許可される。
(たとえば、規則の前置部がセレクターである場合、
空白には意味がある。)
関数またはブロックを定義する場合、 終了トークンは文法内で指定しなければならないが、 最終的なトークンストリームに存在しなくても、 依然として一致する。
translateX( <translation-value> )
しかし、スタイルシートが次のように関数を閉じないまま終了する場合もある:
.foo { transform: translate(50px
CSS パーサーはこれを、1つの宣言を含むスタイル規則として構文解析し、 その値は "translate" という名前の関数となる。 これは上記の文法に一致する。 終了トークンがトークンストリームに現れなかったにもかかわらず一致するのは、 パーサーが完了した時点では、 終了トークンが存在したかどうかをもはや判断できないためである。 分かるのは、ブロックと関数が存在するという事実だけである。
8.1. ブロック内容の定義: <declaration-list>、 <rule-list>、および <stylesheet> 生成規則
CSS パーサーは、一部の at-rule の末尾に現れるものなど、 ブロックの内容について関知しない。 トークンの観点からブロックの汎用文法を定義することは単純ではないが、 これを構文解析するための専用かつ曖昧さのないアルゴリズムが定義されている。
<style-block> 生成規則は、スタイル規則のブロックの内容を表す。 文法ではブロック内の唯一の値としてのみ使用でき、 ブロックの内容をスタイル ブロックの内容を消費するアルゴリズムを使用して構文解析しなければならないことを表す。
<declaration-list> 生成規則は、宣言のリストを表す。 文法ではブロック内の唯一の値としてのみ使用でき、 ブロックの内容を宣言のリストを 消費するアルゴリズムを使用して構文解析しなければならないことを表す。
同様に、<rule-list> 生成規則は規則のリストを表し、 文法ではブロック内の唯一の値としてのみ使用できる。 これは、ブロックの内容を規則のリストを消費する アルゴリズムを使用して構文解析しなければならないことを表す。
最後に、<stylesheet> 生成規則は規則のリストを表す。 <rule-list> と同一であるが、 これを使用するブロックは、特定のコンテキストに限定されていない すべての規則を既定で受け入れる点が異なる。
| 宣言を許可 | ネストされたスタイル規則を許可 | 任意の qualified rule を許可 | at-rule を許可 | 例 | |
|---|---|---|---|---|---|
| <style-block> | ✓ | ✓ | ✗ | ✓ | スタイル規則、@nest、ネストされた条件付きグループ規則 |
| <declaration-list> | ✓ | ✗ | ✗ | ✓ | @font、@counter-style、@page、@keyframes の子規則 |
| <rule-list> | ✗ | ✗ | ✓ | ✓ | @keyframes、@font-feature-values |
| <stylesheet> | ✗ | ✗ | ✓ | ✓ | スタイルシート、ネストされていない 条件付きグループ規則 |
特定のコンテキストが、@font-features-values のように、 at-ruleのみを受け入れることを意図している場合、 実際にはどの生成規則を使用しても問題ないが、 より分かりやすい名前である <rule-list> が推奨される。
@font-face { <declaration-list> }
これは規則の文法の完全かつ十分な定義である。
別の例として、@keyframes 規則はより複雑であり、 その前置部を名前として解釈し、そのブロック内にキーフレーム規則を含む。 その文法は次のとおりである:
@keyframes <keyframes-name> { <rule-list> }
<style-block> または <declaration-list> を使用する規則については、 その規則の仕様は、その規則内でどのプロパティ、記述子、および/または at-rule が有効かを定義しなければならない。 これは「@foo 規則はこの仕様/節で定義される プロパティ/記述子を受け入れる。」と述べるだけの単純なものでもよく、 拡張仕様は単に「@foo 規則はさらに次の プロパティ/記述子を受け入れる。」と述べてもよい。 ブロック内に見つかった、妥当であると定義されていない宣言または at-rule は、 規則の値から削除しなければならない。
<style-block> または <declaration-list> 内では、!important は
どの記述子に対しても自動的に無効である。
規則がプロパティを受け入れる場合、
その規則の仕様は、プロパティがカスケードと相互作用するかどうか、
またどの詳細度で相互作用するかを定義しなければならない。
カスケードと相互作用しない場合、
!important を含むプロパティは自動的に無効となる。
そうでなければ !important の使用は有効であり、
宣言を重要なものとし、
カスケードの目的で使用される。
[CSS-CASCADE-3] を参照。
<rule-list> を使用する規則については、 その規則の仕様は、<declaration-list> と同様に、 どの種類の規則が内部で有効かを定義しなければならず、 認識されない規則も同様に規則の値から削除しなければならない。
<keyframe-rule> = <keyframe-selector> { <declaration-list> }
さらにキーフレーム規則は、すべてのアニメーション可能な CSS プロパティに加えて、 animation-timing-function プロパティを宣言として受け入れるが、 カスケードとは相互作用しないことを定義しなければならない。
<stylesheet> を使用する規則では、 既定ですべての規則が許可されるが、 その規則の仕様は、内部でどの種類の規則が無効であるかを定義してもよい。
@media <media-query-list> { <stylesheet> }
さらに、<stylesheet> は @media 規則を含むことができないという制限を定義しており、 それらが現れた場合には外側の規則の値から削除される。
8.2. 任意の内容の定義: <declaration-value> および <any-value> 生成規則
一部の文法では、 文法内で合理的な任意の入力を受け入れ、 内容について手動でより具体的なエラー処理を行うことが有用である (文法の不一致が通常行うように、 単に構造を無効にするのではなく)。
たとえば、カスタム プロパティは、他の CSS プロパティの任意の断片を含むことができ、 また既存の CSS にまったく含まれないものに使用することもできるため、 合理的な任意の値を許可する。 別の例として、Media Queries の <general-enclosed> 生成規則は、 将来の MQ 構文が許可する範囲を定義し、 「未知」の値を扱うために特別なロジックを使用する。
これを支援するため、2つの追加の生成規則が定義される:
<declaration-value> 生成規則は、 そのシーケンスが <bad-string-token>、<bad-url-token>、 対応のない <)-token>、<]-token>、または <}-token>、 あるいはトップレベルの <semicolon-token> トークン、または値が "!" の <delim-token> トークンを含まない限り、 1つ以上のトークンからなる任意のシーケンスに一致する。 これは、有効な宣言が値として持つことのできるもの全体を表す。
<any-value> 生成規則は <declaration-value> と同一だが、 トップレベルの <semicolon-token> トークン および値が "!" の <delim-token> トークンも許可する。 これは、任意のコンテキストにおいて有効な CSS となり得るもの全体を表す。
9. CSS スタイルシート
CSS スタイルシートを構文解析するには、 まずスタイルシートを 構文解析する。 結果として得られたすべてのトップレベルの qualified rule を、以下で定義する スタイル規則として解釈する。
いずれかのスタイル規則が無効である場合、 またはいずれかの at-rule が認識されないか、その文法またはコンテキストに従って無効である場合、 それは構文解析エラーである。 その規則を破棄する。
9.1. スタイル規則
スタイル規則は、 qualified rule であり、 セレクターリストをプロパティ宣言のリスト および場合によってはネストされた規則のリストと関連付ける。 [CSS2] では 規則セットとも呼ばれる。 CSS Cascading and Inheritance [CSS-CASCADE-3] は、スタイル規則内の宣言がカスケードにどのように参加するかを定義する。
qualified rule の前置部は、<selector-list> として構文解析される。 これが失敗を返した場合、 スタイル規則全体が無効である。
qualified rule のブロックの内容は、スタイルブロックの 内容として構文解析される。 別の仕様またはこの仕様の将来のレベルで別途定義されない限り、 そのリスト内の at-rule は無効であり、 無視しなければならない。
注: [CSS-NESTING-1] は、@nest および 条件付きグループ規則がスタイル規則内で許可されることを定義する。
未知の CSS プロパティに対する宣言、 またはその値がプロパティで定義された構文に一致しない宣言は無効であり、無視しなければならない。 スタイル規則の内容の妥当性は、スタイル規則自体の妥当性には影響しない。 特に指定がない限り、プロパティ名はASCII 大文字・小文字を区別しない。
注: カスタムプロパティ [CSS-VARIABLES] の名前は大文字・小文字を区別する。
CSS スタイルシートのトップレベルにあるqualified ruleはスタイル 規則である。 他のコンテキストの qualified rule は、 そのコンテキストの定義に従って、スタイル規則である場合もあれば、そうでない場合もある。
たとえば、 @media 規則 [CSS3-CONDITIONAL] 内の qualified rule はスタイル規則であるが、 @keyframes 規則 [CSS3-ANIMATIONS] 内の qualified rule はスタイル規則ではない。
9.2. At-rule
at-rule は、 at-keyword で始まる規則であり、 そのため同じコンテキスト内のスタイル規則と区別できる。
At-rule は次の目的に使用される:
-
条件付きグループ規則のように、 スタイル規則および他の at-rule をグループ化し構造化する
-
カウンタースタイルの定義など、 特定の要素に関連付けられていないスタイル情報を宣言する
-
およびスタイル規則では果たされないその他のさまざまな目的に使用される
At-rule は、特定の規則とその目的に応じてさまざまな形式を取るが、 大まかには2種類ある。セミコロンで終わるより単純な構造である 文 at-ruleと、 ネストされた qualified rule、at-rule、または 宣言を含むことができる {}-ブロックで終わる ブロック at-ruleである。
ブロック at-ruleは通常、 at-rule によって定義された制限に従う、 (汎用または at-rule 固有の)at-rule、qualified rule、および/または 記述子宣言の集合を含む。 記述子はプロパティに似ており (同じ構文で宣言される)が、 ツリー内の要素やボックスではなく、特定の種類の at-rule に関連付けられる。
9.3. @charset 規則
スタイルシートのフォールバックエンコーディングを決定するために使用されるアルゴリズムは、 ファイルの最初の数バイトとして特定のバイトシーケンスを探す。 これは "@charset" という名前の at-rule の構文形式を持つ。
しかし、@charset という名前の実際の at-rule は存在しない。 スタイルシートが実際に構文解析される場合、 @charset 規則の出現はすべて、認識されない規則として扱わなければならず、 したがってスタイルシートの文法検査時に無効として破棄される。
注: CSS 2.1 では、@charset は有効な規則だった。 一部のレガシー仕様は、依然として @charset 規則を参照し、 スタイルシート内にそれが存在することについて明示的に述べている場合がある。
10. シリアル化
この仕様で説明されるトークナイザーはコメント用のトークンを生成せず、 その他の方法でもコメントを保持しない。 実装はコメントの内容とトークンストリーム内での位置を保持してもよい。 その場合、この保持された情報は構文解析ステップに一切影響してはならない。
この仕様は CSS を一般にどのようにシリアル化するかを定義せず、 その作業は [CSSOM] および個々の機能仕様に委ねる。 特に、コメントと空白のシリアル化は定義されない。
シリアル化に対する唯一の要件は、構文解析との「ラウンドトリップ」が可能でなければならないことである。 すなわち、スタイルシートを構文解析した結果は、 構文解析し、シリアル化し、再び構文解析した結果と同じデータ構造を生成しなければならない。 ただし、連続する <whitespace-token> は例外で、 単一のトークンにまとめてもよい。
注: この例外が存在できるのは、 CSS 文法が常に任意量の空白を単一の空白と同一に解釈するためである。
- U+005C REVERSE SOLIDUS (\) を含む <delim-token> は、U+005C REVERSE SOLIDUS の後に改行を続けてシリアル化しなければならない。 (トークナイザーは、そのようなトークンを、改行で始まる <whitespace-token> の直前にのみ出力する。)
- "unrestricted" type フラグを持つ <hash-token> は、"id" type フラグを持つ同じトークンほど 多くのエスケープを必要としない場合がある。
- <dimension-token> の単位は、 科学的記数法との曖昧さを避けるためにエスケープが必要になる場合がある。
-
任意の連続するトークンの組について、
最初のトークンが次の表の行見出しに現れ、
2番目のトークンが列見出しに現れ、
選択した行と列の交点のセルに ✗ がある場合、
そのトークンの組は間にコメントを挿入してシリアル化しなければならない。
トークナイザーがコメントを保持している場合、 保持されたコメントを使用するべきである。 そうでなければ、空のコメント(
/**/)を挿入しなければならない。 (次の表で2つのトークン間にコメントが必要とされていなくても、 保持されたコメントを再挿入してもよい。)行見出しと列見出しの単一文字は、その値を持つ <delim-token> を表す。 ただし "
(" は例外で、 (-token を表す。
| ident | function | url | bad url | - | number | percentage | dimension | CDC | ( | * | % | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ident | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ||
| at-keyword | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| hash | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| dimension | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| # | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| - | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| number | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | |||
| @ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ||||||
| . | ✗ | ✗ | ✗ | |||||||||
| + | ✗ | ✗ | ✗ | |||||||||
| / | ✗ |
10.1. <an+b> のシリアル化
-
A が 0 の場合、 B のシリアル化を返す。
-
そうでなければ、result を最初は空の 文字列とする。
-
- A が
1 -
"n" を result に追加する。
- A が
-1 -
"-n" を result に追加する。
- A が 0 ではない
-
A をシリアル化して result に追加し、 次に "n" を result に追加する。
- A が
-
- B が 0 より大きい
-
"+" を result に追加し、 次に B のシリアル化を result に追加する。
- B が 0 より小さい
-
B のシリアル化を result に追加する。
-
result を返す。
11. プライバシーとセキュリティに関する考慮事項
この仕様は、新たなプライバシー上の懸念をもたらさない。
この仕様では、すべての入力に対する CSS の構文解析が曖昧さなく定義されるようになったため、セキュリティが向上する。
ホワイトリスト/フィルターなどの古いパーサーがこの仕様とは異なる構文解析を行う限りにおいて、 それらは多少安全ではない。 しかし、以前の構文解析仕様には、ブラウザーごとに異なる解釈をしていた曖昧な境界事例が多数残されていたため、 それらのフィルターはすでに安全でない可能性があり、 この仕様が状況を悪化させることはない。
12. 変更点
この節は規範的ではない。
12.1. 2019年8月16日付勧告候補からの変更点
次の実質的な変更が行われた:
-
新しい § 5.3.2 CSS 文法に従ってコンマ区切りリストを 構文解析するアルゴリズムを追加した。
-
新しい § 5.3.7 スタイルブロックの内容を構文解析する アルゴリズム および対応する <style-block> 生成規則を追加し、 スタイル 規則がこれを使用することを定義した。
-
スタイルシートを 構文解析するを Fetch 関連の処理に合わせた。 (コミットを参照。)
input からスタイルシートを 構文解析するには 、省略可能な url location が与えられた状態で :
- ...
- 新しいスタイルシートを作成し 、その場所を location に設定する(location が渡されなかった場合は null)。
- ...
次の編集上の変更が行われた:
-
at-rule、文 at-rule、ブロック at-rule、および 記述子の定義を提供するため、 § 9.2 At-rule を追加した。 (5633)
-
場合によって “name” という用語を使用する代わりに、一貫して ident シーケンスと呼ぶように変更した。
-
トークン化前のいくつかの処理に明示的な名前を付け、 構文解析エントリーポイントからそれらを明示的に参照するようにした (「これらのアルゴリズムの開始時に X を行う」という包括的な記述に依存する代わりに)。
-
ident が
--で始まるようになった事実を適切に処理するため、 「間にコメントを挿入する」表にさらに項目を追加した。 (6874)
12.2. 2014年2月20日付勧告候補からの変更点
次の実質的な変更が行われた:
-
<unicode-range-token> を削除し、 代わりに <urange> 生成規則を作成した。
-
文字列を含む url() 関数は、通常の <function-token> として構文解析されるようになった。 「生の」URL を含む url() 関数は、引き続き <url-token> として特別に構文解析される。
-
「URL トークンを消費する」アルゴリズムにおいて、 文字列を消費しようとする前に、その文字列を開始する引用符文字を消費していなかったバグを修正した。
-
現在/次の入力トークンおよび処理対象が早すぎる/遅すぎるタイミングで消費されることに関連する、 複数のパーサーアルゴリズムのバグを修正した。
-
トークン化および構文解析アルゴリズムのいくつかのバグを修正した。
-
ident-like トークンの定義を変更し、"--" で ident を開始できるようにした。 この一環として、トークンを消費するの "-" ステップにおける節の順序を並べ替え、 <CDC-token> が -- <ident-token> になるのではなく、 そのようなものとして認識されるようにした。
-
A が 1 または -1 の場合、<an+b> の数字をシリアル化しないようにした。
-
すべてのトークンが表現を持つことを定義した。
-
2つのコードポイントが有効な エスケープか確認するの小さなバグを修正した—
\の後に EOF が続く場合、 正しく有効なエスケープではないと報告されるようになった。 スタイルシート末尾の\は、単にそれ自体を <delim-token> として出力するようになった。 -
@charset はもはや有効な CSS 規則ではない(@charset という名前の規則のように見える エンコーディング宣言があるだけである)
-
構文解析中に、宣言の値の先頭/末尾から空白を除去するようにした。
-
WG の決議に従い、Selectors 固有のトークンを削除した。
-
WG の決議に従い、入力ストリームからサロゲートをフィルタリングするようにした。 現在、この仕様全体はスカラー値のみを対象として動作する。
次の編集上の変更が行われた:
-
「文字列トークンを消費する」アルゴリズムを変更し、明示的な 終了トークンを指定せずに呼び出せるようにし、 その場合は現在の入力トークンを使用するようにした。 このアルゴリズムの3つの呼び出し箇所も、その形式を使用するように変更した。
-
アルゴリズムの軽微な編集上の再構成。
-
構文解析するおよび コンポーネント値のコンマ区切りリストを 構文解析する API エントリーポイントを追加した。
-
<declaration-value> および <any-value> 生成規則を追加した。
-
Infra Standard の同一の定義を使用するため、「code point」および「surrogate code point」を削除した。
-
すべての範囲について、両端を含むことを明確化した。
-
number トークンが "%" delim トークンの隣に現れる場合を処理するため、 コメント挿入表に列を追加した。
12.3. 2013年11月5日付最終草案からの変更点
- シリアル化の節を書き直し、 「ラウンドトリップ」の要件のみを規範的なものとし、 その実現方法の詳細を注記へ移動した。 これらの詳細におけるいくつかの境界事例も修正した。
- [ENCODING] を 規範的参考文献の一覧に追加した。 以前から規範的な本文で参照されていたが、 そのようなものとして一覧には記載されていなかった。
-
スタイルシートのフォールバックエンコーディングを決定するアルゴリズムで、
@charsetバイトシーケンスを1024バイトに制限した。 これは HTML が<meta charset>に対して行うことと一致し、 シーケンスのサイズが有界であることを保証する。 これはエンコーディングラベルの先頭または末尾に空白がある場合にのみ違いを生じる:@charset " (大量の空白) utf-8";
12.4. 2013年9月19日付作業草案からの変更点
- 環境エンコーディングという概念を追加した。 動作は変わらないが、 一部の定義は関連する仕様へ移動するべきである。
12.5. CSS 2.1 および Selectors Level 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 コードポイントの定義を、 ASCII のすべての定義と一貫するように変更した。 これは コードポイント U+0080 から U+009F に影響し、 これらは他の 非 ASCII コードポイントと同様に、 <delim-token> ではなく ident コード ポイントとなる。
- トークン化では COMMENT または BAD_COMMENT トークンを出力しなくなった。 BAD_COMMENT は現在、通常のトークンと同じものとみなされる(エラーではない)。シリアル化は、 たとえば連続する2つの <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 と一致させるため、数値/パーセンテージ/dimension で科学的記数法をサポートする。
- サロゲートの16進エスケープは、 サロゲートではなく置換文字を出力するようになった。 これにより、実装は内部で UTF-16 を安全に使用できる。
構文解析に関する変更:
- WG の決議に従い、宣言の任意のリストは @page のように、 at-rule も受け入れるようになった。 まだそのような at-rule が定義されていなくても、 これはエラー処理に違いを生じさせる。 at-rule は、有効かどうかにかかわらず、<semicolon-token> なしで {} ブロックで終了し、 次の宣言を開始できるようにする。
-
文法のさまざまな場所に現れる、対応のない <}-token>
のようないくつかの雑多な「特殊」トークンの処理について、
少なくとも1つのブラウザーが示す妥当な動作を規定した。
以前は、そのような場所にこれらのトークンを含むスタイルシートはスタイルシート文法にまったく一致せず、
その処理は完全に未定義だった。
具体的には:
- [] ブロック、() ブロック、および関数は、{} ブロック、<at-keyword-token> または <semicolon-token> を含められるようになった
- qualified rule の前置部はセミコロンを含められるようになった
- qualified rule および at-rule の前置部は <at-keyword-token> を含められるようになった
Selectors Level 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, and Zack Weinberg.