【CSS】:empty疑似クラスの使い方:空要素の判定と非表示

css-empty

CSSの:empty疑似クラスは、動的な要素の表示・非表示をJavaScriptなしで制御できるセレクタですが、「空白」など特有の仕様への理解が必要です。

本記事では、要素が空と判定される条件、「空なら隠す」テクニック、効かない時のチェックリストまで:emptyを使いこなす方法を解説します。

また、CSSに関するカテゴリーページから学びたい内容を決めたい人は、以下のCSSページをご確認ください。

目次

:empty疑似クラスとは:要素が空か判定する仕組み

Web開発において、JavaScriptなどの動的な処理によってHTMLの中身が追加されたり消えたりすることはよくあります。

この時、「要素の中身が何もない(空)なら、要素自体を隠したい」「空の時だけ特別なメッセージを表示したい」という要件が発生します。

このような「要素が空かどうか」を判定し、デザインを切り替えるのに役立つのが:empty疑似クラスです。

ここでは、要素が空と判定される基本ルールを解説します。

:empty疑似クラスとは:要素が「空」か判定する仕組み
  • テキストも子要素も持たない空要素を指定する
  • スペースや改行があると空にならない

テキストも子要素も持たない空要素を指定する

:empty疑似クラスの基本は、「そのタグの中に、テキストも他のHTMLタグ(子要素)も含まれていない空状態」の要素を指定することです。

例えば、<div></div><span></span>のように、開始タグと終了タグの間に何もない要素が:emptyに該当します。

ちなみに、<br><img>のように終了タグを持たない空要素も:emptyの対象となります。

実務で使われるのは、「中身が空になってしまった要素は:emptyを使ってdisplay: none;で非表示にしてしまう」という自衛策です。

p:empty { display: none; }と1行書いておくだけで、CMSが吐き出す邪魔な空タグによるレイアウト崩れを未然に防げます。

⭕️ :empty は「完全な空っぽ」だけを狙い撃ちにするセレクタ!

中身あり
(適用されない)

テキストあり

空の要素
(paddingのせいで謎の箱になる)

空の要素 + :empty
(完全に消え去る)

↑完全に消えている↑

/* 💡 全てのボックスに共通の余白と背景色をつける */
.box {
  background-color: #0d6efd;
  padding: 20px;
}

/* ⭕️ 空になった要素は :empty で隠してレイアウト崩れを防ぐ */
.box:empty {
  display: none; /* 💡 中身がない時は要素ごと消す! */
}
HTMLコード表示
<div class="empty-layout-wrapper">
  
  <p class="empty-caption">⭕️ :empty は「完全な空っぽ」だけを狙い撃ちにするセレクタ!</p>

  <div class="empty-demo-area">
    
    <!-- 💡 通常の要素(中身あり) -->
    <div class="empty-demo-section">
      <p class="empty-label">中身あり<br><small>(適用されない)</small></p>
      <div class="empty-box">テキストあり</div>
    </div>

    <!-- ❌ 失敗:空なのにスタイルが残って邪魔になる -->
    <div class="empty-demo-section">
      <p class="empty-label">空の要素<br><small>(paddingのせいで謎の箱になる)</small></p>
      <div class="empty-box is-bad-empty"></div>
    </div>

    <!-- ⭕️ 成功::emptyを使って非表示にする -->
    <div class="empty-demo-section">
      <p class="empty-label" style="color:#0d6efd;">空の要素 + :empty<br><small>(完全に消え去る)</small></p>
      <div class="empty-box is-good-empty"></div>
      <p style="font-size: 11px; color:#6c757d; margin-top:5px; text-align:center;">↑完全に消えている↑</p>
    </div>

  </div>

  <div class="empty-code-area">
    /* 💡 全てのボックスに共通の余白と背景色をつける */<br>
    <span class="hl-blue">.box</span> {<br>
      <span class="hl-green">background-color:</span> <span class="hl-red">#0d6efd;</span><br>
      <span class="hl-green">padding:</span> <span class="hl-red">20px;</span><br>
    }<br><br>

    /* ⭕️ 空になった要素は :empty で隠してレイアウト崩れを防ぐ */<br>
    <span class="hl-blue">.box:empty</span> {<br>
      <span class="hl-green">display:</span> <span class="hl-red">none;</span> /* 💡 中身がない時は要素ごと消す! */<br>
    }
  </div>
</div>
CSSコード表示
.empty-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.empty-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 30px;
  color: #198754;
  text-align: center;
}

.empty-demo-area {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: 30px;
  background-color: #e9ecef;
  padding: 40px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.empty-demo-section {
  display: flex;
  flex-direction: column;
  width: 120px;
}

.empty-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 15px;
  text-align: center;
  line-height: 1.5;
  height: 40px;
}

/* 共通のボックスベース */
.empty-box {
  background-color: #0d6efd;
  color: white;
  padding: 15px;
  border-radius: 6px;
  font-weight: bold;
  text-align: center;
  font-size: 13px;
  box-sizing: border-box;
}

/* =❌ 実践コード:中身が空なのにpaddingが残る= */
/* ※クラス名でシミュレート(実際は:emptyを使わない状態) */
.is-bad-empty {
  background-color: #dc3545; /* 警告として赤にする */
}

/* =⭕️ 実践コード::emptyを使って非表示にする= */
/* ※クラス名でシミュレート */
.is-good-empty:empty {
  display: none; /* 💡 空の時は完全に消え去る */
}

/* =コード解説エリア= */
.empty-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }

非表示を設定するdisplayプロパティの使い方を詳しく知りたい人は「【html&css】displayの種類は?flexやinline-blockの違い」を一読ください。

スペースや改行があると空にならない

:emptyを使う上で恐ろしいのが、「空白の罠」です。

:emptyは判定が厳格で、「半角スペース」「改行コード」「タブ」が要素の中に1つでも含まれていると「空ではない」と判定されてしまいます。

JSの動的出力などで:emptyを効かせたい場合は、「HTMLを書くときに、開始タグと終了タグを改行せずくっつけて書くこと(例:<div></div>)」です。

⭕️ 改行やスペースは「文字」扱い!:empty を使うならタグはくっつけろ

❌ 改行・スペースあり
(:emptyが効かない)

⭕️ タグ密着
(:emptyが効いて消える)

↑完全に消えている↑

/* 💡 アラート枠のベースデザイン */
.alert {
  background-color: #f8d7da;
  border: 1px solid #f5c2c7;
  padding: 15px;
}

/* ⭕️ プロの鉄則:アラートの中身がない時は :empty で隠す! */
.alert:empty {
  display: none;
}

