0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Tailwind CSS】`bg-opacity-20`が効かず画面が真っ黒に!WordPress移行で学ぶCSS変数依存の落とし穴

0
Posted at

環境情報

  • 作業内容: 静的HTMLサイト(約30ページ)のWordPress移行
  • CSSフレームワーク: Tailwind CSS(CDN版サブセット・軽量化版)
  • WordPressテーマ: 独自開発テーマ(リセットCSS込み)
  • ブラウザ: Google Chrome 120 / Safari 17(ともに最新版)

発生した問題

静的HTMLサイトをWordPressに移行する作業中、ヒーローセクションの背景画像が完全に見えなくなる不具合が発生しました。

セクションの構造

<!-- ヒーローセクション -->
<section class="relative h-[500px]">
  <img src="hero.jpg" class="absolute inset-0 w-full h-full object-cover" alt="">
  <!-- ここが原因のオーバーレイ -->
  <div class="absolute inset-0 bg-black bg-opacity-20"></div>
  <div class="relative z-10 text-white text-center pt-40">
    <h1>キャッチコピー</h1>
    <p>サブテキスト</p>
  </div>
</section>

期待した表示と実際の表示

項目 期待 実際
背景画像 20%の黒で薄暗くなった状態で見える 完全に見えない
オーバーレイ rgba(0, 0, 0, 0.2) rgb(0, 0, 0) の不透明な黒
テキスト 白文字が視認できる 白文字は見えるが背景が真っ黒

原因調査

DevToolsで該当要素の「計算済みスタイル」を確認したところ、background-colorの計算値がrgb(0, 0, 0)になっていました。つまり20%透過のつもりが、100%不透明な黒になっていたのです。

Tailwindのbg-opacity-20の仕組み

通常のTailwind CSS v2系では、bg-opacity-*はCSS変数--tw-bg-opacityを介して透明度を制御します。

/* 本来のTailwind v2系の定義 */
.bg-black {
  --tw-bg-opacity: 1;
  background-color: rgba(0, 0, 0, var(--tw-bg-opacity));
}

.bg-opacity-20 {
  --tw-bg-opacity: 0.2;
}

.bg-opacity-20--tw-bg-opacity0.2を代入し、.bg-black側がこの変数を参照することでrgba(0, 0, 0, 0.2)が生成されます。2つのクラスの組み合わせが前提の設計です。

今回使用していたサブセット版の実態

一方、今回使用していたのはCDN配布の軽量化版(サブセット版)でした。この中身を確認すると、以下のように定義されていました。

/* 今回のサブセット版 */
.bg-black {
  background-color: rgb(0, 0, 0); /* 固定値! */
}

.bg-opacity-20 {
  /* 存在しない or 何も出力されない */
}

軽量化の過程で、CSS変数に依存する複雑な定義が単純な固定値に置き換えられ、--tw-bg-opacityの参照が失われていました。このため、bg-black bg-opacity-20としても不透明な黒が適用され続けたのです。

デバッグ時の確認手順

  1. DevToolsのElementsパネルでオーバーレイ要素を選択
  2. 「Styles」タブで.bg-blackの定義を確認
  3. 「Computed」タブでbackground-colorの値を確認
  4. rgb(0, 0, 0)と表示されており、rgba(0, 0, 0, 0.2)ではないことを確認
  5. 配信中のCSSファイルを直接開き、var(--tw-bg-opacity)が含まれるかgrepで検索
# 該当CSSにCSS変数が残っているか確認
curl -s https://cdn.example.com/tailwind-subset.css | grep "tw-bg-opacity"

修正手順

ステップ1: インラインスタイルに置き換える

最も確実な方法として、オーバーレイ部分をインラインスタイルへ変更しました。

<!-- 修正後 -->
<div class="absolute inset-0" style="background-color: rgba(0, 0, 0, 0.2);"></div>

ステップ2: 同様のパターンを全体検索

*-opacity-*を利用している箇所が他にもないか、プロジェクト全体を検索します。

