The CSS visibility property controls whether an element is visible while typically keeping its layout space, helping you choose between “hide but keep space” and other approaches like display or opacity.
visibility は「要素を見せる/隠す」を指定し、基本的には“場所(レイアウト上の枠)を残す”かどうかの判断に使うプロパティです。
visibility が「何を変える/何を変えない」か(見た目・操作・レイアウト)を説明できるvisible / hidden / collapse の役割と使い分けを判断できるdisplay: none や opacity: 0 と混同せず、目的に合う指定を選べるvisibility って何?ざっくり言うと、visibility は「その要素を見えなくするけど、その場所(レイアウトの枠)は残す」ためのスイッチです。
visibility は、要素の可視性(描画されるかどうか)を制御するためのプロパティです。典型的には visibility: hidden で「見た目だけ消して場所は残す」を実現します。
visibility は基本的にすべての要素に適用できます。値のうち collapse は表(テーブル)関連の要素で意味が強く、それ以外の要素では hidden と同等扱いになるのが一般的です。
hidden で“見た目を消す”が、要素の場所(レイアウト上の枠)を残すvisibility: hidden を付けた上で、子要素に visibility: visible を付けて子だけ復活させられる(後述)collapse を使い、行/列を詰めて消す挙動を狙える(ブラウザ差あり)display の仕事)opacity の罠)hidden は通常、要素の枠(幅・高さ・余白・配置)をそのまま残します。つまり「空白が残る」挙動になります。hidden の要素は基本的にクリックできず、フォーカスも当たりません。一方、opacity: 0 は“見えないのにクリックできる”になり得ます(混同注意)。CSS
.isHidden {
visibility: hidden;
}
まずは visibility: hidden を覚えるのが最短です。「見えないけど場所は残る」挙動を作れます。
visibility: visible;(初期値)visibility: hidden;visibility: collapse;(主にテーブル要素向け)visibility: inherit;(継承を明示したいとき).isHidden)」として外部CSSにまとめ、HTML側はクラスの付け外しで制御するのが保守しやすいです。<style>style="visibility: hidden;" は一時的な検証には便利ですが、運用では差分が追いにくいので基本は避けます。デモは「visibility と opacity と display の違い」が壊れず再現できることを最優先にします。
見える:visibility: visible
初期状態。まずここを基準にします。
見えない(場所が残る):visibility: hidden
「空白が残る」ことが多い。ここが display と最大の違い。
透明(場所も操作も残る):opacity: 0
落とし穴:見えない=操作不可ではありません。
操作確認:下のリンクは、モードによってフォーカスできたりできなかったりします。Tab キーで移動して確認してください。
補足:opacity: 0 を使うなら、意図に応じて pointer-events: none や aria-hidden / inert なども検討します(後述)。
HTML
<div class="box isHidden">Hidden</div>
CSS
.isHidden {
visibility: hidden;
}
visibility は継承します。親が hidden だと子も基本は hidden になります。ただし、子に visibility: visible を指定すると子だけ見える状態にできます(親の背景や枠は見えないまま、子が“浮いて見える”感じになります)。visible です。指定しなければ見えるのが基本です。collapse の意味は主にテーブル要素で強く、他の要素では hidden 相当になることが多いです。visibility はキーワード値なので、% の基準のような話は関係しません。visible / hidden / collapse など)が基本的にそのまま使われます。DevTools の Computed で visibility を見て、意図した値になっているか確認します。visibility: hide;)は無視され、その宣言は効きません。結果として他のルール(または初期値 visible)になります。DevTools の Styles で「そもそも宣言が無効になっていないか」も見ます。visibility は連続的に変化する値ではなく、基本はパッと切り替わる(離散的)です。ふわっと消したいなら opacity のアニメーションを使うのが一般的ですが、「見えないのに操作できる」問題に注意します。visibility は単体のプロパティで、一般的なショートハンド/ロングハンドの関係はありません。visibility: hidden と display: none両方とも見えなくなりますが、最大の違いは場所(レイアウトの枠)が残るかです。
visibility: hidden → 見えないが、枠は残りやすい(空白が残る)display: none → 枠ごと消える(周りが詰まる)visibility: hidden と opacity: 0opacity: 0 は透明にするだけなので、クリックできたりフォーカスできたりすることがあります。visibility: hidden は基本的に操作できません。
opacity を使うことが多いvisibility を併用することが多い透明にしただけで「非表示扱い」のつもりでいると、見えないリンクにフォーカスが当たる、透明ボタンが上に乗ってクリックを奪う、などの事故が起きます。“見えない=操作不可”を保証したいなら、visibility や pointer-events、HTML属性の併用を検討します。
カード一覧やフォームの注釈などで、表示/非表示で周囲がガクッと動くのを避けたいときに visibility が候補になります(例:デバッグ用の補助線、検証中のラベル、レイアウトを固定したい予約枠)。
たとえば「表示前に高さを確保したい」など、設計上の都合で枠を先に確保したい場合があります。ただし、ユーザーにとって意味のない空白はストレスになるので、実際のUIではなるべく理由を持って使うのが安全です。
表の行/列を条件で非表示にしたいとき、collapse が候補になります。ただしブラウザ差があるので、実務では display で行自体を消す、またはテーブルを別構造にする判断もよくあります(次の章で具体例)。
opacity と混同しているopacity: 0 は見えないのにクリックできる場合があります。意図が「操作も止める」なら visibility(または pointer-events: none の併用)を検討します。opacity: 0)が前面にあると、クリックが奪われます。DevTools の要素選択で、クリックできない場所の上に何が乗っているか確認します(Elements で該当要素を選び、Box Model と重なりを確認)。visibility を選ぶべきではないdisplay: none の方が目的に合います。空白が必要な理由(揺れを防ぐ、予約枠を示す等)がないなら、設計を見直します。min-height や余白が効いているvisibility は枠を残すので、min-height や padding があると空白が大きく見えます。DevTools の Box Model で余白とサイズを確認します。visibility が打ち消されていないか確認します。状態クラスより強いセレクタ(IDやインライン)が勝っていることがあります。visibility: visible で復活しているvisibility: visible が付いていると子だけ見えることがあります。DevTools の Computed で子要素の visibility も確認します。collapse(最小デモ)次は visibility: collapse の挙動を確認するための最小デモです。テーブル関連要素で「行が詰まる」ことが期待できますが、環境によって挙動差が出ることがあるため、実務では必ず確認します。
| 項目 | 状態 | メモ |
|---|---|---|
| Row A | visible | 通常の行 |
| Row B | collapse | この行は visibility: collapse |
| Row C | visible | 後続の行 |
Row B が「空白として残る」か「詰まって消える」かは、ブラウザで差が出ることがあります。
visibility: hidden は基本フォーカス不可ですが、opacity: 0 はフォーカス可能なままになり得ます:focus-visible の見やすい表示を維持しますaria-hidden="true"、またはインタラクティブ要素の無効化(disabled / inert)が必要ですopacity を使うことがありますが、prefers-reduced-motion に配慮し、見えない操作を作らないことを優先しますdisplaynone)/ レイアウト方式を変える(flex など)を担当します。空白が不要なら display を優先しやすいです。opacitypointer-events や visibility の併用で事故を防ぎます。pointer-eventsopacity)とセットで使うことがありますが、キーボードフォーカスまで止まるわけではない点に注意します。hiddendisplay: none 相当になります。意味(意図)をHTMLで示したいときの候補です。aria-hidden / inertvisibility は“見た目と一部操作”の制御に寄っているので、「読み上げに残す/残さない」「一切操作させない」を確実にしたいときはこれらも検討します。:focus-visiblevisibilityhidden は見えなくするが、枠は残りやすい。visiblevisibility の初期値。要素は見える。hiddencollapsedisplay: nonevisibility: hidden は枠が残りやすい。display: none は枠が消えるopacity: 0 は透明になるだけ。操作できる場合があるvisibility は継承する。親 hidden でも子 visible で復活できるcollapse は主にテーブル向けで、他では hidden 相当になりがち問題:要素を非表示にしたいが、周囲のレイアウト(並び)を動かしたくない。どの指定が候補?
解説:visibility: hidden が典型です。枠を残す方向に働きます。
問題:同じ「見えない」でも、周囲が詰まる指定はどれ?
解説:display: none です。枠ごと消えるので周囲が詰まります。
問題:opacity: 0 にした要素が、クリックを奪ってしまうことがある。理由は?
解説:透明になっても要素は存在し、ポインターイベントを受けることがあるからです。必要なら pointer-events: none などを併用します。
問題:親に visibility: hidden、子に visibility: visible を指定した。子は見える?
解説:子に visible を指定すると、子だけ表示できます(ただし設計ミスになりやすいので用途を選びます)。
問題:テーブルの行を消したい。visibility: collapse を使ったが挙動が環境で違う。どうする?
解説:ブラウザ差があり得ます。実務では display で行自体を消す、またはテーブルの設計を変えるなど、安定する方法を選びます。
visibility: hidden と display: none はどう違いますか?hidden は見えないが枠は残りやすい、none は枠ごと消えて周囲が詰まる、という違いです。opacity: 0 は透明にするだけなので、要素が前面にあるとクリックを受けることがあります。意図が「操作不可」なら visibility や pointer-events の併用を検討します。visibility: hidden にしたら空白が残りました。これで正しいですか?display: none を検討します。hidden にしたのに、子が見えますvisibility: visible が指定されている可能性があります。DevTools の Computed で子の visibility を確認してください。collapse はいつ使うべきですか?display など別手段も検討します。visibility: hidden を使っている / min-height や padding が効いているdisplay: none に切り替える、余白設計を見直す
opacity: 0 の要素が前面にあるvisibility に切り替える、または pointer-events: none を併用する
visibility: hidden が効かないvisibility: visible が指定されている(復活)visibility を確認visibility: hidden を検討するdisplay: none を検討するopacity を使うが、操作/読み上げの事故を先に潰すvisibility と Styles の勝者 を確認するcollapse はブラウザ差があり得るので、必ず実機で確認して選ぶ