/* 🚨 罠:以下のHTMLだと改行が含まれるため消えない! */
<div class=”alert”>
</div>
HTMLコード表示
<div class="empty-layout-wrapper">
  
  <p class="empty-caption">⭕️ 改行やスペースは「文字」扱い!:empty を使うならタグはくっつけろ</p>

  <div class="empty-demo-area">
    
    <!-- ❌ 失敗:改行やスペースが含まれる(空と判定されない) -->
    <div class="empty-demo-section" style="width: 140px;">
      <p class="empty-label">❌ 改行・スペースあり<br><small>(:emptyが効かない)</small></p>
      
      <!-- 💡 タグの間に改行とスペースがある! -->
      <div class="empty-alert is-fail">
        
      </div>
    </div>

    <!-- ⭕️ 成功:タグが完全にくっついている(空と判定される) -->
    <div class="empty-demo-section" style="width: 140px;">
      <p class="empty-label" style="color:#0d6efd;">⭕️ タグ密着<br><small>(:emptyが効いて消える)</small></p>
      
      <!-- 💡 タグの間に何もない! -->
      <div class="empty-alert is-success"></div>
      <p style="font-size: 11px; color:#6c757d; margin-top:5px; text-align:center;">↑完全に消えている↑</p>
    </div>

  </div>

  <div class="empty-code-area">
    /* 💡 アラート枠のベースデザイン */<br>
    <span class="hl-blue">.alert</span> {<br>
      <span class="hl-green">background-color:</span> <span class="hl-red">#f8d7da;</span><br>
      <span class="hl-green">border:</span> <span class="hl-red">1px solid #f5c2c7;</span><br>
      <span class="hl-green">padding:</span> <span class="hl-red">15px;</span><br>
    }<br><br>

    /* ⭕️ アラートの中身がない時は :empty で隠す! */<br>
    <span class="hl-blue">.alert:empty</span> {<br>
      <span class="hl-green">display:</span> <span class="hl-red">none;</span><br>
    }<br><br>

    /* 🚨 以下のHTMLだと改行が含まれるため消えない! */<br>
    <span class="hl-comment"><div class="alert"></span><br>
    <span class="hl-comment"></div></span>
  </div>
</div>
CSSコード表示
.empty-alert {
  background-color: #f8d7da;
  border: 1px solid #f5c2c7;
  color: #842029;
  padding: 15px;
  border-radius: 6px;
  font-weight: bold;
  text-align: center;
  font-size: 13px;
  min-height: 50px; /* 見えやすくするための高さ */
}

/* =❌ 実践コード:改行・スペースが含まれる= */
/* 実際のHTMLに改行とスペースが入っているため、:emptyは適用されず表示されっぱなしになる */
.is-fail:empty {
  display: none;
}

/* =⭕️ 実践コード:タグが完全にくっついている= */
/* 実際のHTMLが <div></div> と完全に空なので、:emptyが適用されて消える */
.is-success:empty {
  display: none;
}

空のdiv要素を非表示にする

実務のWeb制作において、div要素が常に中身を持っているとは限りません。

JavaScriptによる動的なエラーメッセージの枠や、CMS(WordPressなど)でデータが入力されなかった時の出力結果など、「中身が空っぽのタグ」がHTML上に残ってしまうケースは多々あります。

この時、枠線や背景色のスタイルが当たっていると、中身がないのに「謎の線」や「謎の色の塊」が画面に表示されてしまい不格好です。

ここでは、そんな「中身がない時だけ要素を隠す」テクニックと「中身がある時だけスタイルを当てる」モダンなアプローチを解説します。

空のdiv要素を非表示にする
  • 中身がない時だけ要素を隠す
  • :not:has()を使って中身がある時だけ装飾する

中身がない時だけ要素を隠す

空のdiv要素をそのまま放置するとpaddingなどが設定されている場合、中身がなくても不自然な隙間や高さが生まれます。

これを防ぐ方法が:empty疑似クラスを使って、空の時だけdisplay: none;にするテクニックです。

これ一つで、空のdivや空のあらゆる要素を邪魔にならないよう画面から消し去ることができます。

実務におけるルールは、「要素を無かったことにしたい場合はdisplay: none;を使うこと」です。

:emptydisplay: none;の組み合わせは、HTMLの構造を汚さず、CSSだけで完結する安全な防衛策です。

⭕️ 要素の中身がない時(エラーや未入力)は、:emptyで根こそぎ消し去る!

メッセージあり
(通常表示)

入力エラーがあります。

メッセージなし
(空なのに枠が残る)

メッセージなし + :empty
(完全に消える)

↑完全に消えている↑

/* 💡 エラーメッセージのベースデザイン(枠や背景色がある) */
.alert-box {
  background-color: #f8d7da;
  border: 1px solid #f5c2c7;
  padding: 15px;
}

/* ⭕️ 中身が空の時は、そもそも表示させない! */
.alert-box:empty {
  display: none; /* 💡 空間ごと完全に消滅させる */
}
HTMLコード表示
<div class="hide-layout-wrapper">
  
  <p class="hide-caption">⭕️ 要素の中身がない時(エラーや未入力)は、:emptyで根こそぎ消し去る!</p>

  <div class="hide-demo-area">
    
    <!-- 💡 通常の状態(エラーメッセージがある) -->
    <div class="hide-demo-section">
      <p class="hide-label">メッセージあり<br><small>(通常表示)</small></p>
      
      <div class="hide-alert-box">
        入力エラーがあります。
      </div>
    </div>

    <!-- ❌ 失敗:中身が空なのに枠線と余白が残って邪魔 -->
    <div class="hide-demo-section">
      <p class="hide-label">メッセージなし<br><small>(空なのに枠が残る)</small></p>
      
      <!-- 💡 中身は空っぽ -->
      <div class="hide-alert-box is-bad-empty"></div>
    </div>

    <!-- ⭕️ 成功::emptyを使って完全に非表示 -->
    <div class="hide-demo-section">
      <p class="hide-label" style="color:#0d6efd;">メッセージなし + :empty<br><small>(完全に消える)</small></p>
      
      <!-- 💡 中身は空っぽ -->
      <div class="hide-alert-box is-good-empty"></div>
      <p style="font-size: 11px; color:#6c757d; margin-top:5px; text-align:center;">↑完全に消えている↑</p>
    </div>

  </div>

  <div class="hide-code-area">
    /* 💡 エラーメッセージのベースデザイン(枠や背景色がある) */<br>
    <span class="hl-blue">.alert-box</span> {<br>
      <span class="hl-green">background-color:</span> <span class="hl-red">#f8d7da;</span><br>
      <span class="hl-green">border:</span> <span class="hl-red">1px solid #f5c2c7;</span><br>
      <span class="hl-green">padding:</span> <span class="hl-red">15px;</span><br>
    }<br><br>

    /* ⭕️ 中身が空の時は、そもそも表示させない! */<br>
    <span class="hl-blue">.alert-box:empty</span> {<br>
      <span class="hl-green">display:</span> <span class="hl-red">none;</span> /* 💡 空間ごと完全に消滅させる */<br>
    }
  </div>

