【CSS】要素を非表示にする3つの方法を徹底比較

公開日 : 最終更新日 :

  • コーディング

こんにちは!AndHAエンジニアチームです。

今回は、コーディングをしていると「必ず」と言っていいほど使う、「CSSで要素を非表示にする方法」について徹底比較していきます。

では早速スタート!

方法① display: none

コーディング経験ある方なら幾度となく記述してきたであろう、display: none

今回取り上げる3つの非表示方法の中で、最もポピュラーといえるのではないでしょうか。

公式ドキュメントによる解説は下記になります。

要素の表示を無くし、レイアウトに影響を与えなくなります (文書は要素が存在しないかのように表示されます)。すべての子孫要素も表示がなくなります。 要素が通常占める空間を確保しつつ、実際には何も表示しないようにしたいのであれば、代わりに visibilityプロパティを使用してください。

要素の display の値に none を使用すると、その要素はアクセシビリティツリーから削除されます。すなわち、その要素とすべての子孫要素は読み上げ技術によって読み上げられなくなります。

要素を視覚的に隠したい場合は、よりアクセシブルな代替手段として、画面から視覚的に要素を削除しますが、画面リーダーのような支援技術が解析可能な状態を維持するための、プロパティの組み合わせを使用できます。

https://developer.mozilla.org/ja/docs/Web/CSS/display

つまり、ポイントとしては

  • 要素を完全にないものとし、表示領域もなくなる。
  • アクセシビリティツリーからも削除されるため、読み上げ機能等には認識されなくなる。
  • 子孫要素にも値が継承され、上書きができない。

といったところでしょうか。

方法② visibility: hidden

続いてはvisibility: hidden

こちらも非表示系の記述としてはポピュラーかと思いますが、display: noneとの違いはどこでしょうか。

要素のボックスは不可視になります (描画されません) が、レイアウトには通常通り影響します。子孫要素は visibilityが visibleに設定されていれば可視になります。(タブ順で操作された時などに) 要素はフォーカスを受け取ることができません。

要素の visibilityの値に hiddenを使用すると、 アクセシビリティツリーから削除されます。これは要素及びその子孫要素が読み上げ技術でアナウンスされない結果になります。

https://developer.mozilla.org/ja/docs/Web/CSS/visibility

つまり、ポイントとしては

  • 要素を非表示にするが、表示領域は残る。
  • アクセシビリティツリーからも削除されるため、読み上げ機能等には認識されなくなる。
  • 子孫要素にも値が継承されるが、visibleで上書き可能。

ということで、表示領域が残るか否か、また子孫要素への影響の違いがあるようです。

方法③ opacity: 0

最後はopacity: 0で透明度を0にする方法。

プロパティの意味も直感的にわかりやすく、ただ透明になるだけなのが予想できますが、どんな違いがあるのでしょうか。

要素は完全に透明です (つまり、不可視です)。

opacityの値は子要素に継承されませんが、要素のコンテンツを含む全体に適用されます。すなわち、ある要素とその子の不透明度が互いに異なっていたとしても、その要素の背景に対してはすべて同じ不透明度になります。

https://developer.mozilla.org/ja/docs/Web/CSS/opacity

ポイントとしては、

  • 要素が透明になるだけで、表示領域も残る。
  • アクセシビリティツリーからは削除されない。
  • 子孫要素にも値が継承され、上書きができるが、親要素の透明度に影響を受ける。

前述の2つとは毛色が少し違いますね。見た目が透明になるだけで、アクセシビリティツリーへの影響も出ません。

子孫要素ですが、0は0のままどうしようもありませんでした。が、値は継承されているため、親要素にopacity: 0.5、子要素にも0.5を指定すると、子要素の透明度は0.25になるようです。

追加検証

では、ここまで3つの方法を見てきましたが、ここからは実用的な部分で深掘り検証していきます。

視覚的にわかるよう検証用コードを用意しましたので、併せてご覧ください。

See the Pen visibility_test by and_ima (@and-im) on CodePen.

