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回重ねると大抵の場合に勝てます。

お気軽にご相談ください

お見積りへ お問い合わせへ