</div>
CSSコード表示
.hide-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.hide-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 30px;
  color: #198754;
  text-align: center;
}

.hide-demo-area {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: 30px;
  background-color: #e9ecef;
  padding: 40px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.hide-demo-section {
  display: flex;
  flex-direction: column;
  width: 150px;
}

.hide-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 15px;
  text-align: center;
  line-height: 1.5;
  height: 40px;
}

/* 共通のアラートボックスベース */
.hide-alert-box {
  background-color: #f8d7da;
  border: 1px solid #f5c2c7;
  color: #842029;
  padding: 15px;
  border-radius: 6px;
  font-weight: bold;
  text-align: center;
  font-size: 12px;
  box-sizing: border-box;
}

/* =❌ 実践コード:中身が空なのに消えない= */
/* ※シミュレート用。実際は:emptyの指定がない状態 */
.is-bad-empty {
  /* 中身がないのにpaddingのせいで高さを持ってしまう */
}

/* =⭕️ 実践コード::emptyを使って非表示にする= */
/* ※シミュレート用。 */
.is-good-empty:empty {
  display: none; /* 💡 空の時は完全に消え去る */
}

/* =コード解説エリア= */
.hide-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }

改めて、非表示を設定するdisplayプロパティの使い方を詳しく知りたい人は「【html&css】displayの種類は?flexやinline-blockの違い」を一読ください。

:notや:has()を使って中身がある時だけ装飾する

空の時に隠すのではなく、「中身がある時だけ特別な装飾をしたい」という逆転の発想も実務では使われます。

この時活躍するのが、否定の疑似クラス:not()と組み合わせた:not(:empty)です。

「空ではない時」という条件を指定できるため、例えば「通知バッジに数字が入っている時だけ赤い背景色をつけて目立たせる」といった実装がCSSだけで完結します。

さらにモダンCSSでは、親要素が特定の子要素を持っているかを判定できる:has()も登場し、複雑な条件付きスタイリングが可能になっています。

動的なデータの有無による装飾の切り替えは、「JavaScriptの処理を極限まで減らし、CSSの:not(:empty)に任せること」がよいです。

通知バッジや、未読メッセージのハイライトなど、「データ(文字)が注入された瞬間にデザインを変える」処理は、このセレクタを使うことで軽量に実装できます。

⭕️ JavaScriptは不要!:not(:empty)で「中身が入った時だけ」装飾する

通知なし (空)
(グレーのまま目立たない)

通知あり (文字入り)
(:not(:empty)が反応して赤くなる)

3
/* 💡 バッジの基本スタイル(通知がない時はグレーで目立たせない) */
.badge {
  background-color: #adb5bd;
  /* 丸くする装飾など… */
}

/* ⭕️ 「空ではない」時だけ、目立つ色に上書きする! */
.badge:not(:empty) {
  background-color: #dc3545; /* 💡 赤色にしてユーザーの注意を引く */
  transform: scale(1.1); /* 💡 少し大きくするなどのアニメーションも可能 */
}
HTMLコード表示
<div class="hide-layout-wrapper">
  
  <p class="hide-caption">⭕️ JavaScriptは不要!:not(:empty)で「中身が入った時だけ」装飾する</p>

  <div class="hide-demo-area" style="gap: 50px;">
    
    <!-- 💡 空の状態(通知なし) -->
    <div class="hide-demo-section">
      <p class="hide-label">通知なし (空)<br><small>(グレーのまま目立たない)</small></p>
      
      <div class="hide-icon-wrapper">
        <i class="fas fa-bell hide-bell-icon"></i>
        <!-- 💡 バッジは空っぽ -->
        <span class="hide-badge"></span>
      </div>
    </div>

    <!-- ⭕️ 成功:中身がある状態(通知あり) -->
    <div class="hide-demo-section">
      <p class="hide-label" style="color:#dc3545;">通知あり (文字入り)<br><small>(:not(:empty)が反応して赤くなる)</small></p>
      
      <div class="hide-icon-wrapper">
        <i class="fas fa-bell hide-bell-icon"></i>
        <!-- 💡 JSなどで数字が注入されたと想定 -->
        <span class="hide-badge is-active-badge">3</span>
      </div>
    </div>

  </div>

  <div class="hide-code-area">
    /* 💡 バッジの基本スタイル(通知がない時はグレーで目立たせない) */<br>
    <span class="hl-blue">.badge</span> {<br>
      <span class="hl-green">background-color:</span> <span class="hl-red">#adb5bd;</span><br>
      <span class="hl-comment">/* 丸くする装飾など... */</span><br>
    }<br><br>

    /* ⭕️ 「空ではない」時だけ、目立つ色に上書きする! */<br>
    <span class="hl-blue">.badge:not(:empty)</span> {<br>
      <span class="hl-green">background-color:</span> <span class="hl-red">#dc3545;</span> /* 💡 赤色にしてユーザーの注意を引く */<br>
      <span class="hl-green">transform:</span> <span class="hl-red">scale(1.1);</span> /* 💡 少し大きくするなどのアニメーションも可能 */<br>
    }
  </div>

</div>
CSSコード表示
<!-- ※Font Awesomeを使用するためCDNリンク(環境によっては不要) -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">

<style>
.hide-icon-wrapper {
  position: relative;
  display: inline-block;
  margin: 0 auto;
  padding: 10px;
}

.hide-bell-icon {
  font-size: 32px;
  color: #495057;
}

/* 💡 バッジの基本スタイル(グレー) */
.hide-badge {
  position: absolute;
  top: 0;
  right: 0;
  background-color: #adb5bd; /* デフォルトはグレー */
  color: white;
  font-size: 11px;
  font-weight: bold;
  padding: 3px 6px;
  border-radius: 50%;
  border: 2px solid #fff;
  min-width: 10px;
  min-height: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
}

/* =⭕️ 実践コード:中身がある時だけ装飾を変える= */
/* ※シミュレート用。実際は .hide-badge:not(:empty) と書く */
.is-active-badge:not(:empty) {
  background-color: #dc3545; /* 💡 中身が入ったら赤くする! */
  transform: scale(1.1);
  box-shadow: 0 2px 4px rgba(220,53,69,0.4);
}

