CSS

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 は「要素を見せる/隠す」を指定し、基本的には“場所(レイアウト上の枠)を残す”かどうかの判断に使うプロパティです。

このページでできるようになること

まずは直感:visibility って何?

ざっくり言うと、visibility は「その要素を見えなくするけど、その場所(レイアウトの枠)は残す」ためのスイッチです。

正確な定義(仕様に沿った説明)

何のために存在するか

visibility は、要素の可視性(描画されるかどうか)を制御するためのプロパティです。典型的には visibility: hidden で「見た目だけ消して場所は残す」を実現します。

何に適用されるか(対象)

visibility は基本的にすべての要素に適用できます。値のうち collapse は表(テーブル)関連の要素で意味が強く、それ以外の要素では hidden と同等扱いになるのが一般的です。

できること / できないこと(制約)

できること
  • hidden で“見た目を消す”が、要素の場所(レイアウト上の枠)を残す
  • 親に visibility: hidden を付けた上で、子要素に visibility: visible を付けて子だけ復活させられる(後述)
  • テーブルの行などで collapse を使い、行/列を詰めて消す挙動を狙える(ブラウザ差あり)
できないこと(重要)
  • 要素のサイズや並び(レイアウト)を根本から変えること(それは主に display の仕事)
  • 「透明にしただけで、クリックできない状態にする」こと(透明=操作不可ではない。後述の opacity の罠)
  • スクリーンリーダー等の支援技術から確実に“存在を消す”こと(目的によってはHTML属性や別手段が必要)

影響範囲(レイアウト/描画/ユーザー操作/アクセシビリティ)

レイアウト
hidden は通常、要素の枠(幅・高さ・余白・配置)をそのまま残します。つまり「空白が残る」挙動になります。
描画
見た目(文字、背景、枠線など)が描画されません。見た目が消えるだけなので、レイアウト計算の発生とは別問題として考えます。
ユーザー操作
hidden の要素は基本的にクリックできず、フォーカスも当たりません。一方、opacity: 0 は“見えないのにクリックできる”になり得ます(混同注意)。
アクセシビリティ
「見えないけれどDOM上は存在する」状態は、読み上げ/フォーカス/タップ順に影響する可能性があります。見えないUIを操作できないこと意図しない読み上げが起きないことを確認します(後述)。

基本の書き方(最短の型)

最小サンプル(コピペ用)

CSS

.isHidden {
    visibility: hidden;
}

まずは visibility: hidden を覚えるのが最短です。「見えないけど場所は残る」挙動を作れます。

よく使う値/典型パターン

見える(初期状態)
visibility: visible;(初期値)
見えない(場所は残りがち)
visibility: hidden;
表の行/列を詰めて消す(ブラウザ差あり)
visibility: collapse;(主にテーブル要素向け)
親に合わせる
visibility: inherit;(継承を明示したいとき)

どこに書くか(外部CSS/ページ内style/インライン)

基本:外部CSS(推奨)
実務では「状態クラス(例:.isHidden)」として外部CSSにまとめ、HTML側はクラスの付け外しで制御するのが保守しやすいです。
ページ内 <style>
学習用デモや単体ページで完結させたいときに向いています(このページのデモはページ内にあります)。
インライン(例外)
style="visibility: hidden;" は一時的な検証には便利ですが、運用では差分が追いにくいので基本は避けます。

コピペで動く最小デモ(このページ内で表示)

デモは「visibilityopacitydisplay の違い」が壊れず再現できることを最優先にします。

見える:visibility: visible

Visible(場所あり)
見えるし、クリックやフォーカスも普通に可能。

初期状態。まずここを基準にします。

見えない(場所が残る):visibility: hidden

Hidden(見えない)
箱は見えないが、下の余白は残りやすい。

「空白が残る」ことが多い。ここが display と最大の違い。

透明(場所も操作も残る):opacity: 0

Opacity 0(見えない)
見えないのに、クリックできる“透明ボタン”になり得る。

落とし穴:見えない=操作不可ではありません。

操作確認:下のリンクは、モードによってフォーカスできたりできなかったりします。Tab キーで移動して確認してください。

フォーカス対象リンク(ここにTabが来る?) visible: ふつうにフォーカスできる / hidden: ここはフォーカスできない / opacity 0: 見えないのにフォーカスできる場合がある

補足:opacity: 0 を使うなら、意図に応じて pointer-events: nonearia-hidden / inert なども検討します(後述)。

HTML

<div class="box isHidden">Hidden</div>

CSS

.isHidden {
    visibility: hidden;
}

仕様として押さえるポイント(初心者が事故りやすい所)

