要素を画面から「見えなくしたい」とき、真っ先に思い浮かぶのは display: none かもしれません。しかし、同じ「隠す」でも visibility プロパティを使うと、要素の場所(レイアウト)を保ったまま見た目だけを消せます。この記事では、visibility の基本的な使い方から、混同しやすい display: none や opacity との違い、アニメーションでの活用まで、初心者の方にもわかるように解説します。
目次
visibility は「見た目だけ」を消すプロパティ
visibility は、要素を表示するか非表示にするかを切り替えるプロパティです。ポイントは、非表示にしてもその要素が占めていた場所はそのまま残るという点です。つまり見た目は消えても、まわりのレイアウトは動きません。よく使う値は次の3つです。
| 値 | 効果 |
|---|---|
visible | 表示する(初期値) |
hidden | 非表示にする。ただし場所(レイアウト)は残る |
collapse | 主にテーブルの行・列を、場所ごと消すために使う |
基本の書き方はとてもシンプルです。隠したい要素に visibility: hidden を指定するだけです。
.hidden {
/* 見えなくなるが、場所はそのまま残る */
visibility: hidden;
}
.shown {
visibility: visible; /* 初期値。表示する */
}
下のデモで実際の挙動を見てみましょう。4つのボックスのうち、B に visibility: hidden、C に display: none を指定しています。B は姿が消えてもすき間(場所)が残るのに対し、C は場所ごと消えて D が左に詰まっているのがわかります。CSS タブの値を書き換えて、動きを比べてみてください。
<div class="row">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
</div>
<p class="note">B は visibility: hidden(見えないが場所は残る)/C は display: none(場所ごと消える)</p>
.row {
display: flex;
gap: 8px;
align-items: center;
padding: 16px;
background: #f4f4f4;
}
.box {
width: 56px;
height: 56px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-family: sans-serif;
background: #007bff;
border-radius: 6px;
}
/* 見えなくなるが、場所(レイアウト)はそのまま残る */
.b {
visibility: hidden;
}
/* 要素ごと消え、あとの要素が詰まる */
.c {
display: none;
}
.note {
margin: 0;
padding: 0 16px 16px;
font-family: sans-serif;
font-size: 13px;
color: #555;
}
display: none との違いをおさえる
visibility: hidden と display: none は、どちらも要素を見えなくしますが、レイアウトへの影響がまったく違います。前者は場所を残して見た目だけを消すのに対し、後者は要素そのものを無かったことにして場所も詰めるという違いです。主な違いを表にまとめます。
| 観点 | visibility: hidden | display: none |
|---|---|---|
| 場所(レイアウト) | 残る | 詰まって消える |
| まわりの要素 | 動かない | ずれて詰まる |
| 子要素だけ再表示 | できる(子に visible を指定可) | できない |
| transition の対象 | なる | ならない |
使い分けの目安はこうです。あとで元の場所に戻したい・レイアウトを崩したくないときは visibility: hidden、要素そのものを完全に無い状態にしたいときは display: none を選びます。たとえばタブ切り替えでコンテンツの高さをそろえたい場合は前者が、アコーディオンのように開閉で高さを変えたい場合は後者が向いています。
子要素だけを再表示できる
visibility は継承されるプロパティなので、親に hidden を指定すると子もまとめて隠れます。ただし display: none と違うのは、子要素に visibility: visible を指定すると、その子だけを再び表示できる点です。親全体は隠しつつ一部だけ見せたい、といった細かい制御ができます。
.parent {
visibility: hidden; /* 中身をまとめて隠す */
}
.parent .keep {
visibility: visible; /* この子だけは表示する */
}
opacity: 0 との違い
「見た目だけ消す」という意味では opacity: 0 も似ています。どちらも場所は残りますが、決定的な違いはクリックなどの操作を受け付けるかどうかです。opacity: 0 は透明になっているだけで要素自体は存在するため、その上をクリックすると反応してしまいます。一方 visibility: hidden の要素はクリックやフォーカスの対象から外れます。透明で見えないのに押せてしまう、という事故を避けたいときは visibility のほうが安全です。
transition と組み合わせてなめらかに消す
display: none は transition の対象にならないため、パッと消えてしまいます。しかし visibility は transition を効かせられるので、opacity と組み合わせるとフェードしながら消す表現ができます。ポイントは、opacity でフェードさせつつ、visibility の切り替えを少し遅らせることです。
.fade {
opacity: 1;
visibility: visible;
/* opacity はすぐ、visibility は遅延させて切り替える */
transition: opacity 0.3s, visibility 0s 0s;
}
.fade.is-hidden {
opacity: 0;
visibility: hidden;
/* フェードが終わってから hidden にする */
transition: opacity 0.3s, visibility 0s 0.3s;
}
visibility 0s 0.3s の 0.3s は遅延時間です。opacity のフェード(0.3秒)が終わってから hidden に切り替わるので、消える途中でカクッと隠れることがありません。表示に戻すときは遅延を 0s にして、すぐ見えるようにします。
隠したはずの要素が操作できてしまうとき
visibility: hidden にした要素は、原則としてクリックやキーボードのフォーカスを受け付けません。それでも「隠したはずのボタンにフォーカスが当たる」といった場合は、子要素に visibility: visible が指定されていないか確認してください。前述のとおり子で個別に再表示できるため、意図せず一部だけ操作可能になっていることがあります。
また、スクリーンリーダーなどの支援技術では、visibility: hidden の要素は基本的に読み上げの対象から外れます。見た目だけでなく読み上げ上も「無い」ものとして扱われる点は display: none と共通です。逆に、目には見せずに読み上げだけ残したい(アイコンボタンの説明などの)用途では、visibility ではなく専用の視覚的非表示テクニックを使う、と役割を分けて考えると混乱しません。
まとめ
visibility: hidden は、要素の場所を残したまま見た目だけを消すプロパティです。場所ごと消す display: none、透明にするだけでクリックは受け付ける opacity: 0 と、それぞれ挙動が異なります。レイアウトを崩したくないときは visibility、要素を完全に無くしたいときは display: none と使い分けましょう。transition が効くので opacity と組み合わせればフェードで消す表現もできます。目的に合わせて選べば、表示・非表示の切り替えを思いどおりにコントロールできます。