疑似クラスである:not:hasの使い方を詳しく知りたい人は以下から一読ください。

inputの未入力・入力済みの判定方法

お問い合わせフォームやログイン画面の実装において、「ユーザーが何も入力していない時は枠線を赤くしたい」「入力済みならチェックマークを出したい」といった要望は実務で発生します。

この時、「要素が空かどうか判定するなら:empty疑似クラスが使えるのでは?」と思いつくかもしれませんが、フォーム要素に対して:emptyを使うのはやってはいけないです。

ここでは、なぜinputタグに:emptyが効かないのかというブラウザの仕様、CSSだけで未入力・入力済みを判定する方法を解説します。

inputの未入力・入力済みの判定方法
  • inputタグには:emptyが使えない理由
  • 属性や:placeholder-shownで未入力・入力済みを判定

inputタグには:emptyが使えない理由

なぜ効かないのか?結論から言うと、HTMLの仕様上<input><img>といった「終了タグを持たない要素」は、「空」であると判定されるからです。

input要素の入力値は、タグの中にテキストとして入っているわけではなく、value属性の値として保持されています。

そのため、ユーザーがどれだけ文字を打ち込もうが、HTMLの構造的には子要素を持たない空っぽの要素のままです。

<select>タグの場合も同様の勘違いが起きやすいです。

select:emptyを使うと、選択されていないではなく<option>タグが1つも存在しないという別の意味になります。

実務における主流は、終了タグを持たない空要素(input,img,br,hrなど)に対しては:empty疑似クラスを使用しないことです。

これらはレイアウトの調整には使えず、予想外のスタイル適用を引き起こすだけです。

⭕️ inputタグは常に「空」判定!:empty を使うと永遠にスタイルが当たり続ける

❌ input:empty の罠
(文字を入力しても赤いまま)

/* ❌ input の未入力判定に :empty を使ってしまう */
input:empty {
  border: 2px solid red;
  background-color: #f8d7da;
  /* 🚨 input は終了タグがないため、入力の有無に関わらず一生適用される! */
}
HTMLコード表示
<div class="form-layout-wrapper">
  
  <p class="form-caption">⭕️ inputタグは常に「空」判定!:empty を使うと永遠にスタイルが当たり続ける</p>

  <div class="form-demo-area">
    
    <div class="form-demo-section">
      <p class="form-label">❌ input:empty の罠<br><small>(文字を入力しても赤いまま)</small></p>
      
      <!-- 💡 valueが入っていても、:empty は適用されてしまう! -->
      <input type="text" class="form-input is-bad-empty" value="入力しても赤いまま!">
    </div>

  </div>

  <div class="form-code-area">
    /* ❌ input の未入力判定に :empty を使ってしまう */<br>
    <span class="hl-blue">input:empty</span> {<br>
      <span class="hl-green">border:</span> <span class="hl-red">2px solid red;</span><br>
      <span class="hl-green">background-color:</span> <span class="hl-red">#f8d7da;</span><br>
      <span class="hl-comment">/* 🚨 input は終了タグがないため、入力の有無に関わらず一生適用される! */</span><br>
    }
  </div>

</div>
CSSコード表示
.form-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.form-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 30px;
  color: #198754;
  text-align: center;
}

.form-demo-area {
  display: flex;
  justify-content: center;
  background-color: #e9ecef;
  padding: 40px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.form-demo-section {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 300px;
}

.form-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 15px;
  text-align: center;
  line-height: 1.5;
}

.form-input {
  width: 100%;
  padding: 12px;
  font-size: 14px;
  border-radius: 4px;
  box-sizing: border-box;
}

/* =❌ 実践コード:inputに対する:emptyの誤用= */
/* ※実際は input:empty と書くが、WPの他のinputに干渉しないようクラスで絞っている */
.form-input.is-bad-empty:empty {
  border: 2px solid #dc3545;
  background-color: #f8d7da;
  color: #842029;
}

/* =コード解説エリア= */
.form-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

正しいinputタグやselectタグの使い方を詳しく知りたい人は以下から一読ください。

属性や:placeholder-shownで未入力・入力済みを判定

JavaScriptを使わずにCSSだけで入力済みを判定するにはどうすればよいのでしょうか。

Web制作において、未入力・入力済みをリアルタイムに判定する方法が:placeholder-shownという疑似クラスを使ったハックです。

CSSだけでフォームの入力状態を判定するには、inputタグにダミーのplaceholder=" "を設定し:not(:placeholder-shown)で入力済みを検知することです。

ユーザーが1文字でも入力すると、プレースホルダーは非表示になります。

「プレースホルダーが消えた状態=入力済みである」というブラウザの挙動を逆手に取ることで、CSSだけで動的デザインを作れます。

⭕️ :placeholder-shown と :not() のコンボで、リアルタイムな入力判定を実現!

💡 CSSだけで動くフローティングラベル
(文字を入力するとラベルが上に逃げる!)

/* ⭕️ まずは input に placeholder=” ” を設定する */

/* 💡 入力済み(プレースホルダーが消えた状態)を検知して、隣の label を動かす! */
.float-input:not(:placeholder-shown) + .float-label {
  transform: translateY(-20px) scale(0.8); /* 💡 ラベルを上に逃がして小さくする */
  color: #0d6efd; /* 💡 入力完了の青色に変化! */
}

/* 💡 (おまけ)フォーカス中もラベルを上に逃がす */
.float-input:focus + .float-label {
  transform: translateY(-20px) scale(0.8);
  color: #0d6efd;
}
HTMLコード表示
<div class="form-layout-wrapper">
  
  <p class="form-caption">⭕️ :placeholder-shown と :not() のコンボで、リアルタイムな入力判定を実現!</p>

  <div class="form-demo-area">
    
    <div class="form-demo-section" style="max-width: 350px;">
      <p class="form-label" style="color:#0d6efd;">💡 CSSだけで動くフローティングラベル<br><small>(文字を入力するとラベルが上に逃げる!)</small></p>
      
      <div class="form-float-group">
        <!-- 💡 必須:placeholder=" "(空白でいいので設定する) -->
        <input type="text" id="demo-name" class="form-float-input" placeholder=" ">
        <label for="demo-name" class="form-float-label">お名前を入力してください</label>
      </div>

    </div>

  </div>

  <div class="form-code-area">
    /* ⭕️ まずは input に placeholder=" " を設定する */<br><br>

    /* 💡 入力済み(プレースホルダーが消えた状態)を検知して、隣の label を動かす! */<br>
    <span class="hl-blue">.float-input:not(:placeholder-shown) + .float-label</span> {<br>
      <span class="hl-green">transform:</span> <span class="hl-red">translateY(-20px) scale(0.8);</span> /* 💡 ラベルを上に逃がして小さくする */<br>
      <span class="hl-green">color:</span> <span class="hl-red">#0d6efd;</span> /* 💡 入力完了の青色に変化! */<br>
    }<br><br>

    /* 💡 (おまけ)フォーカス中もラベルを上に逃がす */<br>
    <span class="hl-blue">.float-input:focus + .float-label</span> {<br>
      <span class="hl-green">transform:</span> <span class="hl-red">translateY(-20px) scale(0.8);</span><br>
      <span class="hl-green">color:</span> <span class="hl-red">#0d6efd;</span><br>
    }
  </div>