継承する?(inheritance)
visibility継承します。親が hidden だと子も基本は hidden になります。ただし、子に visibility: visible を指定すると子だけ見える状態にできます(親の背景や枠は見えないまま、子が“浮いて見える”感じになります)。
初期値は?(initial)
初期値は visible です。指定しなければ見えるのが基本です。
適用対象は?(applies to)
基本的にはすべての要素に適用できます。collapse の意味は主にテーブル要素で強く、他の要素では hidden 相当になることが多いです。
%の基準は?(percentages)
visibility はキーワード値なので、% の基準のような話は関係しません。
算出値/使用値の考え方(computed/used value)
指定したキーワード(visible / hidden / collapse など)が基本的にそのまま使われます。DevTools の Computedvisibility を見て、意図した値になっているか確認します。
省略時の扱い、無効値の扱い
無効な値(例:visibility: hide;)は無視され、その宣言は効きません。結果として他のルール(または初期値 visible)になります。DevTools の Styles で「そもそも宣言が無効になっていないか」も見ます。
アニメーション可能?(animatable)
visibility は連続的に変化する値ではなく、基本はパッと切り替わる(離散的)です。ふわっと消したいなら opacity のアニメーションを使うのが一般的ですが、「見えないのに操作できる」問題に注意します。
ショートハンド/ロングハンド
visibility は単体のプロパティで、一般的なショートハンド/ロングハンドの関係はありません。

よくある勘違い・混同ポイント

visibility: hiddendisplay: none

両方とも見えなくなりますが、最大の違いは場所(レイアウトの枠)が残るかです。

  • visibility: hidden → 見えないが、枠は残りやすい(空白が残る)
  • display: none → 枠ごと消える(周りが詰まる)
visibility: hiddenopacity: 0

opacity: 0 は透明にするだけなので、クリックできたりフォーカスできたりすることがあります。visibility: hidden は基本的に操作できません。

  • 「アニメでふわっと消したい」→ opacity を使うことが多い
  • 「見えないなら操作も止めたい」→ visibility を併用することが多い
「動くけど危ない書き方」

透明にしただけで「非表示扱い」のつもりでいると、見えないリンクにフォーカスが当たる、透明ボタンが上に乗ってクリックを奪う、などの事故が起きます。“見えない=操作不可”を保証したいなら、visibilitypointer-events、HTML属性の併用を検討します。

実務でよくある使用例(制作会社の現場を想定)

並びを崩したくない一時的な非表示(レイアウト保持)

カード一覧やフォームの注釈などで、表示/非表示で周囲がガクッと動くのを避けたいときに visibility が候補になります(例:デバッグ用の補助線、検証中のラベル、レイアウトを固定したい予約枠)。

“見えないが場所は必要”なUIの土台

たとえば「表示前に高さを確保したい」など、設計上の都合で枠を先に確保したい場合があります。ただし、ユーザーにとって意味のない空白はストレスになるので、実際のUIではなるべく理由を持って使うのが安全です。

テーブルの行を消したいが、構造を保ちたい

表の行/列を条件で非表示にしたいとき、collapse が候補になります。ただしブラウザ差があるので、実務では display で行自体を消す、またはテーブルを別構造にする判断もよくあります(次の章で具体例)。

実務で起きがちな事故と回避策

「非表示のはずなのにクリックできる/できないが逆」

原因候補:opacity と混同している
opacity: 0 は見えないのにクリックできる場合があります。意図が「操作も止める」なら visibility(または pointer-events: none の併用)を検討します。
原因候補:上に透明な要素が重なっている
透明な要素(opacity: 0)が前面にあると、クリックが奪われます。DevTools の要素選択で、クリックできない場所の上に何が乗っているか確認します(Elements で該当要素を選び、Box Model と重なりを確認)。

「空白が残ってレイアウトが不自然」

原因候補:visibility を選ぶべきではない
空白が不要なら display: none の方が目的に合います。空白が必要な理由(揺れを防ぐ、予約枠を示す等)がないなら、設計を見直します。
原因候補:min-height や余白が効いている
visibility は枠を残すので、min-heightpadding があると空白が大きく見えます。DevTools の Box Model で余白とサイズを確認します。

「効かない(見えないはずが見えている)」

原因候補:上書き(詳細度/順序)
DevTools の Stylesvisibility が打ち消されていないか確認します。状態クラスより強いセレクタ(IDやインライン)が勝っていることがあります。
原因候補:子要素が visibility: visible で復活している
親を隠したつもりでも、子に visibility: visible が付いていると子だけ見えることがあります。DevTools の Computed で子要素の visibility も確認します。

テーブルでの collapse(最小デモ)

次は visibility: collapse の挙動を確認するための最小デモです。テーブル関連要素で「行が詰まる」ことが期待できますが、環境によって挙動差が出ることがあるため、実務では必ず確認します。

visibility: collapse のデモ(行を消す)
項目 状態 メモ
Row A visible 通常の行
Row B collapse この行は visibility: collapse
Row C visible 後続の行

Row B が「空白として残る」か「詰まって消える」かは、ブラウザで差が出ることがあります。

