CSSの便利な疑似セレクタ「:empty」と「:blank」、その違いと賢い使い方
Post on:2018年9月25日
エラーメッセージを実装する際、エラーがある時とエラーがない時の区別は「:empty」や「:blank」を使用すると、非常に簡単にスタイルを定義することができます。
「:empty」と「:blank」、その違いと実際にどのように使用するのか、どちらが便利なのかを紹介します。
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- 私は誤解していた
- 「:empty」と「:blank」の違い
- 「:empty」と「:blank」を実際に使用する場面
- 「:empty」の方が十分ではないと思った理由
- 「:empty」と「:blank」のサポートブラウザ
- まとめ
私は誤解していた
私は1ヵ月前のツイートで、「:empty」と「:blank」についてひどい誤解をしてました。
「:empty」は有用ではなく、「:blank」は「:empty」よりはるかに有用であると。
しかし、これは間違いです。
「:empty」は非常に有用で、むしろ「:blank」が現状使えないと思います。
それがなぜなのか、「:empty」と「:blank」について解説します。
「:empty」と「:blank」の違い
「:empty」は疑似セレクタで、空の要素を選択できます。
1 2 3 |
:empty { /* スタイルを定義 */ } |
空の要素とは、その中に何もデータを持たない要素です。空白スペースさえも含むことはできません。
1 2 |
<!-- 空の要素の例 --> <div></div> |
空の要素はデータを持つことはできませんが、コメントを含めることはできます。
1 2 |
<!-- コメントは可 --> <div><!-- コメント --></div> |
「:blank」は「:empty」をパワーアップした形です。「:blank」では、空白スペースを持つことができます。
1 2 |
<!-- :blankでは一致するけど、:emptyでは一致しない --> <div> </div> |
「:empty」と「:blank」を実際に使用する場面
「:empty」と「:blank」は、次の場合に便利です。
- 空の要素をスタイルする場合
- 空の状態を作成する場合
空の要素をスタイルする場合
空の要素をスタイルするというのは、例えば、文言が変わるエラーメッセージを表示するための空のdiv要素をスタイルする場合です。
1 2 3 4 5 |
<!-- エラーがない場合 --> <div class="error"></div> <!-- エラーがある場合 --> <div class="error">Whoops! Something went wrong!</div> |
div要素には.errorが付与されています。スタイルを定義する際に「:empty」を使用しない場合は、classや属性に依存しなければなりません。これは冗長な感じがします。
1 2 |
<!-- エラーがある場合 --> <div class="error" data-state="error">Whoops! Something went wrong!</div> |
1 2 3 4 5 6 7 8 9 |
.error { display: none; background-color: hsl(0, 20%, 50%); padding: 0.5em 0.75em; } .error[data-state="error"] { display: block; } |
しかし、「:empty」を使用すると、余分なclassや属性は必要ありません。.errorを直接スタイルすることができます。「display: none;」さえ必要ありません。
1 2 3 4 5 6 7 8 |
.error { background-color: hsl(0, 20%, 50%); padding: 0.5em 0.75em; } .error:empty { padding: 0; } |
実際の動作は、下記のデモで確認できます。
「.error:empty」から「padding: 0;」を削除してみてください。レッドの背景が表示されるはずです。
See the Pen Empty demo by Zell Liew (@zellwk) on CodePen.
空の状態を作成する場合
続いて、空の状態を作成する場合を見てましょう。
リスト要素で実装したTODOリストで、最初の状態はリストの中身がゼロです。
あなたはゼロのときに何を表示しますか?
このゼロの状態は、空の状態(empty state)と呼ばれます。
リストがゼロの時は、div要素でメッセージを表示するようにしてみます。この場合、「:empty」を使用すると、ゼロの時とゼロでない時のスタイルを簡単に定義できます。
1 2 3 4 5 6 |
<ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> <div class="empty-state"></div> |
1 2 3 4 5 6 7 |
.empty-state { display: none; } ul:empty + .empty-state { display: block; } |
私はこの「:empty」を使用したテクニックをA Todo Listから学びました。
メモ: 空の状態(empty state)はコンテンツを作成する上で必ず必要です。さらに詳しく学びたい時は、Invisionの記事が参考になります。
「:empty」の方が十分ではないと思った理由
これには2つの理由があります。
- 制作者の経験不足
- JavaScriptで空白スペースを整える必要があるため
1つ目の理由はもっともですが、あまり重要ではありません。しかし、2つ目の理由は重要です。私はこの記事を書いている時にはなぜうまくいかなかったのか分かりませんでしたが、コメントのおかげで理解できました。
それぞれ詳しく説明します。
制作者の経験不足
先ほど使用したTODOリストを例にします。
1 2 3 4 5 6 |
<ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> <div class="empty-state"></div> |
あなたは「:empty」が機能しているかどうか、どのように調べますか?
私はcommand+Xでli要素をカットして削除します。3つのli要素を削除すると、下記のようになります。
1 2 |
<ul> </ul> |
ここまでで、上記のHTMLが「:empty」をトリガーにしないことが分かります。そうです、「:empty」は要素に空白スペースがない場合にのみ機能します。つまり、私は「:empty」のために空白スペースを削除しなければならなかったということです。
これはまぁ、小さな問題と言えるでしょう。
JavaScriptで空白スペースを整える必要があるため
空白スペースは、JavaScriptで手動で切り取る必要があります。実際に例を見てましょう、そうすれば何を意味するのかが分かると思います。
もう一度、TODOリストを例に使用します。
1 2 3 4 |
<ul> <li>Item 1</li> </ul> <div class="empty-state"></div> |
空の状態(empty state)が機能するには、ul要素からli要素を削除する必要があります。シンプルなJavaScriptを使用する場合は、removeChildで実現できます。
1 2 3 4 |
const ul = document.querySelector('ul') const li = ul.children[0] ul.removeChild(li) |
removeChildはインスペクタに表示されない場合でも、空白スペースを含むHTMLを生成します。childNodesプロパティでテキストノード(つまり空白スペース)を調べることができます。
空白スペースはremoveChildで削除できないので、あなた自身で削除する必要があります。これは余分なJavaScriptです。
1 2 3 4 5 6 7 8 |
const ul = document.querySelector('ul') const li = ul.children[0] ul.removeChild(li) if (ul.children.length === 0) { ul.innerHTML = '' } |
実際の動作は、下記デモで確認できます。
See the Pen Empty demo with todolist by Zell Liew (@zellwk) on CodePen.
「:empty」と「:blank」のサポートブラウザ
2018年9月現在、「:empty」はすべてのブラウザにサポートされていますが、「:blank」はごく一部のブラウザにしかサポートされていません。
このことだけでも「:empty」を「:blank」より使用する理由になります。
「:blank」は、主要なブラウザのほとんどでサポートされていません。
「:blank」がすべてのブラウザにサポートされる日がくることを願っています。
まとめ
「:empty」と「:blank」は空の要素をスタイルし、空の状態(empty state)を簡単にスタイルできます。
「:blank」は「:empty」よりも機能的に優れているため、より良い制作環境が提供されます。しかし、「:blank」のサポートブラウザは十分ではありません。「:empty」のサポートブラウザは十分で、すぐに使用することができます。
「:empty」と「:blank」について、あなたの考えを教えてください。
sponsors