</div>
CSSコード表示
.form-float-group {
  position: relative;
  width: 100%;
  margin-top: 20px;
}

.form-float-input {
  width: 100%;
  padding: 15px 15px 10px;
  font-size: 16px;
  border: 2px solid #ced4da;
  border-radius: 6px;
  box-sizing: border-box;
  outline: none;
  background-color: transparent;
  transition: border-color 0.3s ease;
}

/* プレースホルダーの文字自体は見えなくする(判定用に存在させるだけ) */
.form-float-input::placeholder {
  color: transparent; 
}

.form-float-label {
  position: absolute;
  top: 15px;
  left: 15px;
  font-size: 16px;
  color: #6c757d;
  transition: all 0.2s ease-out;
  pointer-events: none; /* クリックをすり抜けてinputに当てる */
  transform-origin: left top;
  background-color: #e9ecef; /* デモエリアの背景色と同じにして線を隠す */
  padding: 0 5px;
}

/* 💡 フォーカスされた時、または【入力済み】の時にラベルを動かす */
.form-float-input:focus + .form-float-label,
.form-float-input:not(:placeholder-shown) + .form-float-label {
  transform: translateY(-24px) scale(0.8);
  color: #0d6efd;
  font-weight: bold;
}

/* 入力済み、またはフォーカス時の枠線の色 */
.form-float-input:focus,
.form-float-input:not(:placeholder-shown) {
  border-color: #0d6efd;
}

:not疑似クラスの使い方を詳しく知りたい人は「【CSS】:not()疑似クラスの使い方:効かない原因と複数条件の指定」を一読ください。

Gridの空セルやレイアウトの余白調整

Webレイアウトを構築する際、要素が隙間なく敷き詰められている状態だけでなく、「空のセルを作る」あるいは「意図しない余白を消す」といったコントロールが求められる場面があります。

ここでは、テーブルの空セルの制御、Gridにおける意図的な空エリアの作成、謎の余白を消す方法を解説します。

Gridの空セルやレイアウトの余白調整
  • テーブルの空セルやGridの空の行・列の扱い
  • レイアウトの余白を埋める・削除する

テーブルの空セルやGridの空の行・列の扱い

HTMLのテーブル(<table>)において、中身が何もない空のセルの枠線や背景を表示するかどうかは、empty-cellsプロパティ(showまたはhide)で制御されてきました。

一方、主流であるGridにおいて、空の列や空の行を作るアプローチは異なります。

Gridレイアウトでは、アイテムを配置しないことで空のセルが生まれますが、明示的に「ここは空けておく」と指定したい場合はgrid-template-areasプロパティを活用します。

実務において、Gridレイアウトで空のセルや列を管理するには、grid-template-areasを使い、空にしたい場所に .(ピリオド)を記述することです。

これにより、CSSのコード自体が設計図のようになり、どこに要素が入り、どこが空になるのかが一目で分かります。

⭕️ Gridで空のセルを作るなら、template-areas の「 . 」(ピリオド)を使え!

💡 中央だけ空セル(ドーナツ型レイアウト)

Header
Left
Right
/* ⭕️ プロの鉄則:ピリオド( . )を使って、視覚的に空のセルを定義する */
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-areas:
    “header header header” /* 1行目 */
    “left . right “ /* 💡 2行目の中央に . を置いて空セル化! */
    “footer footer footer”; /* 3行目 */
}

/* 💡 各アイテムに名前を割り当てる */
.item-header {
  grid-area: header;
}
HTMLコード表示
<div class="grid-space-layout-wrapper">
  <p class="grid-space-caption">⭕️ Gridで空のセルを作るなら、template-areas の「 . 」(ピリオド)を使え!</p>

  <div class="grid-space-demo-area">
    
    <div class="grid-space-demo-section">
      <p class="grid-space-label">💡 中央だけ空セル(ドーナツ型レイアウト)</p>
      
      <!-- 💡 Gridコンテナ -->
      <div class="grid-area-container">
        <div class="grid-area-item is-header">Header</div>
        <div class="grid-area-item is-left">Left</div>
        <!-- 💡 中央は空(HTMLにも要素はない) -->
        <div class="grid-area-item is-right">Right</div>
        <div class="grid-area-item is-footer">Footer</div>
      </div>
    </div>

  </div>

  <div class="grid-space-code-area">
    /* ⭕️ ピリオド( . )を使って、視覚的に空のセルを定義する */<br>
    <span class="hl-blue">.container</span> {<br>
      <span class="hl-green">display:</span> <span class="hl-red">grid;</span><br>
      <span class="hl-green">grid-template-columns:</span> <span class="hl-red">repeat(3, 1fr);</span><br>
      <span class="hl-green">grid-template-areas:</span><br>
        <span class="hl-red">"header header header"</span> /* 1行目 */<br>
        <span class="hl-red">"left   .      right "</span> /* 💡 2行目の中央に . を置いて空セル化! */<br>
        <span class="hl-red">"footer footer footer"</span>; /* 3行目 */<br>
    }<br><br>

    /* 💡 各アイテムに名前を割り当てる */<br>
    <span class="hl-blue">.item-header</span> {<br>
      <span class="hl-green">grid-area:</span> <span class="hl-red">header;</span><br>
    }
  </div>
</div>
CSSコード表示
.grid-space-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.grid-space-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 30px;
  color: #198754;
  text-align: center;
}

.grid-space-demo-area {
  display: flex;
  justify-content: center;
  background-color: #e9ecef;
  padding: 40px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.grid-space-demo-section {
  width: 100%;
  max-width: 300px;
}

.grid-space-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 15px;
  text-align: center;
}