アクセシビリティ/UX観点での注意(必要な範囲で)

関連プロパティ・関連セレクタとの組み合わせ・相互作用

display
枠ごと消す(none)/ レイアウト方式を変える(flex など)を担当します。空白が不要なら display を優先しやすいです。
opacity
透明度を変えるだけです。アニメしやすい反面、「見えないのに操作できる」を作りやすいので、必要なら pointer-eventsvisibility の併用で事故を防ぎます。
pointer-events
クリック/タップを無効化できます。透明化(opacity)とセットで使うことがありますが、キーボードフォーカスまで止まるわけではない点に注意します。
HTML属性 hidden
HTML側で「非表示」を表す属性です。実装としては多くの環境で display: none 相当になります。意味(意図)をHTMLで示したいときの候補です。
aria-hidden / inert
支援技術への露出や操作性を制御するために使われます。visibility は“見た目と一部操作”の制御に寄っているので、「読み上げに残す/残さない」「一切操作させない」を確実にしたいときはこれらも検討します。
疑似クラス :focus-visible
非表示制御と組み合わせるときほど重要です。「見えるべきときに確実に見えるフォーカス」を保つのがUXの基本になります。

試験(Webクリエイター能力認定試験)で得点できる整理

用語ミニ辞典

visibility
要素が見えるかどうかを指定するプロパティ。hidden は見えなくするが、枠は残りやすい。
visible
visibility の初期値。要素は見える。
hidden
見えない。一般的にクリックやフォーカスの対象にならない。枠は残りやすい。
collapse
主にテーブル要素向け。行/列を詰めて消す意図の値だが、挙動差があり得る。
display: none
要素の枠ごと消える指定。周囲の要素が詰まる。

ひっかけポイント(短く)

「問われ方」っぽいミニ確認(解説付き)

  1. 問題:要素を非表示にしたいが、周囲のレイアウト(並び)を動かしたくない。どの指定が候補?

    解説:visibility: hidden が典型です。枠を残す方向に働きます。

  2. 問題:同じ「見えない」でも、周囲が詰まる指定はどれ?

    解説:display: none です。枠ごと消えるので周囲が詰まります。

  3. 問題:opacity: 0 にした要素が、クリックを奪ってしまうことがある。理由は?

    解説:透明になっても要素は存在し、ポインターイベントを受けることがあるからです。必要なら pointer-events: none などを併用します。

  4. 問題:親に visibility: hidden、子に visibility: visible を指定した。子は見える?

    解説:子に visible を指定すると、子だけ表示できます(ただし設計ミスになりやすいので用途を選びます)。

  5. 問題:テーブルの行を消したい。visibility: collapse を使ったが挙動が環境で違う。どうする?

    解説:ブラウザ差があり得ます。実務では display で行自体を消す、またはテーブルの設計を変えるなど、安定する方法を選びます。

よくある質問(FAQ)

visibility: hiddendisplay: none はどう違いますか?
hidden は見えないが枠は残りやすい、none は枠ごと消えて周囲が詰まる、という違いです。
「見えないのにクリックできる」ことがあります。なぜですか?
opacity: 0 は透明にするだけなので、要素が前面にあるとクリックを受けることがあります。意図が「操作不可」なら visibilitypointer-events の併用を検討します。
visibility: hidden にしたら空白が残りました。これで正しいですか?
はい、空白が残りやすいのが典型挙動です。空白が不要なら display: none を検討します。
親を hidden にしたのに、子が見えます
子に visibility: visible が指定されている可能性があります。DevTools の Computed で子の visibility を確認してください。
collapse はいつ使うべきですか?
主にテーブルの行/列を詰めて非表示にしたい意図で使います。ただし挙動差があり得るため、実務では要件に応じて display など別手段も検討します。

よくあるエラー/症状 早見表

症状:非表示にしたのに空白が残る
原因候補:visibility: hidden を使っている / min-heightpadding が効いている
最短の確認:DevTools の Box Model でサイズと余白を見る
解決の方向性:空白が不要なら display: none に切り替える、余白設計を見直す
症状:見えないのにクリックを奪う
原因候補:opacity: 0 の要素が前面にある
最短の確認:DevTools で要素を選択し、重なり(前面の要素)を確認
解決の方向性:visibility に切り替える、または pointer-events: none を併用する
症状:visibility: hidden が効かない
原因候補:上書き(詳細度/順序) / インラインやIDセレクタが勝っている
最短の確認:DevTools の Styles で打ち消し線を確認
解決の方向性:勝っているルールを整理し、状態クラスの適用箇所を見直す
症状:親を隠したのに子だけ見える
原因候補:子に visibility: visible が指定されている(復活)
最短の確認:子要素の Computedvisibility を確認
解決の方向性:意図がなければ子の指定を削除し、設計として一貫させる

まとめ:迷ったときの判断軸(短いチェックリスト)