検証① ソースコードへの影響

上記のCodePenではわかりにくいかもしれませんが、ページのソースコードを表示すると、視覚的には見えていない要素も全て表示されます。

目で見えないし読み上げもされない要素でも、右クリックで簡単に見られてしまうということですね。

検証② transition効果

hoverしたときにふわっと変化させるみたいな設定をするCSSプロパティのtransition

CodePenからもわかる通り、transition効果が正しく効いたのはopacityだけでした。

ほかの2つはあるものを非表示にする、逆にないものを表示するという、中間の無い0か100の操作であるということですね。

検証③ テキスト選択

ここはおそらくアクセシビリティツリーへの影響と相関すると考えられましたが、念の為検証してみます。

見えている要素も見えていない要素も、左クリック+ドラッグでテキスト選択をし、コピー&ペーストしてみました。

結果は以下。

通常の表示状態子要素

display: none のtransitionテスト


が子要素で上書き可能

visibility: hidden のtransitionテスト

opacity: 0が子要素に継承

opacity: 0が子要素で上書きできない

opacity: 0 のtransitionテスト

通常の表示状態とtransitionテストの行は無視するとして、display: nonevisibility: hiddenをしている要素は選択できませんでした。

対して、visibility: visibleで上書きした子要素、opacity: 0をした要素は選択ができました。

やはり、アクセシビリティツリーへの影響とは相関があるようです。

Google ポリシーへの影響

Googleではウェブ検索のスパムに関するポリシーを公開しています。

その中に「隠しテキストや隠しリンク」の項がありますが、要素の非表示についての記述がありました。

隠しテキストや隠しリンクは、検索エンジンを操作することのみを目的としてページにコンテンツを配置しながら、人間のユーザーには見えにくいようにする行為です。Google のポリシーに違反する隠しテキストや隠しリンクの例としては、次のようなものが挙げられます。

  • 白の背景で文字の色を白にする
  • テキストを画像の背後に置く
  • CSS を使用してテキストを画面の外に配置する
  • フォントサイズまたは不透明度を 0 に設定する
  • 目立たない 1 文字(段落の中頃にあるハイフンなど)のみをリンクにすることで隠す

現在では、コンテンツの表示 / 非表示を動的に制御する方法を活用して、ユーザー エクスペリエンスを高めるウェブデザイン要素が多数存在します。以下の要素は Google のポリシーに違反していません。

  • 追加コンテンツの表示 / 非表示を切り替えるアコーディオンやタブ形式のコンテンツ
  • 複数の画像やテキスト段落を切り替えるスライドショーやスライダー
  • ユーザーが要素に対してなんらかの操作をしたときに追加コンテンツを表示するツールチップや類似のテキスト
  • スクリーン リーダーを使用するユーザーのエクスペリエンスを高めることを目的として、スクリーン リーダーのみがアクセスできるテキスト
https://developers.google.com/search/docs/essentials/spam-policies?hl=ja&visit_id=638113588992650738-39614180&rd=1#hidden-text-and-links

つまり、ユーザーを騙す目的で要素を見えないような処理をすることは、Googleのポリシーに違反することになるので注意しましょう。

アコーディオンやタブコンテンツ、スライダー等のUIは違反でないと記載されていますね。

まとめ

いかがでしたか。

ここまでの内容を、一覧にしてまとめてみました。

 ソースコードアクセシビリティツリーテキスト選択レイアウトへの影響子孫要素での上書きtransition効果
display: none表示される削除されるできない要素が完全になくなり表示領域も残らないできない効かない
visibility: hidden表示される削除されるできない表示領域は残るできる効かない
opacity: 0表示される削除されないできる表示領域は残るできない(親要素が0以外の数値であれば、子孫要素にも値が継承され上書きができるが、親要素の透明度に影響を受ける。)効く

コーディングの際はそれぞれの特性を理解しながら、適切なプロパティを選択していきましょう!

ではまた!

合わせて読みたい!