段階化の順序
Updated / Published
ユーザは User Agnet(ユーザエージェント)の設定で制作者スタイルシート, ユーザスタイルシート, デフォルトスタイルシートの中から好みのレイアウトを選択することができます。UA の中でも視覚環境のものはデフォルトのスタイルシートを内蔵しており、(X)HTML文書をレンダリング(描画)する際にそのスタイル情報を当てはめています。そして、制作者スタイルシートやユーザスタイルシートは、その UA のデフォルトのスタイルシートを上書きすることができます。どのスタイルシートもセレクタと宣言ブロックのルールセットがいくつも並べられた、順序立てられたリストの構成になっています。
Cascading Style Sheets の Cascade とは順序立てられたリストのスタイルシートという意味から名付けられたもので、スタイルシートが段階的に継承していく働きを表しています。そして、順序立てられたリストの中で記述されている位置やセレクタの違いにより、段階化の順序(スタイル情報が反映される優先順位)は異なってきます。
3種類のスタイルシートにおける優先順位
CSS には制作者スタイルシート, ユーザスタイルシート, デフォルトスタイルシートの3つがあります。視覚環境の UA の環境設定では、どのスタイルシートを文書のレイアウトに当てはめるかを設定することができますが、特に指定がなければデフォルトではユーザスタイルシートよりも制作者スタイルシートの方が優先順位が上で、さらに制作者スタイルシートとユーザスタイルシートは、視覚環境の UA が内蔵しているデフォルトスタイルシートよりも優先順位が高くなります。つまり、3種類のスタイルシートを同時にレイアウトに当てはめた場合、デフォルトスタイルシートはユーザスタイルシートと制作者スタイルシートに上書きされ、ユーザスタイルシートは制作者スタイルシートの上書きされて反映されることになります。
たとえば、デフォルトスタイルシートの文字色が black
でも、ユーザスタイルシートで white
が指定されている場合、デフォルトスタイルシートの black
の指定は、ユーザスタイルシートの white
の指定によって上書きされます。さらに、そこに制作者が文書内にスタイルシートを組み込んでいて、文字色に red
の指定を行っている場合、ユーザスタイルシートの white
の指定は、制作者スタイルシートの red
の指定によって上書きされ、最終的な文字色は red
が反映されることになります。
スタイルシートの適用タイプにおける優先順位
CSS概論では、CSS のスタイル情報を (X)HTML文書に適用する方法として主な3通りの方法を紹介しましたが、ここではさらに @import
を使った方法を紹介します。計4つの方法の中で、スタイルの指定が上書きされる優先順位は次の通りです。
- 適用させる要素に対して、
style
属性を追加して直接スタイル情報を指定する(優先順位:最高) - 適用させる文書の
head
要素内に、style
要素を使ってスタイル情報を記述する(優先順位:高い) - link要素で (X)HTML文書とスタイルシートのファイルとを連結させる(優先順位:低い)
style
要素や外部のスタイルシートファイルの中で @import を使って、別のスタイルシートのファイルを参照させる(優先順位:最低)
たとえば、次のような(X)HTML文書があるとします。
<head>
<style type="text/css">
@import 'color_black.css';
</style>
<link rel="stylesheet" type="text/css" href="color_white.css" />
<style type="text/css">
body { color : red ; }
</style>
</head>
<body style="color : blue ; ">
...
</body>
まず最初にlink
要素で参照した CSSファイルの中に @import
でさらに別の CSSファイルを参照しており、そこに body
要素型名をセレクタに文字色を black
に指定していたとします。この指定は、link
要素で参照した CSSファイルに文字色を white
にする指定があった場合に、@import
で参照した CSSファイルにある black
の指定は、link
要素で参照した CSSファイルの white
の指定によって上書きされます。さらに、文書のhead
要素内に style
要素で直接スタイル情報を組み込んでいて、文字色を red
に指定しているので、link
要素で参照したスタイルシートの white
の指定は、style
要素内に記述されている red
の指定によって上書きされます。その上さらに body
要素に対して直接、style
属性で文字色が blue
に指定されているので、style
要素内に記述されている red
の指定は、body
要素に直接指定されている style
属性の blue
の指定によって上書きされ、当該文書における最終的な文字色は blue
が反映されることになります。
リストの中での位置における優先順位
Cascading Style Sheets の Cascade とは順序立てられたリストという意味であるように、セレクタと宣言ブロックのルールセットをいくつも並べたリストの中で、同一のセレクタがある場合は、リスト内であとに並べられているものほど優先され、その指定が上書きされます。つまり、リストの中で位置が後になっている指定ほど、優先順位が高くなります。
h1 { color : black ; }
h1 { color : red ; }
h1 { color : blue ; }
この例では、一番後に記述されている "h1 { color : blue ; }
" の指定が優先され、h1
要素の文字色は最終的に blue
が上書きされて、表示に反映されます。
セレクタ(selector)における優先順位
セレクタ(selector)が具体的であればあるほど、スタイル情報は上書きして反映されます。通常の要素型名だけをセレクタにした場合よりも、特定の要素の子要素としてセレクタにした場合や、class
属性や id
属性で同じ要素型名でも詳細な区分けが行われたセレクタほど優先順位が高くなります。
ul { color : black ; }
li { color : black ; }
ul li { color : red ; }
li.ex { color : green ; }
.ex { color : blue ; }
li#ex { color : maroon ; }
#ex { color : gray ; }
......
<ul>
<li>ul li { color : red ; } が反映される</li>
<li class="ex">li.ex { color : green ; } が反映される</li>
<li id="ex">li#ex { color : maroon ; } が反映される</li>
</ul>
この例では、ul
要素と li
要素は文字色が black
になっていますが、ul
要素の子要素である li
要素に対して red
の指定があるため、通常の li
要素には red
が反映されることになります。また、ex
というクラス名で具体化することによって、li.ex
要素には green
が反映されます。続いて、li
要素がつけられていない ex
だけのクラス名のセレクタがありますが、li.ex
で指定する方が具体的であるため、li.ex
の指定が優先して反映されます。ID名の部分も同じで、li#ex
要素は maroon
が優先して反映されます。
詳細度
セレクタは具体的であればあるほど、そのセレクタが優先されるのですが、正確には以下の詳細度という値によって決められます。
- 要素に直接指定されている
style
属性を a とする - IDセレクタを数え上げて、その数を b とする
- クラスセレクタと属性セレクタ、擬似クラスを数え上げて、その数を c とする
- 要素型名と擬似要素を数え上げて、その数を d とする
そして、この a, b, c, d の4つの数を順に連結して詳細度とし、その値が大きいほど優先順位が高くなり、指定は上書きされます。
* {} /* a=0, b=0, c=0, d=0, 詳細度 = 0000 */
p {} /* a=0, b=0, c=0, d=1, 詳細度 = 0001 */
p a {} /* a=0, b=0, c=0, d=2, 詳細度 = 0002 */
.class {} /* a=0, b=0, c=1, d=0, 詳細度 = 0010 */
p.class {} /* a=0, b=0, c=1, d=1, 詳細度 = 0011 */
p a[href] {} /* a=0, b=0, c=1, d=2, 詳細度 = 0012 */
a[href]:link {} /* a=0, b=0, c=2, d=1, 詳細度 = 0021 */
#id {} /* a=0, b=1, c=0, d=0, 詳細度 = 0100 */
p#id {} /* a=0, b=1, c=0, d=1, 詳細度 = 0101 */
style="" /* a=1, b=0, c=0, d=0, 詳細度 = 1000 */
なお、全称セレクタの詳細度は 0000 ですが、現在リリースされている UA では通常の要素型名だけの指定では上書きされないので、実際には多くの UA の実装が全称セレクタの詳細度を 0002 以上で計測しているようです。
強制的に優先順位をあげる「!important」
セレクタの詳細度による優先順位やスタイル情報を記述したルールセットがいくつも並べられたリストの中での位置における優先順位に関係なく、強制的に指定のスタイル情報を優先させたい場合には、宣言の値(value)をセミコロン(;
)で閉じる前の部分に "!important
" の文字列を前置します。
ul,li { color : black !important; }
ul li { color : red ; }
li.ex { color : green ; }
.ex { color : blue ; }
li#ex { color : maroon ; }
#ex { color : gray ; }
h1 { color : black !important; }
h1 { color : red ; }
h1 { color : blue ; }
通常の要素型名だけのセレクタに比べて、詳細度の高い具体的なセレクタになる li.ex
要素や li#ex
要素が存在しても、また h1
要素もセレクタやリストの中での位置に関係なく、どちらも宣言の値に "!important
" をもつ black
の文字色が強制的に反映されます。
たとえば、ユーザスタイルシートにて "!important
" を使うことで、制作者スタイルシートで指定されているスタイル情報を上書きすることもできます。