CSS
この記事では「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 は「要素を見せる/隠す」を指定し、基本的には“場所(レイアウト上の枠)を残す”かどうかの判断に使うプロパティです。
- Table Of Contents
このページでできるようになること
visibilityが「何を変える/何を変えない」か(見た目・操作・レイアウト)を説明できるvisible/hidden/collapseの役割と使い分けを判断できるdisplay: noneやopacity: 0と混同せず、目的に合う指定を選べる- 「クリックできない」「フォーカスが当たらない」「場所が空いたまま」などの症状を DevTools で切り分けられる
- 実務でありがちな“事故”(上書き・継承・アクセシビリティ)を避けた実装ができる
- 試験で問われやすいポイント(違い・適用対象・継承)を整理できる
まずは直感: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;"は一時的な検証には便利ですが、運用では差分が追いにくいので基本は避けます。
コピペで動く最小デモ(このページ内で表示)
デモは「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;
}
仕様として押さえるポイント(初心者が事故りやすい所)
- 継承する?(inheritance)
-
visibilityは継承します。親がhiddenだと子も基本はhiddenになります。ただし、子にvisibility: visibleを指定すると子だけ見える状態にできます(親の背景や枠は見えないまま、子が“浮いて見える”感じになります)。 - 初期値は?(initial)
- 初期値は
visibleです。指定しなければ見えるのが基本です。 - 適用対象は?(applies to)
- 基本的にはすべての要素に適用できます。
collapseの意味は主にテーブル要素で強く、他の要素ではhidden相当になることが多いです。 - %の基準は?(percentages)
visibilityはキーワード値なので、%の基準のような話は関係しません。- 算出値/使用値の考え方(computed/used value)
- 指定したキーワード(
visible/hidden/collapseなど)が基本的にそのまま使われます。DevTools の Computed でvisibilityを見て、意図した値になっているか確認します。 - 省略時の扱い、無効値の扱い
- 無効な値(例:
visibility: hide;)は無視され、その宣言は効きません。結果として他のルール(または初期値visible)になります。DevTools の Styles で「そもそも宣言が無効になっていないか」も見ます。 - アニメーション可能?(animatable)
visibilityは連続的に変化する値ではなく、基本はパッと切り替わる(離散的)です。ふわっと消したいならopacityのアニメーションを使うのが一般的ですが、「見えないのに操作できる」問題に注意します。- ショートハンド/ロングハンド
visibilityは単体のプロパティで、一般的なショートハンド/ロングハンドの関係はありません。
よくある勘違い・混同ポイント
visibility: hiddenとdisplay: none-
両方とも見えなくなりますが、最大の違いは場所(レイアウトの枠)が残るかです。
visibility: hidden→ 見えないが、枠は残りやすい(空白が残る)display: none→ 枠ごと消える(周りが詰まる)
visibility: hiddenとopacity: 0-
opacity: 0は透明にするだけなので、クリックできたりフォーカスできたりすることがあります。visibility: hiddenは基本的に操作できません。- 「アニメでふわっと消したい」→
opacityを使うことが多い - 「見えないなら操作も止めたい」→
visibilityを併用することが多い
- 「アニメでふわっと消したい」→
- 「動くけど危ない書き方」
-
透明にしただけで「非表示扱い」のつもりでいると、見えないリンクにフォーカスが当たる、透明ボタンが上に乗ってクリックを奪う、などの事故が起きます。“見えない=操作不可”を保証したいなら、
visibilityやpointer-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-heightやpaddingがあると空白が大きく見えます。DevTools の Box Model で余白とサイズを確認します。
「効かない(見えないはずが見えている)」
- 原因候補:上書き(詳細度/順序)
- DevTools の Styles で
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 が「空白として残る」か「詰まって消える」かは、ブラウザで差が出ることがあります。
アクセシビリティ/UX観点での注意(必要な範囲で)
- 見えない要素にフォーカスが当たらないか確認:
visibility: hiddenは基本フォーカス不可ですが、opacity: 0はフォーカス可能なままになり得ます - フォーカス表示は消さない:非表示制御と同時に、
:focus-visibleの見やすい表示を維持します - 空白の意味を持たせる:意味のない空白は読みづらさにつながるので、レイアウト保持が本当に必要か見直します
- “支援技術から消す”目的は別途検討:状況によっては
aria-hidden="true"、またはインタラクティブ要素の無効化(disabled/inert)が必要です - 動きは控えめ:ふわっと消す演出が必要なら
opacityを使うことがありますが、prefers-reduced-motionに配慮し、見えない操作を作らないことを優先します
関連プロパティ・関連セレクタとの組み合わせ・相互作用
display- 枠ごと消す(
none)/ レイアウト方式を変える(flexなど)を担当します。空白が不要ならdisplayを優先しやすいです。 opacity- 透明度を変えるだけです。アニメしやすい反面、「見えないのに操作できる」を作りやすいので、必要なら
pointer-eventsやvisibilityの併用で事故を防ぎます。 pointer-events- クリック/タップを無効化できます。透明化(
opacity)とセットで使うことがありますが、キーボードフォーカスまで止まるわけではない点に注意します。 - HTML属性
hidden - HTML側で「非表示」を表す属性です。実装としては多くの環境で
display: none相当になります。意味(意図)をHTMLで示したいときの候補です。 aria-hidden/inert- 支援技術への露出や操作性を制御するために使われます。
visibilityは“見た目と一部操作”の制御に寄っているので、「読み上げに残す/残さない」「一切操作させない」を確実にしたいときはこれらも検討します。 - 疑似クラス
:focus-visible - 非表示制御と組み合わせるときほど重要です。「見えるべきときに確実に見えるフォーカス」を保つのがUXの基本になります。
試験(Webクリエイター能力認定試験)で得点できる整理
用語ミニ辞典
visibility- 要素が見えるかどうかを指定するプロパティ。
hiddenは見えなくするが、枠は残りやすい。 visiblevisibilityの初期値。要素は見える。hidden- 見えない。一般的にクリックやフォーカスの対象にならない。枠は残りやすい。
collapse- 主にテーブル要素向け。行/列を詰めて消す意図の値だが、挙動差があり得る。
display: none- 要素の枠ごと消える指定。周囲の要素が詰まる。
ひっかけポイント(短く)
visibility: 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で行自体を消す、またはテーブルの設計を変えるなど、安定する方法を選びます。
よくある質問(FAQ)
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が効いている
最短の確認:DevTools の Box Model でサイズと余白を見る
解決の方向性:空白が不要ならdisplay: noneに切り替える、余白設計を見直す - 症状:見えないのにクリックを奪う
-
原因候補:
opacity: 0の要素が前面にある
最短の確認:DevTools で要素を選択し、重なり(前面の要素)を確認
解決の方向性:visibilityに切り替える、またはpointer-events: noneを併用する - 症状:
visibility: hiddenが効かない -
原因候補:上書き(詳細度/順序) / インラインやIDセレクタが勝っている
最短の確認:DevTools の Styles で打ち消し線を確認
解決の方向性:勝っているルールを整理し、状態クラスの適用箇所を見直す - 症状:親を隠したのに子だけ見える
-
原因候補:子に
visibility: visibleが指定されている(復活)
最短の確認:子要素の Computed でvisibilityを確認
解決の方向性:意図がなければ子の指定を削除し、設計として一貫させる
まとめ:迷ったときの判断軸(短いチェックリスト)
- 空白を残したい → まず
visibility: hiddenを検討する - 空白を残したくない → まず
display: noneを検討する - ふわっと消したい →
opacityを使うが、操作/読み上げの事故を先に潰す - 「効かない」なら Computed の
visibilityと Styles の勝者 を確認する - テーブルの
collapseはブラウザ差があり得るので、必ず実機で確認して選ぶ