Twitter Bootstrap を使う際に a:link などに color を設定するとボタンの色まで上書きされちゃう問題の対策
1年ぶりくらいに更新しますが、引き続きクロコスにおりまして (てかこの前の記事が去年の7月なんでその後ヤフーに買収されるなどいろいろあったりしましたが) 、まあまあ元気にやっております。
-
-
- -
-
さて本題。普段 CSS 書くときは大抵、 Twitter Bootstrap からいくつかの LESS をインポートしつつ、必要に応じてスタイルを上書きする形式をとっています。
そんな中、なんかどうしてもボタン(buttons.less でスタイルをあてているやつ)の文字色が反映されない状況に陥りまして、なんでだろうと調べて一応解決したので書いておきます。
問題の概要
今回のケースでは、デフォルトの文字色を次のように設定していました。
@import "bootstrap/buttons.less"; a, a:link { color: #666666; } a:visited { color: #999999; }
Bootstrap では .btn
クラスをつけるとボタンの形式になり、 .btn-primary
のようなボタンに意味を付与するクラスをつけると意味に応じた色がつく、といった仕組みになっています。
/* bootstrap/buttons.less */ .btn { ... } .btn-primary { color: #ffffff; }
で、例えばこの状態で次のようにHTMLがあるとします。
<p><a href="#">いえーい</a></p> <p><a href="#" class="btn btn-primary">いえーい</a></p>
実際にこの状態で画面を見てみると次のようになります。
.btn-primary
を設定しているのに文字色が #ffffff
になっていません。
僕は最初、「CSS は要素よりもクラスの方が優先度が高いはずなので .btn-primary
が適応されないのはおかしい」と思ってしまったのですが、よくよく調べたら擬似クラスもクラスと同じだけ重み付けされるんで、「要素 + 擬似クラス」と「クラス」の差で a:link
などのスタイルが単なるクラスのみの指定である .btn-primary
より優先されてしまった、ということでした。
対策
で、最初は .btn
に疑似クラスや要素をつけて上書きする方法を考えたのですが、無駄な感じでやりたくないなーと思って別の方法を探した結果、否定疑似クラス (:not()
) を使えばもっとも簡単に制御できるという結論にいたりました。
a:not(.btn), a:link:not(.btn) { color: #666666; } a:visited:not(.btn) { color: #999999; }
このようにしておくと .btn
の色に干渉することがなくなるので、デフォルトのボタン色がそのまま使われるようになります。
Bootstrap みたいな CSS フレームワークを用いる際、特定のスタイルに干渉してほしくない場合なんかは :not()
知っておくとよさそうです。