意外と説明できない・・・なぜリンクの色が優先されるのか調べてみた
こんにちは湿気でつやつやてかてかの井畑です。
今回はCSSのリンクの色についてふと疑問に思うことがあったので、調べて記事にしてみました。
調べてみると、何て事はなかったのですが(爆)目から鱗というかなるほどーと思うことだったので、皆さんの脳みそのしわの一つにでもなれば幸いです。
それではどうぞー!
aのリンク色はなぜ親要素から継承されないの?
僕が疑問を持った点を説明します。まずはコチラをご覧ください
<div id="piyopiyo"><a href="#">3連休って何?</a></div>
a { color:#F00; } div #piyopiyo { color:#00F; }
このように記述をするとaのスタイルが優先されて文字色は赤色になります。多くの人はリンクの色を指定したい時は、#piyopiyo aでカラーを指定していると思います。
この記述自体はスーパーよく使うので、なんの疑問も持たずに使っていたのですが、よくよく考えるとこれって不思議だなーと思い始めました。だって優先度的にはdiv #piyopiyoが優先されても良いんじゃないでしょうか。
ん?ちょっと待って、優先度って何?
なぜ井畑がなぜ疑問に思ったのか、分かった方は次にお進みください。
よく分からなかった方は、井畑の考え方と一緒にCSSのおさらいをしてみましょう。
CSSの優先順位を理解してみる
ここでおさえておきたいのはCSSの優先順位についてです。CSSではスタイルを指定しても上手く反映されない場合があります。その理由の一つにCSSの優先順位があります。
基本的なCSSの優先順位
まずは、基本の基本から。スタイルは基本的に、「後から読み込んだスタイルを優先的に適用」していきます。同じセレクタであれば後に書いてあるものが優先されます。
a { color:#FFF; } a { color:#F00; }
以上のようにコードを書くと、下のaのスタイルが優先されて、リンクの色は赤くなります。
CSSの優先順位で覚えておきたいのが、「!important」です。
これを宣言されたスタイルは何よりも最優先で適用されます。全てを無視して適用してくれるため、助けられることも多々あるのですが、スタイルがルールどおり効かなくなる等の不都合も多くなるため多用することはおすすめしません。
a { color:#FFF !imporatnt; } a { color:#F00; }
以上のようにコードを書くと、!imporantが優先されて、リンクの色は白くなります。
CSSの詳細度について
さて、次はちょっと複雑です。以下のコードをごらんください。
<div id="piyopiyo" class="nyannyan"><p class="wanwan"><a>3連休ぇ...</a></p></div>
div#piyopiyo a { color:#FFF; } div.nyannyan p.wanwan a { color:#F00; }
子孫セレクタを使ったスタイルの指定です。これだと一見、長々と書いてあるdiv.nyannyan p.wanwan aの方が適用されそうですが、実際はdiv#piyopiyo aが適用されます。
なぜかというと、CSSには詳細度の高いスタイルを優先して適用させるというルールがあるからです。
詳細度には計算式があり、以下のようになります。
★style 属性がある場合は P とする。
★IDセレクタの数を a とする。
★クラス、疑似クラスレセクタの数を b とする。
★要素、疑似要素セレクタの数を c とする。上記を連結したものを下の式で計算したものを「詳細度」とする。
【計算式】
詳細度 = (P×1000) + (a×100) + (b×10) + (c×1)
この計算式をさっきの記述にあてはめると、
- div#piyopiyo a=100(#piyopiyo)+2(div,a)=102
- div.nyannyan p.wanwan a=20(.nyannyan,.wanwan)+3(div,p,a)=23
となり、div#piyopiyo aが優先されます。
これでCSSの優先順位についてのおさらいはおしまいです。
話をもどして、疑問点を検証してみる
さて、上記の点を押さえた上で、本題に。
もう一度問題の記述を持ってきます。
<div id="piyopiyo"><a href="#">3連休って何?</a></div>
a { color:#F00; } div #piyopiyo { color:#00F; }
ここで、先ほど書いたCSSの詳細度にのっとると、
- a=1(a)=1
- div #piyopiyo=100(#piyopiyo)+1(div)=101
となり、div #piyopiyoのが優先されるのではないか?というところが説明できないのです。
かなーり長くなりましたが、これが僕が疑問に思った流れです。
解決:祖先から継承した指定の詳細度は「なし」という扱い
調べた結果、原因がこちらの記事に書いてありました。
つまり、祖先から継承した指定の詳細度は「なし」という扱いになるということらしいです。
文章だと上手く説明できないので図にしてみました。
div#piypiyo詳細度が効くのはdiv id=”piyopiyo”の直下だけで、その子要素であるaは詳細度がリセットされて0になります。
そして、優先度”1″のaのスタイルがあると、そちらが優先され文字色は赤くなる、ということなのです。
おー。分かってしまえば、何て事はない事でしたw
確かに指定したスタイルの子要素、孫要素にまで詳細度が反映されていくと…色々ややこしいことになりそうですもんね。
上手くできてるんだなーw
とっても参考になりました!
親要素の色をリンク色に継承させるには
ついでに#piyopiyo aのように個別にスタイルを指定しなくても色を指定できる方法を調べてみました。
というか、こちらもメモログさんに答えがのっていました。とっても助かりました!!;D
inheritを使う
以下の記述でリンク色を指定せずに色を指定できます。
<div id="piyopiyo"><a href="#" class="inherit">3連休って何?</a></div>
a { color:#F00; } div #piyopiyo { color:#00F; } .inherit { color: inherit; }
aタグにclass属性を追加し、colorプロパティにinheritを設定すれば、完成。
このinheritは、親要素の値を強制的に継承するので、リンクの色がdiv#piyopiyoで指定した色になります。
上記のように設定すれば、一つずつリンク色を指定しなくて良いのでとてもステキですね!!ただ、やはりというべきでしょうかIE6,IE7では対応していないので注意が必要です。
それにしてもこのinherit…初めて知りましたが、IE6,IE7無視していいなら結構使えそうですね、スタイルの変更時に一カ所変えれば全部変わるとかできそう..;D
最後に
メモログさんも書いていらっしゃいましたが、CSSがよく分からない人にだったら、「より内側にあるタグに指定したCSSの方が、外側のタグに指定したものより有効になるんよ」と伝えても特に問題はなさそうですね。
一つ脳みそのしわが深くなった気がした出来事でした。
こういう豆知識面白いですねーまた思いついたら報告します。
以上井畑でした!
コメントを残す