2026年5月20日
2026年5月20日
WordPressのCSSのspecificityの問題を解決する方法
はじめに
「CSSを書いたのにスタイルが適用されない」という問題の多くはCSS詳細度(specificity)の競合が原因です。WordPressではプラグインやブロックエディターが高詳細度のCSSを出力することがあり、上書きに苦労することがあります。
症状・原因
style.cssに書いたCSSが効かない!importantを使わないとスタイルが上書きできない- Gutenbergブロックのスタイルが消えない
- プラグインのCSSを上書きしたい
解決手順
ステップ1:詳細度の計算方法を理解する
詳細度は (A, B, C) の3桁で表されます:
- A:IDセレクタの数(
#id→ A=1) - B:クラス・属性・擬似クラスの数(
.class,[attr],:hover→ B=1) - C:要素・擬似要素の数(
div,::before→ C=1)
/* 詳細度の例 */
div /* (0,0,1) */
.card /* (0,1,0) */
div.card /* (0,1,1) */
#header /* (1,0,0) */
#header .nav a /* (1,1,1) */
/* :is() と :not() は引数の詳細度を継承 */
:is(#header, .nav) a /* (1,0,1) ← #headerの詳細度を引き継ぐ */
/* :where() は常に詳細度0 */
:where(#header, .nav) a /* (0,0,1) */
ステップ2:詳細度を高めて勝つ
/* 方法1: クラスを重ねる */
.wp-block-button.wp-block-button .wp-block-button__link {
background: #d63638; /* クラスが2つで (0,2,0) → 勝てる */
}
/* 方法2: body を先頭に付ける */
body .entry-content .wp-block-quote {
border-color: #2271b1;
}
/* 方法3: 属性セレクタを使う(詳細度はクラスと同じ) */
.wp-block-button__link[class] {
border-radius: 4px; /* (0,2,0) */
}
ステップ3:!importantを使う場面と代替案
/* !important は最後の手段 */
.entry-content p {
font-size: 1rem !important; /* プラグインのインラインスタイルを上書き */
}
/* 代替案1: インラインスタイルを除去するフィルター(PHP側で解決) */
/* functions.php */
add_filter('the_content', function(string $content): string {
// インラインスタイルを除去する場合(慎重に)
return preg_replace('/(<[^>]+) style="[^"]*"/i', '$1', $content);
});
/* 代替案2: CSS Layer で読み込み順を制御 */
@layer base, theme, utilities;
@layer base {
/* 低優先度のベーススタイル */
.wp-block-button__link { background: #0073aa; }
}
@layer theme {
/* テーマのスタイル(baseより優先) */
.wp-block-button__link { background: #2271b1; }
}
ステップ4:Cascade Layers(@layer)で管理する
/* WordPress 6.0+ でも利用可能(モダンブラウザ) */
@layer reset, wp-core, theme-base, theme-custom, utilities;
@layer reset {
*, *::before, *::after { box-sizing: border-box; }
}
@layer wp-core {
/* WordPressコアCSSを受け入れる */
.wp-block-image { margin: 1.5em 0; }
}
@layer theme-base {
/* テーマのベーススタイル */
:root { --color-primary: #2271b1; }
}
@layer theme-custom {
/* カスタマイズ(wp-coreより必ず優先) */
.wp-block-quote {
border-left-color: var(--color-primary);
}
}
@layer utilities {
/* ユーティリティクラス(最高優先) */
.text-center { text-align: center; }
}
ステップ5:プラグインのCSSを上書きする実践例
/* Contact Form 7 のエラーメッセージをカスタマイズ */
.wpcf7-not-valid-tip {
color: #d63638;
font-size: 0.85rem;
}
/* WooCommerceのボタン */
.woocommerce #respond input#submit,
.woocommerce a.button,
.woocommerce button.button {
background: #2271b1;
border-radius: 4px;
font-weight: 700;
}
/* Yoast SEOのブレッドクラム */
.yoast-breadcrumb { font-size: 0.85rem; }
注意事項
!importantを使いすぎると、次に上書きするときにさらに!importantが必要になる「詳細度戦争」に陥ります@layerは比較的新しい機能です(Chrome 99+・Firefox 97+・Safari 15.4+)。古いブラウザのサポートが必要な場合は注意してください- 子テーマのスタイルシートはキューに追加する順番(
wp_enqueue_styleの依存関係)で読み込まれます。後から読み込まれたCSSが同じ詳細度なら勝ちます
まとめ
詳細度の競合解決策:①クラスを重ねて詳細度を上げる → ②body を先頭に付ける → ③@layer で読み込み順を明示的に制御する → 最終手段として !important。Gutenbergブロックは .wp-block-{name} を2回重ねると大抵の場合に勝てます。