/* =⭕️ 実践コード:Gridコンテナとエリアの定義= */
.grid-area-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  /* 💡 アスキーアートのようにレイアウトを組む */
  grid-template-areas:
    "header header header"
    "left   .      right"  /* 💡 真ん中の . が空セルになる */
    "footer footer footer";
  background-color: #dee2e6;
  padding: 10px;
  border-radius: 6px;
  border: 2px dashed #6c757d;
}

/* 各アイテムのベース */
.grid-area-item {
  background-color: #0d6efd;
  color: white;
  padding: 15px;
  border-radius: 4px;
  font-weight: bold;
  text-align: center;
  font-size: 12px;
}

/* 各アイテムの配置割り当て */
.is-header {
  grid-area: header;
}
.is-left {
  grid-area: left;
}
.is-right {
  grid-area: right;
}
.is-footer {
  grid-area: footer;
}

/* =コード解説エリア= */
.grid-space-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}
.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

tableタグあるいはGridの使い方を詳しく知りたい人は以下から一読ください。

レイアウトの余白を埋める・削除する

Webデザインにおいて、要素を並べた際に生じる余白やGridの枠内に余ったスペースをどう扱うかは、デザインに直結します。

例えば、カード一覧などを並べた際に最後の行に余った空間を埋めたい場合は、fr単位やauto-fitといったGridの機能が活躍します。

一方で、意図しない空行や隙間を削除したいケースもあります。

「謎の隙間」を削除しつつ、Gridの余った空間を埋める方法は以下の2点です。

一つは、要素を並べる時はインライン要素の並列を避け、親要素にdisplay: flex;またはdisplay: grid;を指定し、隙間はgapで一元管理します。

これで改行コードによる謎の余白は消滅します。

二つ目は、画面幅に合わせて要素を敷き詰め、余白を埋めるならgrid-template-columns: repeat(auto-fit, minmax(最小幅, 1fr));を使います。

これにより、最後の行で要素が少なくても、余った空間を埋めるように要素が伸びます。

⭕️ 謎の隙間はFlex/Gridで撲滅!余った空間は auto-fit で美しく埋める

❌ inline-block の罠
(margin:0 なのにHTMLの改行が半角スペースになって隙間ができる)

Box 1
Box 2
Box 3

⭕️ Grid + auto-fit 指定
(謎の隙間が消え、余った空間を1frで自動的に埋める)

Box 1
Box 2
Box 3
/* ❌ inline-blockで並べると、HTMLの改行が隙間を生む */
.inline-box {
  display: inline-block;
  margin: 0; /* 💡 0にしても隙間は消えない! */
}

/* ⭕️ Gridを使い、auto-fit で余白(empty space)を埋め尽くす */
.grid-container {
  display: grid;
  /* 💡 最小幅100pxを保ちつつ、親の幅が余れば自動で伸びて(1fr)隙間を埋める */
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  gap: 0; /* 💡 隙間を消すならgapを0にするだけ */
}
HTMLコード表示
<div class="grid-space-layout-wrapper">
  <p class="grid-space-caption">⭕️ 謎の隙間はFlex/Gridで撲滅!余った空間は auto-fit で美しく埋める</p>

  <div class="grid-space-demo-area" style="flex-direction: column; align-items: center; gap: 30px;">
    
    <!-- ❌ 失敗:インライン要素の改行による謎の隙間 -->
    <div class="grid-space-demo-section" style="width: 100%;">
      <p class="grid-space-label">❌ inline-block の罠<br><small>(margin:0 なのにHTMLの改行が半角スペースになって隙間ができる)</small></p>
      
      <div class="space-fail-container">
        <!-- 💡 HTML上で改行しているのが原因 -->
        <div class="space-inline-box">Box 1</div>
        <div class="space-inline-box">Box 2</div>
        <div class="space-inline-box">Box 3</div>
      </div>
    </div>

    <!-- ⭕️ 成功:Gridの auto-fit で隙間をなくし、余白を埋める -->
    <div class="grid-space-demo-section" style="width: 100%;">
      <p class="grid-space-label" style="color:#0d6efd;">⭕️ Grid + auto-fit 指定<br><small>(謎の隙間が消え、余った空間を1frで自動的に埋める)</small></p>
      
      <div class="space-success-container">
        <div class="space-grid-box">Box 1</div>
        <div class="space-grid-box">Box 2</div>
        <div class="space-grid-box">Box 3</div>
      </div>
    </div>

  </div>

  <div class="grid-space-code-area">
    /* ❌ inline-blockで並べると、HTMLの改行が隙間を生む */<br>
    <span class="hl-blue">.inline-box</span> {<br>
      <span class="hl-green">display:</span> <span class="hl-red">inline-block;</span><br>
      <span class="hl-green">margin:</span> <span class="hl-red">0;</span> /* 💡 0にしても隙間は消えない! */<br>
    }<br><br>

    /* ⭕️ Gridを使い、auto-fit で余白(empty space)を埋め尽くす */<br>
    <span class="hl-blue">.grid-container</span> {<br>
      <span class="hl-green">display:</span> <span class="hl-red">grid;</span><br>
      <span class="hl-comment">/* 💡 最小幅100pxを保ちつつ、親の幅が余れば自動で伸びて(1fr)隙間を埋める */</span><br>
      <span class="hl-green">grid-template-columns:</span> <span class="hl-red">repeat(auto-fit, minmax(100px, 1fr));</span><br>
      <span class="hl-green">gap:</span> <span class="hl-red">0;</span> /* 💡 隙間を消すならgapを0にするだけ */<br>
    }
  </div>

</div>
CSSコード表示
.space-fail-container {
  background-color: #dee2e6;
  border: 1px solid #adb5bd;
}

.space-inline-box {
  display: inline-block;
  margin: 0; /* marginを0にしても... */
  background-color: #dc3545;
  color: white;
  padding: 10px;
  font-weight: bold;
  font-size: 12px;
  /* HTMLの改行のせいで、赤い箱の間に白い隙間(背景)が見えてしまう */
}

/* =⭕️ 実践コード:Gridで隙間を消し、余白を埋めるコンテナ= */
.space-success-container {
  display: grid;
  /* 💡 最小幅80px、余白があれば1frで引き伸ばして埋める */
  grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
  gap: 0; /* 💡 余白を完全に削除 */
  background-color: #dee2e6;
  border: 1px solid #adb5bd;
}

.space-grid-box {
  background-color: #0d6efd;
  color: white;
  padding: 10px;
  font-weight: bold;
  font-size: 12px;
  text-align: center;
  border-right: 1px solid #0a58ca; /* 境界線を分かりやすくするため */
}
.space-grid-box:last-child {
  border-right: none;
}

