2016.03.28
CSS3 擬似クラス:notで無駄っぽい上書きを減らす
でっかい括りにcssを適用してると、「ほげっ!なんじゃ、このボーダー!」ってことよくあります。
1 |
.side_bar img {border:1px solid #ccc;} |
リセットcssとか使って初めから全体のimgにborder:noneしつつも、どっか大きいとこに一括指定をしてたりします。
んで、サイドバーにウィジェットとか追加してそこのイメージにはボーダーいらんとなると、
1 2 |
.side_bar img { border: 1px solid #ccc; } .side_bar .widget img { border:none; } |
ボーダーを打ち消すcssを書かんとなりません。
しかも他のウィジェットも同じクラス名でimgにボーダーが要るとすると事態は一層の混乱を深めます。
消して、付けて、いらんもの付けて、消すのです。
どうも納得がいかん。
否定擬似クラスぅ?
:notとかいう否定擬似クラスを使って余計な事を書かずに済まそうという魂胆です。
否定擬似クラスは
E:not(セレクタ)
という書式です。
「引数に入れたセレクタ」じゃないやつにスタイルを適用します。
IE8以前のバージョンではやっぱり使えません…。
imgにはだいたいというか絶対srcがあるので:not擬似クラスと属性セレクタを組み合わせるだす。
1 2 3 |
.side_bar img:not([src*="hoge.net"]) { border:1px solid #ccc; } |
ほげネットが配信してる画像以外の画像にボーダーをつける。
src属性に部分一致の*をつけて属性値にhoge.net という文字列があるimg要素をnotしています。
ちまめに、一致の種類は3個だけだけど、わりとなんとかなるような。
img:not([src^="img/hoge"]) /* 前方一致 */
img:not([src$="fooo.png"]) /* 後方一致 */
img:not([src*="hoge.net"]) /* 部分一致 */
:notは並列できます。
1 2 3 |
.side_bar img:not([src*="hoge.net"]):not([src*="hoge_folder"]) { border:1px solid #ccc; } |
記述が長いか長くないかは別として…。
プロパティが多くなるにつれてお得感がでてきます
一行くらいの打ち消しなら、上書きでもいいんですよ。noneでも。
でもすんごく打ち消さなきゃって時、大変じゃないですか。
当ちゅんもす置き場の場合、sidebarの見出しの装飾を全部打ち消そうとする場合大変うざいことになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#side .widget-container h3 { color: #800000; width: 265px; height: 30px; font-size: 85%; line-height: 30px; letter-spacing: .3em; padding-left: 15px; margin: 0 0 12px; background: #fc6; border-radius: 5px; position: relative; box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); } /* .hogegeというクラスをつけて上書きで打ち消すよ */ #side .widget-container h3.hogege { color: #999; width: 100%; height: auto; font-size: 70%; line-height: 1; letter-spacing: 0; padding: 0 0 2px; margin: 40px 0 0; background: none; border-radius: 0; box-shadow: none; } |
はぁ〜、のんのん、うざい。
しかし、:notを使うと!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#side .widget-container h3:not(.hogege) { color: #800000; width: 265px; height: 30px; font-size: 85%; line-height: 30px; letter-spacing: .3em; padding-left: 15px; margin: 0 0 12px; background: #fc6; border-radius: 5px; position: relative; box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); } #side h3.hogege { color: #999; font-size: 75%; padding: 0 0 2px; margin: 40px 0 0; } |
とまあ、余計な打ち消しを書かなくてすんで、7行ほど節約ができるわけです。
使いどころは多かれど、利便性に欠けるか?
しかし、wordpressなどの場合だと安易にクラスをつけられないこともしばしばだと思うんです。
notの引数の中で子孫セレクタや隣接セレクタが使えれば選択が用意になるのですが、ccs3ではできません。
css4で複雑なセレクタ使用の草案がでてるらしいので、期待しましょう。
それまでは擬似クラスなどを駆使して乗り切るんだ!
(jQueryでトラバースしまくってaddclassもありだぞ!)
引数に使える値(セレクタ)
- 全称セレクタ *
- 要素セレクタ h1 p ulなど
- クラスセレクタ .hoge
- ID セレクタ #fuga
- 属性セレクタ
[href] [src=" "]
など - 擬似クラス(not擬似クラスを以外) nth-childなど
おまけ 使用例
検証がsafariとfirefoxだけですので、あれなんですが、
親要素にnotつけてもいけるみたいです。
サイドの’fugaじゃないwidget’の子で ’hogeじゃないh3’のbefore擬似要素に適用。
1 2 3 |
#side .widget:not(#fuga) h3:not(.hoge)::before { } |
1 2 3 4 5 6 7 8 9 |
<li class="widget" id="fuga"> <h3>....</h3><!-- css適用されない --> </li> <li class="widget"> <h3>....</h3><!-- css適用される --> </li> <li class="widget"> <h3 class="hoge">....</h3><!-- css適用されない --> </li> |
なお、先祖要素からの除外はできない模様。
imgを例にすると、:not対象の要素との間に親としてa要素が挟まりimgが孫要素となると除外されないようです。
1 |
.side div:not(.widget) img |
1 2 3 4 5 |
<div class="side"> <div class="widget"> <a href="#"><img src="hoge/fuga.png"></a> </div> </div> |
スポンサーリンク
コメントをどうぞ