[CSS]否定疑似クラス「:not」の便利な使い方と使う時の注意点
Post on:2016年3月25日
例えばリストの各アイテムの区切りにボーダーをつける時、まずはli要素にボーダーを指定し、最後のli要素にだけボーダー無しを上書きで指定する、そんなスタイルシートも「:not」を使うと簡単に指定することができます。
否定疑似クラス「:not」の便利な使い方と使う時の注意点(特に優先順位)を紹介します。
以下、各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様に許可を得て翻訳しています。
まずは、「:not」の各ブラウザのサポート状況。
2016年現在、どの環境でも特に問題なく、利用できると思います。
「:not」の便利な使い方
否定疑似クラス「:not」は使い方が分かると、非常に便利です。
この疑似クラスは簡単に言うと、指定した属性を持っていない要素にターゲットを定めることができます。今までは複数行で記述していたコードもシンプルに、そして簡単に記述できます。
よくある例を見てみましょう。
リストの各アイテムの区切りにボーダーをつける時、最後のアイテムだけボーダーを無しにします。
1 2 3 4 5 6 |
/* 今までのコード 「:not」は無し */ li { border-right: 1px solid #000; } li:last-child { border-right: none; } /* 「:not」を使ったコード */ li:not(:last-child) { border-right: 1px solid #000; } |
「:not」を使ったコードは、「:last-child」ではない要素にボーダーを適用しています。
疑似クラス「:not」は、このように非常に便利な使い方ができます。
では、優先順位をつかった疑似クラス「:not」を見てみましょう。
1 2 |
a:not(.ul) { text-decoration: none; } nav a { text-decoration: underline; } |
私がこのコードを書いた時、nav a要素は下線を持っていないことに気がつきました。なぜこのような現象が起きるのか検証したいと思います。
CSSセレクタの優先順位 101
CSSセレクタの優先順位を把握することはなかなか複雑ですが、簡単な例から見ていきます。
1 |
<p class="foo" id="bar">Lorem ipsum dolor sit amet.</p> |
上記のHTMLにスタイルを適用します。
1 2 3 4 |
p { color: red; } .foo { color: green; } #bar { color: blue; } p.foo#bar { color: yellow; } |
同じ要素にターゲットを定めている複数のセレクタがある場合、セレクタの優先順位によって適用される属性が決定されます。その要因は、2つです。
- どんな種類のセレクタが使用されているか。
3種類のセレクタがあります。- idセレクタ(例: #bar)
- classセレクタ(例: .foo, :last-child)
- typeセレクタ(例: p)
- セレクタのそれぞれの種類と数。(例: idセレクタ1つとclassセレクタ1つなど)
この2つの要因を合わせて、セレクタの優先順位が決められます。上記の例を使って、優先順位がどのように計算されるか見てみましょう。
セレクタの優先順位
セレクタを比較する時、まずは最初の値(idセレクタの数)を比較します。idセレクタがより高い値であれば、優先順位も高いということになります。もしidセレクタでその値が等しい場合は、次の値(classセレクタの数)を比較し、さらに等しい場合はtypeセレクタを比較します。
上記の例では、「#bar」が「1-0-0」、「p.foo#bar」が「1-1-0」、idセレクタの値が同じで、classセレクタの値を比較し、優先順位が最も高いセレクタは「p.foo#bar」で、「color: yellow;」が適用されます。
次の例を見てみましょう。
セレクタの優先順位
idセレクタを使用しているセレクタが一つだけなので、classセレクタやtypeセレクタの値は無関係です。「#bar」が適用されます。
メモ
優先順位の計算は定義されたスタイルだけに適用されます。
インラインのスタイルは、すべてのセレクタベースのスタイルに優先されます。
「:not」を含む優先順位
「:not」自身は他の疑似クラスがそうであるように、優先順位の数に何も加えません。しかし、「:not」がセレクタの中にある時はそうではありません。
下記のコードを見てみてください。
1 2 |
p.bar { color: red; } p:not(.foo) { color: green; } |
優先順位において「p:not(.foo)」は、「p」にclassセレクタを加えた状態と同じになります。
「p class="bar"」が、何色になると思いますか? 正しい答えはレッドではなく、グリーンです。
なぜなら「:not」を加えたということは、「p class="bar"」要素に「.notFoo」を加えたことと同じになります。
セレクタの優先順位
「:not」のスタイルは「p.bar」と同じ優先順位になりますが、記述の順番が後なので、「:not」のスタイルが優先されます。
記述の順番を入れ替えると、レッドが適用されます。
1 2 |
p:not(.foo) { color: green; } p.bar { color: red; } |
これは同様に「nav」の例でも説明できます。「:not」はネストされたtypeセレクタに勝ちます。
セレクタの優先順位
idセレクタがあると、ちょっとやっかいです。
p要素にclassセレクタを加えた「p:not(.foo)」と同様に、p要素にidセレクタを加えてみます。
1 2 |
p:not(#foo) { color: green; } p.bar { color: red; } |
今度は何色になると思いますか? 正しい答えは後に指定したレッドではなく、グリーンです。
優先順位を見てみましょう。
セレクタの優先順位
「p.bar」は記述の順番が後に定義されていますが、一つ目の「:not」の方にidセレクタがあるためこのようになります。
「:not」を使う時の注意点
この仕様は私が「:not」を使う方法を再考させました。
「li:last-child」のように、特定のルールを他より優先するよう記述の必要があるように思われますが、「:not」が同じことをするように思われます。
「:not」は多くの状況でスタイルがシンプルに記述できる方法なので、これからも私は使い続けるでしょう。その時には、以下の3つに注意します。
- idセレクタと一緒に使わない(例: :not(#bar))
- 一般的なtypeセレクタとは限定的に(例: div:not(.foo))
- 必要があれば、優先されるように「:not」のスタイルは記述の順番で前に定義する。
sponsors