display要素であるflexgrid、余白管理するgapプロパティの使い方を詳しく知りたい人は以下から一読ください。

:emptyが効かない原因とCSSの警告

CSSの:empty疑似クラスは便利ですが、「指定したのに全く効かない!」と頭を抱えることがあります。

また、エディタやビルドツールを使っていると、「empty rulesets」という見慣れない警告が出て焦ることもあるでしょう。

ここでは、:emptyが効かない場合の最終チェックリストとCSSファイル自体が空の時に出る警告の正体と解決策について解説します。

:emptyが効かない原因とCSSの警告
  • :emptyが効かない時のチェックリスト
  • エラーの意味と対処法

:emptyが効かない時のチェックリスト

:emptyが効かない!」とパニックになった時、原因はほぼ以下の3つのどれかに絞られます。

チェックリストを順番に確認するだけで、99%のトラブルは解決します。

  1. HTMLタグの間に「改行」や「半角スペース」が混ざっていないか?
    最も多い原因です。
    <div> </div>のようにスペースが1つでも入っていたり、HTMLを見やすくするエディタ上で改行してインデントをつけていたりすると空ではないと判定されます。
  2. inputなどの「空要素タグ」に指定していないか?
    input,img,br,hrなどのタグは、中に文字や要素を入れることができない仕様のタグです。
    これらに:emptyを指定すると「空である」と判定され、意図した挙動になりません。
  3. JavaScriptで「見えない文字」を入れていないか?
    JSでelement.innerHTML = "&nbsp;"などを挿入してしまっている場合、見た目は空でも内部的には文字が入っているため:emptyは効きません。
    空にしたいならelement.innerHTML = ""にしてください。

実務で:emptyのバグを防ぐには、:emptyの対象となる要素の出力は、手書きではなくJavaScriptやPHPなどのプログラム側で<div class="alert"></div>と1行で出力させることです。

手書きのHTMLは改行ミスが起きやすいため、システム側で制御するのが安全です。

⭕️ :empty が効かない時は、この3つの「罠」に落ちていないか確認せよ!

❌ 罠1: スペース入り
(空と判定されない)

❌ 罠2: inputタグ
(常に空と判定され続ける)

⭕️ 成功: 完全な空
(正しく消える)

↑完全に消えている↑

/* 💡 ボックスの基本設定(見えやすくするため色をつける) */
.box {
  width: 100%;
  height: 40px;
  background-color: #dc3545;
}

/* ⭕️ :empty の指定(空なら消す!) */
.box:empty {
  display: none;
}

/* 🚨 罠1のHTML:<div class=”box”> </div>(スペースが入っているから消えない) */
/* 🚨 罠2のCSS:input:empty は、valueがあっても永遠に適用される! */
HTMLコード表示
<div class="empty-warn-layout-wrapper">
  
  <p class="empty-warn-caption">⭕️ :empty が効かない時は、この3つの「罠」に落ちていないか確認せよ!</p>

  <div class="empty-warn-demo-area">
    
    <!-- ❌ 罠1:改行とスペース -->
    <div class="empty-warn-section">
      <p class="empty-warn-label">❌ 罠1: スペース入り<br><small>(空と判定されない)</small></p>
      <div class="warn-box is-space"> </div>
    </div>

    <!-- ❌ 罠2:inputタグへの誤用 -->
    <div class="empty-warn-section">
      <p class="empty-warn-label">❌ 罠2: inputタグ<br><small>(常に空と判定され続ける)</small></p>
      <input type="text" class="warn-input is-input-empty" value="文字あり">
    </div>

    <!-- ⭕️ 成功:完全にくっついたタグ -->
    <div class="empty-warn-section">
      <p class="empty-warn-label" style="color:#0d6efd;">⭕️ 成功: 完全な空<br><small>(正しく消える)</small></p>
      <div class="warn-box is-perfect-empty"></div>
      <p style="font-size: 11px; color:#6c757d; margin-top:5px; text-align:center;">↑完全に消えている↑</p>
    </div>

  </div>

  <div class="empty-warn-code-area">
    /* 💡 ボックスの基本設定(見えやすくするため色をつける) */<br>
    <span class="hl-blue">.box</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">100%;</span><br>
      <span class="hl-green">height:</span> <span class="hl-red">40px;</span><br>
      <span class="hl-green">background-color:</span> <span class="hl-red">#dc3545;</span><br>
    }<br><br>

    /* ⭕️ :empty の指定(空なら消す!) */<br>
    <span class="hl-blue">.box:empty</span> {<br>
      <span class="hl-green">display:</span> <span class="hl-red">none;</span><br>
    }<br><br>

    /* 🚨 罠1のHTML:<div class="box"> </div>(スペースが入っているから消えない) */<br>
    /* 🚨 罠2のCSS:input:empty は、valueがあっても永遠に適用される! */
  </div>

</div>
CSSコード表示
.empty-warn-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.empty-warn-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 30px;
  color: #198754;
  text-align: center;
}

