きっかけはこれです。プロフィールページのツールグリッドに、使っているツールのラベル(<p>タグ)を追加したのですが、スマホで見たときに指定したはずのmargin-bottom: 0.6emより、明らかに広い余白が空いてしまう不具合に遭遇しました。
CSSは合っているはずなのに効いていない、という原因を追いかけた記録です。
まずは実際にマッチしているルールを洗い出す
まずは事実確認です。こういう時に感覚だけで直そうとすると大体ハマるので、ブラウザの開発者ツールで、その要素に実際に適用されているCSSルールを1つずつ確認していきました。
自分で書いた.c-tool-grid__labelの指定はちゃんと存在しているのに、優先されずに別の値が勝っている状態です。
犯人はCocoonの巨大な結合セレクタだった
調べていくと、使っているCocoonテーマ標準の.entry-content > *, .article p, ...という、とても長い結合セレクタがmargin-bottom: 1.8emを設定していることが分かりました。
これがラベルの余白を広げていた張本人です。
ここが本題です。CSSの詳細度は、単純に「後に書いた方が勝つ」わけではなく、セレクタの構成要素(IDの数・クラスの数・要素の数)で優先順位が決まります。
今回の場合、Cocoon側の.article pは「クラス1つ+要素1つ」の組み合わせだったのに対し、こちらの.c-tool-grid__labelは「クラス1つ」だけ。
要素セレクタが1つ余分にある分、詳細度としてはCocoon側の方がわずかに高くなっていて、結合セレクタの中の1つでも自分より詳細度が高ければそちらが勝ってしまう、という仕組みでした。
解決は、クラスを2重に書くだけ
対応はこうです。対処法としては、.c-tool-grid__label.c-tool-grid__labelのように、同じクラスを2回連続で書く方法を選びました。
これでクラスの詳細度が2つ分になり、Cocoon側の「クラス1+要素1」を上回ります。
!importantを使う手もありますが、後から自分や他の誰かがさらに上書きしたくなったときに詰みやすくなるので、詳細度の計算だけで解決できる今回のようなケースでは、この方法の方が扱いやすいと感じました。
既視感がありました。実はこれと似た経験は、以前Cocoonの目次(TOC)デザインをカスタマイズしたときにもありました。
あの時もCocoon本体が動的に出力するCSSの詳細度に阻まれて、IDセレクタ+!importantでようやく上書きできた経緯があります。
今回はクラスの2重指定だけで済んだので、都度状況に応じて一番手数の少ない方法を選べばいいんだなと再確認できました。
まとめ
教訓はこれです。「CSSは書いた通りに合っているのに、なぜか効いていない」というのは、大体このパターンです。
既存テーマをベースにカスタマイズしていると、テーマ側が持っている結合セレクタの詳細度に、思いがけないところで負けていることがあります。
見た目のCSSだけを疑うのではなく、実際にどのルールが勝っているのかをブラウザで確認する癖をつけておくと、こういう沼にハマったときの脱出が早くなりそうです。
この記事が参考になったら、応援クリックをお願いします




