Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C liability, trademark and document use rules apply.
この仕様書は、スコープ付きスタイルや@scope規則、Shadow DOMセレクタ、ページ/領域ベースのスタイリングなど、CSSの様々なスコーピング/カプセル化メカニズムを定義します。 CSSは、構造化文書(HTMLやXMLなど)のレンダリングを画面、紙、音声などで記述するための言語です。
このセクションは、公開時点での本書のステータスについて説明します。他の文書が本書に取って代わる場合があります。現在のW3C出版物およびこの技術レポートの最新版は、W3C技術レポート一覧 http://www.w3.org/TR/で確認できます。
本書は最初の公開ワーキングドラフトです。
最初の公開ワーキングドラフトとしての公開は、W3C会員による承認を意味しません。これはドラフト文書であり、随時更新・差し替え・廃止される可能性があります。本書を進行中の作業以外として引用するのは不適切です。
本仕様の議論には、(アーカイブ)のパブリックメーリングリストwww-style@w3.org(案内参照)が推奨されます。メール送信時は件名に「css-scoping」と入れてください。推奨例:「[css-scoping] …コメント要約…」
この文書はCSS作業グループ(スタイル活動の一部)によって作成されました。
この文書は、2004年2月5日 W3C特許ポリシーの下で運用されているグループによって作成されました。W3Cは、グループの成果物に関連して行われた特許開示の公開リストを管理しています。そのページには特許開示の方法も記載されています。ある特許が必須請求項を含むと信じる合理的根拠がある場合、W3C特許ポリシー第6節に従って情報を開示しなければなりません。
...
スコープ付きスタイル規則は、ドキュメント全体ではなく、ドキュメントの部分木内のみに適用されます。 スコーピングには主に2つの効果があります:
スタイル規則は、ドキュメント言語で定義された構造や、CSSの@scope規則を使ってスコープ化できます。
ドキュメント言語は、スタイルシートをドキュメント内の特定要素にスコープする仕組みを定義できる場合があります。 例えばHTMLでは、style要素にscoped属性を付けることで、そのスタイルシートをstyle要素の親要素にスコープします。 [HTML]
@scopeアットルールは、著者がCSS構文でスコープ付きスタイル規則を作成できるようにします。 @scope規則の構文は次のとおりです:
@scope <selector> {
<stylesheet>
}
ここで<selector>でマッチした要素がスコーピングルートとなり、<stylesheet>内のスタイル規則に対して適用されます。また、@scopeでスコープされたスタイル規則のセレクタは、自身のスコーピングルートにスコープ制限されます。
この規則により、著者がスコープ付きスタイルシートを非常に簡単に作成できるため、スコープ付きスタイルの実装における最適化戦略へ影響する可能性があります。
複数の要素が<selector>にマッチした場合、<stylesheet>はそれぞれ独立して複製され、個別にスコープされます。 著者は、あまりにも一般的なセレクタの利用を避けるべきです。なぜならカスケードとの相互作用で混乱が生じる可能性があるためです。
@scope div {
span {
color: blue;
}
}
@scope section {
span {
color: orange;
}
}
そして次のドキュメント断片があった場合
<div>
<section>
<div>
<span>text</span>
</div>
</section>
</div>
テキストは青色になります。
@scope規則はネストできます。 この場合、ネストしたスタイル規則と同様に、外側の@scopeのセレクタが、内側のものをスコープで包含します。
@scope規則内のセレクタの詳細度(specificity)はローカルに計算されます。スコーピング要素を指定するセレクタは無視されます。ただし、スコープ付きスタイルは非スコープ付きスタイルよりも優先されるため、@scope内のスタイル規則は外側の規則を上書きします。
@scope aside {
p { color: green; }
}
aside#sidebar p { color: red; }
複数の@scope規則が要素に適用された場合、それらは詳細度でカスケードされるべきでしょうか?
スコープ付きスタイルシート内では、:scope疑似クラス([SELECTORS4]で定義)は、スコーピングルートにマッチします。
しかし、スコープ付きスタイルシートでは、ツリー外部に対して単一の複合セレクタではなく、複雑なセレクタでマッチさせたい場合もあるため、構文上ツリー要素の順序を反転しない、より一般的な仕組みを使う方がよいかもしれません。
考えられる案:
:scope-context(<selector>) div {...} scope(<selector>) div {...} \scope <selector>\ div {...} <selector> \scope\ div {...}
この機能は、セレクタとしては適切でない@globalを置き換えることになります。
Shadow DOM仕様は、DOMにいくつかの新しい概念を追加しており、そのうちいくつかはCSSと関連します。
シャドウツリーは、DOM内のどんな要素にもアタッチできるドキュメントフラグメントです。 シャドウツリーのルートはシャドウルートであり、これはシャドウホストに関連付けられる非要素ノードです。 1つの要素は任意の数のシャドウツリーを持つことができ、それらは作成順に並びます。 ある要素の直近で作成されたシャドウツリーが、その要素にとってのアクティブシャドウツリーです。
シャドウツリーを持つ要素はシャドウホストです。 それは自身のシャドウツリーに対してのホスト要素となります。
シャドウホストの子孫は、フォーマットツリーでボックスを生成してはなりません。 代わりに、アクティブシャドウツリーの内容が、その要素の内容であるかのようにボックスを生成します。
シャドウDOM内では、要素が要素の親を持たない場合があり(その代わり親がシャドウルートなどの場合があります)、親を持たない、または親が要素でない要素はトップレベル要素と呼ばれます。
シャドウホストの子は通常ボックスを生成しませんが、明示的にシャドウツリーへ引き込んで通常通りレンダリングさせることができます。 これは要素を配布リストに割り当てることで行います。 配布リストを持つ要素は挿入ポイントとなります。
この仕様では、要素を配布リストへ割り当てる方法は定義せず、それはShadow DOM仕様に委ねています。 この仕様の執筆時点では、content要素だけが、シャドウツリー内で配布リストを持つことができます。
挿入ポイント自身はボックスを生成してはなりません。 代わりに、その配布リスト内の要素が通常通りボックスを生成し、すべての要素が挿入ポイントの位置に置き換えられるかのように振る舞います。 (これはdisplay-box: contentsの動作に似ています。)
要素ツリー内の要素は、さらに0個以上のシャドウツリーおよび0個または1個の配布リストを持ちます。
注: 要素の「子孫」は、その要素の子を基準にしています。シャドウツリーや配布リストは含みません。
セレクタがシャドウツリーに対してマッチングされるとき、初期セレクタマッチリストは、シャドウホスト、続いてシャドウツリーのすべてのトップレベル要素とその子孫(先行順で並ぶ)となります。
シャドウホストは、自身がホストするシャドウツリーの外部にありますが、時にはシャドウツリーの文脈からそれをスタイルしたい場合があります。
セレクタの観点では、ホスト要素もまた、それぞれのシャドウツリー内に現れ、そのシャドウツリーの内容が子として扱われます。 要素が複数のシャドウツリーを持つ場合、それぞれのシャドウツリーの文脈で独立して現れます。 各シャドウツリーは自身の内容だけをホスト要素のものとして扱い、他のシャドウツリーは見えません。
ホスト要素は、あらゆる手段でも選択できず、例外は:hostと:host-context()疑似クラスのみです。 つまり、この文脈でシャドウホストはタグ名、ID、クラス、属性を持たず、追加情報は:host疑似クラスが一致することだけです。 特に、ホスト要素は*セレクタでもマッチしません。
シャドウホストはシャドウツリーの外部に存在し、そのマークアップはコンポーネント作者ではなくページ作者の管理下にあります。
もしコンポーネントがシャドウツリー内で特定のクラス名を使い、ページ作者が偶然同じクラス名をホスト要素に付けてしまった場合、コンポーネント作者が予想できず、ページ作者もデバッグが困難な、意図しないスタイリングが発生してしまいます。
とはいえ、シャドウツリー内のスタイルシートが自分のホスト要素をスタイルしたい合理的なユースケースもあります。 そのため、この状況を許容しつつ、意図しないスタイリングを防ぐために、ホスト要素はまったく特徴のないものとして現れ、:host以外では選択できません。
Shadow DOMは、Shadow DOMに関係した要素を便利に選択できる新しいセレクタをいくつか定義しています。
このセクションはまだ議論中です。 以下の機能の直感的な構文について、フィードバックや提案を歓迎します。
:host疑似クラスは、シャドウツリーの文脈で評価された場合、そのシャドウツリーのホスト要素にマッチします。 他の文脈では何にもマッチしません。
:host( <compound-selector> )
シャドウツリーの文脈で評価された場合、シャドウツリーのホスト要素が、通常の文脈でセレクタ引数にマッチした場合に一致します。 それ以外の文脈では、何にもマッチしません。
<x-foo class="foo">
<"shadow tree">
<div class="foo">...</div>
</>
</x-foo>
シャドウツリー内のスタイルシートでは:
<x-foo>要素にマッチします。
<div>要素のみにマッチします。
<x-foo>要素にマッチします。
通常、シャドウツリー内のセレクタは、シャドウツリー外の要素を参照できません。 しかし、時にはシャドウツリーの外側で上位にある祖先要素を選択できると便利な場合があります。
:host-context()関数疑似クラスは、シャドウツリー外に条件を満たす祖先が存在するかどうかを判定します。 構文は次の通りです:
:host-context( <compound-selector> )
シャドウツリーの文脈で評価された場合、:host-context()疑似クラスは、ホスト要素またはその祖先のいずれかが指定された<compound-selector>にマッチすれば、ホスト要素にマッチします。 この疑似クラスにおける「祖先」は次の通りです:
注: これは、セレクタが引数にマッチする要素を探しながらシャドウ境界を貫通して上へたどり、ドキュメントルートに到達するまで繰り返すことを意味します。
要素が1つでもシャドウツリーを持つ場合、::shadow疑似要素はシャドウルート自体にマッチします。 HTMLにおいて、シャドウルートはShadowRootオブジェクトによって表現されます。
::shadow疑似要素は、他の仕様で特に指定されていない限り、ボックスを生成してはなりません。 ただし、セレクタの観点では、::shadow疑似要素はシャドウツリーのルートと見なされ、シャドウツリー内のトップレベル要素が::shadow疑似要素の直接の子となります。
<x-foo>
<"shadow tree">
<div>
<span id="not-top">...</span>
</div>
<span id="top">...</span>
</>
</x-foo>
外部ドキュメントのスタイルシートでは、 x-foo::shadow > spanは #topにマッチしますが、 #not-topにはマッチしません。 これは、#not-topがシャドウツリーのトップレベル要素ではないためです。
#not-topを対象にしたい場合、x-foo::shadow > div > spanなどと書くこともできます。 しかし、これはコンポーネントの内部構造に強く依存するため、通常は x-foo::shadow span のように子孫結合子を使って、シャドウツリー内のある型のすべての要素を選択する方が良いでしょう。
同様に、シャドウツリー内で :host::shadow div のようなセレクタは、その要素上のすべてのシャドウツリー内の div要素を選択し、 そのセレクタを含むシャドウツリーだけでなく、すべてに適用されます。
::content疑似要素は、配布リストを持つ要素において、その配布リスト自体にマッチします。
::contentは、シャドウツリーの投影コンテンツ専用であるにもかかわらず、やや一般的過ぎる名前です。
::content疑似要素は、他の仕様で特に指定されていない限り、ボックスを生成してはなりません。 ただし、セレクタの観点では、::content疑似要素は、配布リスト内の要素たちの親と見なされます。
<x-foo>
<div id="one" class="foo">...</div>
<div id="two">...</div>
<div id="three" class="foo">
<div id="four">...</div>
</div>
<"shadow tree">
<div id="five">...</div>
<div id="six">...</div>
<content select=".foo"></content>
</"shadow tree">
</x-foo>
シャドウツリー内のスタイルシートでは、 ::content div のようなセレクタは、#one、#three、および#fourを選択します。 これらは唯一のcontent要素によって配布されている要素だからです。一方で#twoは選択されません。
トップレベル要素によって配布されたcontent要素のみを対象にしたい場合は、子結合子を使うことができます。たとえば ::content > div のように書くと、#four は::content疑似要素の子と見なされないため除外されます。
注:::content divのようなセレクタは、*::content divと等価です。 *はcontent要素以外も多く選択し得ますが、content要素だけが配布リストを持つため、実際に::content疑似要素を持つのはcontent要素だけです。
セレクタ内で/deep/結合子が現れた場合、 セレクタマッチリスト内のすべての要素を 元の要素から子リストやシャドウツリーを任意回数たどって到達可能なすべての要素で置き換えます。
<x-foo>
<"shadow tree">
<div>
<span id="not-top">...</span>
</div>
<span id="top">...</span>
<x-bar>
<"shadow tree">
<span id="nested">...</span>
</>
</x-bar>
</>
</x-foo>
外部ドキュメントのスタイルシートでは、
x-foo /deep/ span
のセレクタは、3つすべての<span>要素、
#top、#not-top、および#nestedを選択します。
これは基本的にスーパー子孫結合子です。
子孫結合子に本当の記号があれば、それを単純に2つ重ねるのも面白いかもしれません。
子孫結合子に>>の別名をつけてもいいかもしれませんが、これはスーパー子結合子なのでしょうか?
すると/deep/は>>>と書けるかもしれません。
シャドウルート内要素を対象とする規則の期待されるカスケード動作に対応するため、本仕様はカスケード仕様で定義されたカスケード順序を拡張します。[CSS3CASCADE]
オリジンとスコープの間に「シャドウツリー」という追加のカスケード基準を挿入する必要があります。
注:これはスコープ付きスタイルの挙動とは逆です。
出現順の計算時には、Shadow DOM仕様で定義されたツリー構造を使って順序を決定します。
シャドウツリーのトップレベル要素は、自身のホスト要素から継承します。
配布リスト内の要素は、最終的に配布されるcontent要素の親から継承し、通常の親からは継承しません。
フラグメント化されたコンテンツは、その出現する行・列・ページ・領域などに応じて異なるスタイルを適用できます。 これは、適切なフラグメント疑似要素を使うことで実現でき、要素全体ではなく個々のフラグメントをターゲットできます。
#region1::region p {
color: #0C3D5F;
font-weight: bold;
}
この例では、::region疑似要素の後にpの相対セレクタが来ています。 color および font-weight の宣言は、#region1内に表示される段落のフラグメントすべてに適用されます。 次の図は、#region1専用のスタイルを適用した場合のレンダリングの違いを示しています。 font-weightがnormalではなくboldになったことで、 このボックスに入るテキスト量が減ったことに注目してください。
注:この機能は::first-lineスタイリングの拡張です。
::region 疑似要素は、CSS Regionにマッチするセレクタと、特定の名前付きフロー内のコンテンツのフラグメントにマッチする相対セレクタとの関係を表します。 これにより、特定の領域に流れ込む名前付きフローのフラグメントに対してスタイル宣言を適用できます。
<region selector>::region <content selector> {
... CSS styling declarations ...
}
::region 疑似要素が1つ以上のCSS Regionsにマッチする セレクタに付加されると、 これは「フローフラグメント」セレクタを作成します。 フローフラグメントセレクタは、相対セレクタがマッチできるフロー内の要素の範囲を指定します。 相対セレクタは、選択された領域に部分的または完全に表示される名前付きフローの範囲内の要素にマッチできます(詳細は[DOM]を参照)。
フローフラグメント範囲に部分的または完全に含まれる要素は、相対セレクタにマッチする可能性があります。 ただし、スタイル宣言は対応する領域に表示されるその要素のフラグメントにのみ適用されます。
::region 疑似要素に適用されるプロパティは限定されたリストのみです:
このリストは機能的に継承可能なすべてのプロパティ、あるいはすべてのプロパティであるべきです。 なぜボックスプロパティを含むような、任意に見える部分集合なのか?
次の例では、名前付きフロー “article-flow” が “region-1” と “region-2” に流れ込みます。
<style>
#div-1 {
flow-into: article-flow;
}
#region-1, #region-2 {
flow-from: article-flow;
}
/* region styling */
#region-1::region p {
margin-right: 5em;
}
</style>
<body>
<div id="div-1">
<p id="p-1">...</p>
<p id="p-2">...</p>
</div>
<div id="region-1"></div>
<div id="region-2"></div>
</body>
領域スタイリングは、region-1 に収まるフローコンテンツに適用されます。 相対セレクタは、これらの段落が region-1 に流れ込むため、 p-1 と p-2 にマッチします。 p-2 のうち region-1 に流れ込むフラグメントだけが疑似要素によってスタイルされます。
::region 疑似要素内のすべてのセレクタはその特異性に寄与します。 したがって、上の例の ::region 疑似要素の特異性は、id セレクタの特異性と型セレクタの特異性を組み合わせた、101 になります。
特定の要素または要素フラグメントにマッチするセレクタ(上記の説明に従う)は、 CSS カスケーディング順序([CSS21]で定義)に従って扱われます。
特定の領域におけるフラグメントのスタイルを照会する方法が必要になります。
getComputedStyle() だけでは不十分です。
なぜなら要素は複数の領域に存在し得て、それぞれのフラグメントが異なるスタイルを受ける可能性があるからです。
適合要件は、記述的な主張と RFC 2119 用語の組み合わせで表現されます。規範部分におけるキーワード "MUST"、"MUST NOT"、"REQUIRED"、"SHALL"、"SHALL NOT"、"SHOULD"、"SHOULD NOT"、"RECOMMENDED"、"MAY"、および "OPTIONAL" は RFC 2119 に従って解釈されます。 ただし、可読性のために本仕様ではこれらの語をすべて大文字で表記していない場合があります。
この仕様の本文は、明示的に非規範とマークされた節、例、およびノートを除き、すべて規範的です。[RFC2119]
本仕様の例は "for example" という語で導入されるか、または規範テキストから class="example" で区別されます。次のように:
これは情報的な例の例です。
情報的なノートは "Note" という語で始まり、class="note" で規範テキストと区別されます。
注:これは情報的なノートです。
本仕様への適合性は3つの適合クラスで定義されます:
スタイルシートは、本モジュールで定義された構文を使用するすべての記述が、汎用の CSS 文法および各機能の個別文法に従って有効である場合、本仕様に適合します。
レンダラーは、適切な仕様によって定義された通りにスタイルシートを解釈することに加えて、本仕様で定義されたすべての機能を解析して正しくレンダリングすることで、本仕様に適合します。ただし、機器の制限により文書を正しくレンダリングできないことは、UA を非適合にしません(例えば、モノクロモニタで色をレンダリングする必要はありません)。
オーサリングツールは、本モジュール内の各機能の汎用 CSS 文法および個別文法に従って構文的に正しいスタイルシートを書き、本モジュールで説明されたスタイルシートの適合要件を満たす場合に本仕様に適合します。
著者がフォワードコンパチブルなパース規則を利用してフォールバック値を割り当てられるように、CSS レンダラーはサポートがない at-rule、プロパティ、プロパティ値、キーワード、その他構文構成を無効として扱い(適切に無視する)必要があります。特に、UA はサポートされていない構成値を部分的に無視して、同じ多値プロパティ宣言内のサポートされている値だけを適用してはなりません:いずれかの値が無効と見なされる場合、CSS はその宣言全体を無視することを要求します。
将来の CSS 機能との衝突を避けるため、CSS2.1 仕様はプロプライエタリおよび実験的拡張のためにプレフィックス付き構文を予約しています。
仕様が W3C の Candidate Recommendation ステージに達する前は、CSS 機能のすべての実装は実験的と見なされます。CSS 作業部会は、実装者に対してワーキングドラフトの機能を含むような実験的機能についてはベンダープレフィックス付き構文を使用することを推奨します。これにより、ドラフトの将来の変更による非互換を回避できます。
仕様が Candidate Recommendation ステージに達すると、非実験的な実装が可能になり、実装者は CR レベルの機能を仕様に従って正しく実装したことを示せる場合、プレフィックスなしの実装を公開するべきです。
CSS の相互運用性を確立・維持するため、CSS 作業部会は非実験的な CSS レンダラーがプレフィックスなし実装を公開する前に実装レポート(必要ならその実装レポートに使用したテストケース)を W3C に提出することを要請します。W3C に提出されたテストケースは、CSS 作業部会によるレビューと修正の対象となります。
テストケースと実装レポートの提出に関する詳しい情報は、CSS 作業部会のウェブサイト(http://www.w3.org/Style/CSS/Test/)を参照してください。質問は public-css-testsuite@w3.org 宛てに行ってください。
定義されたプロパティはありません。
しかし、スコープ付きスタイルシートでは外部ツリーに対して複雑なセレクタをマッチさせたい場合もあるため、要素の順序を構文的に反転させない、より一般的な仕組みを代わりに使うべきかもしれません。
考えられる案:
:scope-context(<selector>) div {...} scope(<selector>) div {...} \scope <selector>\ div {...} <selector> \scope\ div {...}
この機能は、セレクタとしては適切でない @global を置き換えることになります。
↵>> の別名をつけることも考えられますが、そうすると /deep/ は >>> と書けるかもしれません。
↵
getComputedStyle() だけでは不十分です。
なぜなら要素は複数の領域に存在し得て、それぞれのフラグメントが異なるスタイルを受ける可能性があるからです。
↵