[10] [[CSS]] では[[構文解析]]の方法が仕様により定められており、どのような[[バイト列]]、[[文字列]]であってもそれが
[[CSS]] [[スタイルシート]]としてどう解釈されるべきかが明確になっています。

;;
[11] 本項では[[構文解析器]] ([[利用者エージェント]]) の動作について扱います。構文一般について、あるいは[[著者]]の要件については
[[CSSの構文]]の項をご覧ください。

* 仕様書

[REFS[
- [4] [CITE@en[CSS Syntax Module Level 3]] ([TIME[2013-06-29 19:17:26 +09:00]] 版) <http://dev.w3.org/csswg/css-syntax/>
-- [34] [CITE@en[CSS Syntax Module Level 3]] ([TIME[2014-09-05 21:35:03 +09:00]] 版) <http://dev.w3.org/csswg/css-syntax/#parse-grammar>
]REFS]

* 文字符号化の処理

[41] [[CSSにおける文字コード]]参照。

* 入口点

[5] [[css-syntax]] ではいくつかの[RUBYB[[[入口点]]]@en[entry point]] (構文解析器の動作開始点) を定義しています。
[FIG(list)[
- [15] [[スタイルシート]] / [[parse a style sheet]]
-- [[外部スタイルシート]]
-- [CODE(HTMLe)@en[[[style]]]] [[要素]]
- [16] [[規則リスト]] / [[parse a list of rules]]
- [17] [[規則]] / [[parse a rule]]
-- [CODE(DOMm)@en[[[insertRule]]]]
-- [CODE(DOMi)@en[[[CSSRule]]]] [CODE(DOMa)@en[[[cssText]]]]
- [18] [[宣言]] / [[parse a declaration]]
- [19] [[宣言リスト]] / [[parse a list of declarations]]
- [20] [[構成値]] / [[parse a component value]]
- [21] [[構成値リスト]] / [[parse a list of component values]]
]FIG]

[6] この他にも次のような[[入口点]]があります。
[FIG(list)[
- [22] [[選択子群]] / [[parse a group of selectors]] / [[parse a selector]]
-- [CODE(DOMa)@en[[[selectorText]]]]
-- [CODE(DOMm)@en[[[querySelector]]]], [CODE(DOMm)@en[[[querySelectorAll]]]]
-- >>21 を特定の文法に従い解釈するもの
- [23] [[相対選択子]] / [[parse a relative selector]]
-- [CODE(DOMm)@en[[[find]]]], [CODE(DOMm)@en[[[findAll]]]]
-- [CODE(DOMm)@en[[[matches]]]]
-- >>21 を特定の文法に従い解釈するもの
- [24] [[ページ選択子リスト]] / [[parse a list of CSS page selectors]]
-- [CODE(DOMi)@en[[[CSSPageRule]]]] [CODE(DOMa)@en[[[selectorText]]]]
-- >>21 を特定の文法に従い解釈するもの
- [25] [[媒体クエリーリスト]] / [[parse a media query list]]
-- [CODE(HTMLa)@en[[[media]]]] [[属性]]
-- [CODE(DOMa)@en[[[mediaText]]]]
-- [CODE(DOMi)@en[[[CSSMediaRule]]]] [CODE(DOMa)@en[[[conditionText]]]]
-- >>21 を特定の文法に従い解釈するもの
- [26] [[媒体クエリー]] / [[parse a media query]]
-- [CODE(DOMm)@en[[[appendMedium]]]]
-- >>25 で[[媒体クエリー]]1つの指定のみ受け付けるもの
- [27] [[CSS宣言ブロック]] / [[parse a CSS declaration block]]
-- [CODE(HTMLa)@en[[[style]]]] [[属性]]
-- [CODE(DOMi)@en[[[CSSStyleDeclaration]]]] [CODE(DOMa)@en[[[cssText]]]]
-- >>19 で[[宣言]]を[[プロパティー]]の指定として解釈するもの
- [28] [[特性値]] / [[parse a CSS value]]
-- [CODE(DOMm)@en[[[setProperty]]]]
-- [CODE(DOMi)@en[[[CSSStyleDeclaration]]]] の [[CSS特性]]を[[反映]]する[[属性]]
-- [[SVG]] の [[CSS特性]]に対応する[[表現的属性]]
-- [CODE(XMLe)@en[[[animate]]]] ([CODE(XMLa)@en[[[attributeType]]]] [CODE(XML)@en[[[CSS]]]])
-- >>21 を特定の文法に従い解釈するもの
- [29] [[対応条件]]
-- [CODE(DOMi)@en[[[CSSSupportsRule]]]] [CODE(DOMa)@en[[[conditionText]]]]
-- [CODE(JS)@en[[[CSS.supports]]]]
-- >>21 を特定の文法に従い解釈するもの
- [30] [CODE(CSS)@en[[[<color>]]]]
-- [CODE(DOMa)@en[[[fillStyle]]]], [CODE(DOMa)@en[[[strokeStyle]]]], [CODE(DOMm)@en[[[addColorStop]]]], [CODE(DOMa)@en[[[shadowColor]]]], [[meta-theme-color]]
--- [[parse a CSS <color> value]] = >>20 を特定の文法に従い解釈するもの
-- [CODE[<link color>]]
--- [[仕様書]]なし
- [31] >>35 + [CODE(CSS)@en[<'[[font]]'>]]
-- [CODE(DOMi)@en[[[DrawingStyle]]]] [CODE(DOMa)@en[[[font]]]]
- [32] [CODE(CSS)@en['[[cursor]]']]
-- [CODE(DOMm)@en[[[addHitRegion]]]]
- [33] [CODE(CSS)@en[[[<source-size-list>]]]] / [[valid source size list]] / [[parse a sizes attribute]]
-- [CODE(HTMLe)@en[[[picture]]]] の [CODE(HTMLe)@en[[[source]]]] の [CODE(HTMLa)@en[[[sizes]]]]
-- >>21 を特定の文法に従い解釈するもの
- [40] [CODE(CSS)@en[<filter-function-list>]]
-- [CODE(HTMLe)@en[canvas]] の [CODE(DOMa)@en[filter]]
]FIG]

