「カスタムHTML」ブロックでCSSのネスト記法(&)を使うと効かない原因と対策

Cocoonカスタマイズ集
この記事は約3分で読めます。
記事内に広告が含まれています。

はじめに

WordPressの「カスタムHTML」ブロック内にCSSを追加した際、CSSのネスト記法(&)が&に化けているという現象が発生します。

この記事では、この現象が発生する内部メカニズム(原因)と、具体的な対策を解説します。

現象

「カスタムHTML」ブロックに以下のようなCSSネスト記法を記述したとします。

@media (width <= 1500px) {
  .my_button {
    a {
      &:hover {
        background-color: red;
      }
    }
  }
}

しかし、実際のWebページのソースコード(DOM)を確認すると、以下のように&が&#038;へエスケープされて出力されてしまいます。

@media (width <= 1500px) {
  .my_button {
    a {
      &#038;:hover {
        background-color: red;
      }
    }
  }
}

HTMLエンティティ化されたことでCSSの構文エラーとなり、スタイルが正しく適用されなくなります。

原因

この現象は、WordPressコアの仕様(wp-includes/formatting.phpのwptexturize()の制約)によるものです。

wptexturize()は本文を「HTMLタグ部分」と「テキスト部分」に分割して処理します。
<style>内部は通常、変換対象外です。

しかし、@media (width <= 1500px)の<がHTMLタグの開始と誤認されると、<style>と</style>が正しく対として認識されません。
その結果、除外が効かず、CSSネストの&が&#038;に置換されます。

対策

対策1:ネスト記述をせず、フラットなCSS構文で書く

「カスタムHTML」ブロック内に直接CSSを書く場合は、ネスト用の&や、範囲構文の<を使わず、従来どおりのフラットなCSS構文で記述します。

@media (max-width: 1500px) {
  .my_button a:hover {
    background-color: red;
  }
}

対策2:ネスト記述を使う場合は、max-width などの従来の書き方で範囲を指定する

CSSネストを使う場合でも、メディアクエリの範囲指定に<を使わず、max-widthやmin-widthで記述します。
本文中に<がなくなるため、<style>が正しく認識され、&が&#038;に変換されません。

@media (max-width: 1500px) {
  .my_button {
    a {
      &:hover {
        background-color: red;
      }
    }
  }
}

対策3:CSSを適切な保存先へ移す

CSSの記述場所を「投稿本文」以外にすると、本文用のフィルター(wptexturize()など)を経由せずに、ネストの &を安全に記述できます(表1参照)。

CSSネストへの影響
保存先内部の保存処理CSSネストへの影響
「カスタムHTML」ブロックpost_content(投稿本文)あり
カスタムCSS(Cocoon独自)update_post_meta()なし
追加CSSwp_update_custom_css_post()なし
子テーマの style.css静的ファイル(PHPフィルター不通過)なし

さいごに

今回紹介した方法を使えば、WordPressの「カスタムHTML」ブロックでCSSが効かないトラブルをスムーズに解決できます。

「カスタムHTML」ブロック内では&や<を使わないフラットな記法を徹底するか、CocoonのカスタムCSS欄や「追加CSS」といった安全な保存場所を活用して、意図通りのスタイリングを行っていきましょう。

タイトルとURLをコピーしました