.empty-warn-demo-area {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: 30px;
  background-color: #e9ecef;
  padding: 40px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.empty-warn-section {
  display: flex;
  flex-direction: column;
  width: 130px;
}

.empty-warn-label {
  font-size: 12px;
  font-weight: bold;
  color: #333;
  margin-bottom: 15px;
  text-align: center;
  line-height: 1.5;
  height: 40px;
}

/* ボックスのベース */
.warn-box {
  width: 100%;
  height: 40px;
  background-color: #dc3545; /* 警告の赤 */
  border-radius: 4px;
  border: 2px solid #b02a37;
}

/* =❌ 罠1:スペースが入っているため:emptyが効かず表示されたまま= */
.is-space:empty {
  display: none;
}

/* =❌ 罠2:inputタグに対する:emptyの誤用= */
.warn-input {
  width: 100%;
  height: 40px;
  box-sizing: border-box;
  text-align: center;
  font-size: 12px;
}
.is-input-empty:empty {
  background-color: #f8d7da;
  border: 2px solid #dc3545;
  color: #dc3545;
  /* 入力しても常に空判定なので赤いまま */
}

/* =⭕️ 成功:完全に空なので消える= */
.is-perfect-empty:empty {
  display: none;
}

/* =コード解説エリア= */
.empty-warn-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

エラーの意味と対処法

VS CodeなどのエディタでCSSを書いている時やSCSSをコンパイルした時にターミナルに出現する黄色い警告メッセージがあります。

これは:empty疑似クラスのエラーではありません。

「中身が何もない空っぽのCSSルールセットを作らないでください」という、CSSの構文チェックツールからの警告です。

例えば、クラス名だけ書いてプロパティを1つも書いていない状態です。

.btn {
  /* 何も書いていない!これが empty ruleset */
}

do not use empty rulesets」警告が出た場合の対処法は以下の通りです。

  1. 中身のない { } は即座に削除します。
    スタイルが必要になった時に初めて書くのが基本です。
  2. もし、意図的に「親要素のスタイルをリセットする」等の目的で何も指定したくない場合は、空にするのではなく、意味のあるリセットプロパティ(例:all: unset;margin: 0;など)を明記します。

⭕️ 「do not use empty rulesets」は :empty のエラーではない!

❌ 警告が出る書き方(Empty Ruleset)

/* 🚨 このように中身がないブロックを作ると警告が出ます */
.header-title {
  /* nothing… */
}

.sidebar-menu {

}

⭕️ 正しい書き方(プロパティを記述するか、削除する)

/* 💡 中身のないルールは削除し、必要なプロパティだけを書く! */
.header-title {
  font-size: 24px;
  font-weight: bold;
}

/* 💡 sidebar-menu はスタイルが不要になったので削除した */
HTMLコード表示
<div class="empty-warn-layout-wrapper">
  
  <p class="empty-warn-caption">⭕️ 「do not use empty rulesets」は :empty のエラーではない!</p>

  <div class="empty-warn-demo-area" style="flex-direction: column; align-items: center; gap: 20px;">
    
    <div class="empty-warn-section" style="width: 100%; max-width: 400px;">
      <p class="empty-warn-label">❌ 警告が出る書き方(Empty Ruleset)</p>
      
      <div class="empty-warn-code-area" style="border-left: 4px solid #dc3545; background-color: #2b2b2b;">
        <span class="hl-comment">/* 🚨 このように中身がないブロックを作ると警告が出ます */</span><br>
        <span class="hl-blue">.header-title</span> {<br>
          <span class="hl-comment">/* nothing... */</span><br>
        }<br><br>
        <span class="hl-blue">.sidebar-menu</span> {<br><br>
        }
      </div>
    </div>

    <div class="empty-warn-section" style="width: 100%; max-width: 400px;">
      <p class="empty-warn-label" style="color:#0d6efd;">⭕️ 正しい書き方(プロパティを記述するか、削除する)</p>
      
      <div class="empty-warn-code-area">
        <span class="hl-comment">/* 💡 中身のないルールは削除し、必要なプロパティだけを書く! */</span><br>
        <span class="hl-blue">.header-title</span> {<br>
          <span class="hl-green">font-size:</span> <span class="hl-red">24px;</span><br>
          <span class="hl-green">font-weight:</span> <span class="hl-red">bold;</span><br>
        }<br><br>
        <span class="hl-comment">/* 💡 sidebar-menu はスタイルが不要になったので削除した */</span>
      </div>
    </div>

  </div>
</div>
CSSコード表示
<style>
/* ※このブロックはコード解説の見た目を整えるためだけにCSSを使用しています */
/* ※実際の empty ruleset はCSSとしてブラウザに無視されるだけです */
</style>

まとめ

分かりやすいようにまとめを記載します。

本記事のまとめ
  • :empty疑似クラスは、要素内にテキストも子要素も全く存在しない「空状態」を判定する。
  • 主な用途は、中身がない要素を隠す(display: none;)、または空の時だけスタイルを当てること。
  • HTMLタグの間に改行、半角スペース、タブなどが1つでも含まれていると「空ではない」と判定されるため注意が必要。
  • 実務では、動的に出力される要素に対し、.alert:empty { display: none; }としてレイアウト崩れを防ぐ。
  • :not(:empty)を使うことで、「中身がある時だけ装飾する」という実装がCSSだけで可能になる。
  • <input><img>などの「空要素タグ」は空と判定されるため、:emptyを使って入力の有無を判定することはできない。
  • inputタグの未入力・入力済み判定にはplaceholder=" "を設定し、:placeholder-shown(または:not(:placeholder-shown))を使用する。
  • Gridで明示的に空のセルを作りたい場合はgrid-template-areasの値に.(ピリオド)を使用する。
  • CSSコンパイル時の「do not use empty rulesets」警告は:emptyのエラーではなく、中身が1つも書かれていないCSSブロックが存在することを指摘している。

よくある質問(FAQ)

:emptyを指定したのに要素が消えません。なぜですか?

HTMLタグの間に「改行」や「半角スペース」「タブ」が含まれていると、「空ではない」と判定されてしまうのが最も多い原因です。

:emptyを効かせるには、<div></div>のように開始タグと終了タグを密着させて書くか、JavaScriptなどのプログラム側で空白を含めずに出力させる必要があります。

未入力の<input>タグの枠線を:emptyで変えようとしましたが、入力しても色が戻りません。

<input><img>のような「終了タグを持たない空要素」は、仕様上子要素を持てないため、ユーザーが文字を入力しても「空」と判定され続けます。

フォームの未入力・入力済みをCSSだけで判定したい場合は、placeholder=" "を設定し:placeholder-shown(または:not(:placeholder-shown))疑似クラスを使用してください。

中身がない空の要素を完全に非表示にするには、どのプロパティを使えばいいですか?

要素:empty { display: none; }と記述するのが正解です。

width: 0; height: 0;opacity: 0;で隠そうとすると、設定されたpaddingが残ってしまったり、見えないだけで領域を占有してクリック判定の邪魔になったりするため、display: none;を使用して消すのがよいです。

「中身が空ではない時」だけスタイルを当てることは可能ですか?

はい、可能です。

否定の疑似クラス:not()と組み合わせて:not(:empty)と記述します。

これを使えば、JavaScriptでクラスを付け外ししなくても、「通知の数字が入った時だけアイコンを赤くする」「エラーメッセージが入った時だけ枠線を出す」といった動的なスタイリングがCSSだけで完結します。

CSSの::beforeや::afterで文字を入れた場合、その要素は:emptyと判定されますか?

はい、空(:empty)として判定されます。

:empty疑似クラスは、あくまで「HTMLのDOM構造上に子要素やテキストノードが存在するか」をチェックする仕様です。

CSSで後から付与された疑似要素(content)はDOMには存在しないため判定に影響を与えません。

したがって、親要素が:emptydisplay: none;になると、疑似要素も道連れになって非表示になります。

この記事を書いた人

sugiのアバター sugi Site operator

【経歴】玉川大学工学部卒業→新卒SIer企業入社→2年半後に独立→プログラミングスクール運営/受託案件→フリーランスエンジニア&SEOコンサル→Python特化のコンテンツサイトJob Code&UIコピペサイトCode Stock運営中

目次