[35] [[css-syntax]] には [DFN[[[parse something according to a CSS grammar]]]]
という手順が定義されており [SRC[>>34]]、他の仕様書から [[CSS]]
系の文字列の構文解析を行う際に呼び出されます [SRC[>>36]]。入力は[[文字列]]、[[字句]]の列、
[[component value]] の列のいずれかです。出力は構文に依存する構文解析結果か、
失敗かのいずれかです。この手順が呼び出されると、 >>21 により構文解析し、
その結果得られた [[component value]] を指定された[[文法]]により処理します。

* スタイルシートの読み込みと DOM

[7] [[CSSOM]] へは [CODE(DOMa)@en[[[sheet]]]] [[属性]]からアクセスできますが、 [[HTML]] [[DOM]] とは異なり読み込み途中の状態にはアクセスできないようです。

[8] [[スタイルシート]]には [[style sheet ready]] フラグ [SRC[<http://www.whatwg.org/specs/web-apps/current-work/#styling>]]
があり、適用の準備ができるまではこのフラグが未設定になっています。具体的にどの時点で準備ができたといえるのか明確にはなっていませんが、
普通に考えれば構文解析が完了してブラウザー内部のデータ構造となり、[[カスケーディング]]の対象となったり、
[[CSSOM]] のオブジェクトとして利用可能になったりした時点でしょう。

[9] 通常のスタイルシートの場合、 [[style sheet ready]] フラグが設定されるまでは[[スクリプト]]の実行がブロックされます。
[[代替スタイルシート]]ではブロックされません。 ([[WinIE10]] では[[代替スタイルシート]]でもブロックされます。)
なので[[スクリプト]]から [[CSSOM]] にアクセスしようとしても、完全な [[CSSOM]] が返されるか、
[CODE[[[null]]]] が返されるかのどちらかのようです。

* 歴史

[12] [[CSS1]] と [[CSS2]]、さらに 2000年代までの [[CSS3]] ([[css3-syntax]]) では [[Flex]] と [[Yacc]]
により[[形式的]]に構文が記述されていましたが、[[参考]]であり、また様々な制約から不正確でした。
[[規定]]としては英語で構文および[[前方互換構文解析規則]]が説明されており、また各[[特性]]の値は専用の文法記述方法が用いられていました。

[14] このように構文と構文解析に関する規定が詳細に説明されているだけでも当時としては十分先進的ではありましたが、
[[Flex]] によって記述された字句化とよりマクロな構文の対応関係が不明瞭で [CODE(CSS)[[[<an+b>]]]]
のような災厄をもたらしたり、[[前方互換構文解析規則]]の細部が不明確であったりというような問題を抱えていました。

[REFS[
- [13] [CITE@en[Grammar of CSS 2.1]] ([TIME[2011-06-07 13:09:52 +09:00]] 版) <http://www.w3.org/TR/CSS21/grammar.html>
]REFS]

** 状態機械の仕様化

[REFS[
-[1] [CITE[IRC logs: freenode / #whatwg / 20120409]]
( ([TIME[2012-04-15 13:32:46 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20120409#l-406>
]REFS]

[2] 2012年の春になって、ようやく [[css3-syntax]] で [[HTML5]] 
仕様風の[[字句化器]]と[[木構築器]]からなる[[状態機械]]として[[構文解析]]の挙動が明確に記述されるようになりました。

[3] [CITE[tabatkins/css-parser]]
( ([TIME[2012-08-05 15:02:04 +09:00]] 版))
<https://github.com/tabatkins/css-parser>

[REFS[
- [36] [CITE@en[Bug 26208 – For parsing CSS <color> values, this should explicitly ref the CSS Syntax spec, and use the "parse a component value" algorithm defined there.]] ([TIME[2014-09-22 05:53:02 +09:00]] 版) <https://www.w3.org/Bugs/Public/show_bug.cgi?id=26208>
- [37] [CITE@en[Web Applications 1.0 r8793 Better reference CSS for parsing according to CSS.]] ([TIME[2014-09-20 04:21:00 +09:00]] 版) <https://html5.org/r/8793>
- [38] [CITE@en[Web Applications 1.0 r8796 Fix recent CSS-related wording to be more precise.]] ([TIME[2014-09-20 06:25:00 +09:00]] 版) <https://html5.org/r/8796>
]REFS]

[39] [CITE@en[Minutes Sydney F2F 2015-02-08 Part I: CSS Parser]]
([[Dael Jackson]] 著, [TIME[2015-03-04 04:22:47 +09:00]] 版)
<https://lists.w3.org/Archives/Public/public-houdini/2015Mar/0008.html>

[42] [CITE@en[1422951 - Add a CSS-parsing WebExtensions API]]
([TIME[2017-12-21 00:56:16 +09:00]])
<https://bugzilla.mozilla.org/show_bug.cgi?id=1422951>

[43] [CITE@en[Clarify the definition of addColorStop()]]
([[Ms2ger]]著, [TIME[2018-01-10 18:42:20 +09:00]])
<https://github.com/whatwg/html/commit/cc508ebd8427dd561ed2dc3d5d9a45a967fccf71>

[44] [CITE@en[Clarify the definition of addColorStop by Ms2ger · Pull Request #3308 · whatwg/html]]
([TIME[2018-02-12 13:14:20 +09:00]])
<https://github.com/whatwg/html/pull/3308>