grep -rn "bg-opacity-" --include="*.html" ./

ステップ3: サブセット版のCSSを再ビルド

根本解決として、Tailwind CLIを導入し、必要なユーティリティだけを正しくビルドして配信することにしました。

npm install -D tailwindcss@2.2.19
npx tailwindcss -o dist/tailwind.css --minify

ビルド後、生成されたCSSにvar(--tw-bg-opacity)が含まれていることを確認します。

grep "tw-bg-opacity" dist/tailwind.css | head

さらに見つかった問題: CTAボタンの文字色消失

同じ移行作業中、CTAボタンでもCSS競合が発生しました。

<a href="/contact" class="bg-white text-primary px-6 py-3 rounded">
  お問い合わせ
</a>

症状

  • bg-whiteは効いており、背景は白
  • text-primaryが無効化され、文字色が「透明」に見える

原因

WordPressテーマ側のグローバルCSSに、以下のリセットが定義されていました。

/* WordPressテーマ側 */
a {
  color: inherit !important;
}

!important付きのcolor: inheritが、Tailwindの.text-primaryより優先されました。

/* Tailwind側 */
.text-primary {
  color: #0066cc;
}

親要素の文字色が白だったため、白背景に白文字となり、ボタンのラベルが消えたように見えたのです。

対処策

!important同士の戦いを避けるため、<a><button>へ変更し、テーマ側のaセレクタの影響範囲から外しました。

<button type="button" onclick="location.href='/contact'"
        class="bg-white text-primary px-6 py-3 rounded">
  お問い合わせ
</button>

Tailwindバージョン比較

バージョン 記法 透明度の仕組み 注意点
v2系 bg-black bg-opacity-20 CSS変数--tw-bg-opacity クラス組み合わせが前提
v3系 bg-black/20 color-mix()やJIT bg-opacity-*は非推奨
v4系 bg-black/20 ネイティブCSS関数 ビルド必須

FAQ

Q. サブセット版CSSを使うべきではないの?

A. 表示速度の最適化を目的とした軽量化なら、本家CDN版でも十分です。独自にユーティリティを削ったサブセット版は、CSS変数の依存関係まで削られるリスクがあります。信頼性を重視するならTailwind CLI / PostCSSでのビルドを推奨します。

Q. opacity-20ではダメなの?

A. 要素全体の不透明度を下げるため、背景だけを半透明にしたい場合は使えません。

<!-- 要素全体が20%になるため、テキストも薄くなる -->
<div class="bg-black opacity-20">テキスト</div>

Q. WordPressテーマと併用するときのベストプラクティスは?

A. !importantの使用をスコープ付きに絞ることです。例えば、テーマ側はbody .entry-content aのようにセレクタを限定すると、グローバルへの影響を防げます。

まとめ

今回の経験から得た教訓は3つです。

  1. Tailwindのサブセット版はCSS変数の依存関係が壊れていることがある
    • ビルド後のCSSを必ず確認し、var(--tw-bg-opacity)が残っているか検証する
  2. WordPressテーマのグローバルCSSリセットは予想外のスコープに影響する
    • 移行前にa, p, divなどの要素セレクタを洗い出す
  3. color: inherit !importantは便利だが、Tailwindのユーティリティクラスを全て殺す
    • 使う場合はスコープを限定し、影響範囲をコントロールする

「クラス名は正しいのに効かない」問題は、フレームワーク内部の実装依存とグローバルCSSの競合が絡む典型例です。同じ問題に遭遇した方の参考になれば幸いです。


この記事を書いた人

BENTEN Web Works — 業務自動化・システム開発のフリーランスエンジニアです。

GAS / Python / RPA を使った業務自動化や、Web制作・システム開発のご相談を承っています。
「こんなこと自動化できる?」というご質問だけでもお気軽にどうぞ。

👉 BENTEN Web Works — 詳細・お問い合わせはこちら
🐦 X(旧Twitter) — 日々の知見を発信中

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?