JavaScript | DOM 操作:CSS / クラス操作 – visibility の切り替え

JavaScript
スポンサーリンク

visibility の切り替えとは何か

visibility は「要素を見える/見えない」にするプロパティです。visibility: hidden にすると見えなくなりますが、レイアウト上の“場所”は残ります(スペースを確保したまま非表示)。再表示は visibility: visible に戻します。ここが重要です:display: none と違い、レイアウトは維持されるため、配置を崩さずに一時的に隠す場面に向いています。


display: none と visibility: hidden の違い(選び方の軸)

目的別の使い分け

  • レイアウトごと消したい: display: none(スペースも消える)
  • 場所は保ったまま隠したい: visibility: hidden(スペースは残る)
  • アニメーションさせたい: visibility は transition 可能(opacity と相性が良い)

ここが重要です:表示を消すだけならどちらでも隠せますが、“スペースを残すか”が最大の違い。UI の意図に合わせて選びましょう。


基本の切り替え(クラス方式が保守に強い)

クラスで一元管理(推奨)

<style>
  .is-hidden { visibility: hidden; }
  .is-visible { visibility: visible; }
</style>

<button id="toggle">切り替え</button>
<div id="panel" class="panel is-visible">内容</div>

<script>
  const btn = document.getElementById("toggle");
  const panel = document.getElementById("panel");

  btn.addEventListener("click", () => {
    const nowHidden = panel.classList.toggle("is-hidden");
    panel.classList.toggle("is-visible", !nowHidden);
    btn.textContent = nowHidden ? "見せる" : "隠す";
  });
</script>
HTML

ここが重要です:見え方のルールは CSS に集約し、JS は“状態クラス”だけ触る。プロジェクトが大きくなっても整合性を保てます。

インラインで最短切り替え(小規模向け)

<div id="panel" style="visibility: visible;">内容</div>
<script>
  const panel = document.getElementById("panel");
  panel.style.visibility = "hidden";  // 非表示(スペースは残る)
  panel.style.visibility = "visible"; // 再表示
</script>
HTML

ここが重要です:素早い試作には便利ですが、設計が散らばりやすい。基本はクラス方式に寄せましょう。


深掘り:visibility の実務的な特性

スペースは残る(レイアウトは維持)

ボタンやラベルを一瞬隠したいが、横並びレイアウトを崩したくない場面で有効です。ここが重要です:要素の“幅・高さ・位置”はそのまま。周囲要素の並びが変わりません。

子孫も隠れる(ただし上書き可能)

親を visibility: hidden にすると、原則として子孫も見えなくなります。特定の子だけ見せたいなら、その子に visibility: visible を指定すれば上書きできます。ここが重要です:親子で意図的に“見える/見えない”を分ける設計が可能です。

クリックは防げない(pointer-events を併用)

visibility: hidden は“見えないだけ”。位置は残り、クリック判定が通ることがあります。ここが重要です:操作不可にしたいなら pointer-events: none を併用します。

.hidden {
  visibility: hidden;
  pointer-events: none; /* クリック/ホバーを受けない */
}
CSS

スクリーンリーダー対策(aria-hidden)

見えない要素を読み上げさせたくないなら、aria-hidden=”true” を付けます。ここが重要です:視覚・操作・読み上げの整合性をそろえると UX が安定します。

el.classList.add("hidden");
el.setAttribute("aria-hidden", "true");
JavaScript

アニメーションに強い設計(visibility + opacity)

フェードの基本パターン

<style>
  .fade { opacity: 0; visibility: hidden; transition: opacity 180ms; }
  .fade.is-show { opacity: 1; visibility: visible; }
</style>

<div id="toast" class="fade">保存しました</div>
<script>
  const toast = document.getElementById("toast");
  function showToast() {
    toast.classList.add("is-show");
    setTimeout(() => toast.classList.remove("is-show"), 1500);
  }
</script>
HTML

ここが重要です:opacity をトランジションさせ、visibility で“見えない状態”を明示。pointer-events: none を足すと操作も防げます。

レイアウト維持が前提の演出

visibility はスペースを保つため、ガタつきがありません。ここが重要です:メニューやツールチップの“スッと出る/消える”演出に向いています。


実践例(ラベルの一時隠し、ツールチップ、ローディング)

ラベルを条件で見せる/隠す(配置維持)

<style>
  .label { margin-left: 8px; }
  .label.is-hidden { visibility: hidden; }
</style>

<button id="run">実行</button><span id="label" class="label">完了</span>
<script>
  const label = document.getElementById("label");
  label.classList.add("is-hidden");          // 初期は非表示(スペースは保持)

  document.getElementById("run").addEventListener("click", () => {
    label.classList.remove("is-hidden");     // 結果に応じて表示
    setTimeout(() => label.classList.add("is-hidden"), 2000);
  });
</script>
HTML

ここが重要です:ボタンの横幅が変わらず、UI が安定して見えます。

ツールチップの表示(フェード + 操作不可)

<style>
  .tip { position: absolute; opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 120ms; }
  .tip.is-show { opacity: 1; visibility: visible; pointer-events: auto; }
</style>

<div class="field">
  <input id="name">
  <div id="tip" class="tip">名前を入力してください</div>
</div>
<script>
  const tip = document.getElementById("tip");
  const name = document.getElementById("name");
  name.addEventListener("focus", () => tip.classList.add("is-show"));
  name.addEventListener("blur",  () => tip.classList.remove("is-show"));
</script>
HTML

ここが重要です:opacity/visibility/pointer-events をセットで管理すると、直感的で安全な UI になります。

ローディング覆い(場所は確保、操作を封じる)

<style>
  .overlay { position: relative; }
  .overlay::after {
    content: ""; position: absolute; inset: 0;
    background: rgba(255,255,255,.6); visibility: hidden; pointer-events: none;
  }
  .overlay.is-busy::after { visibility: visible; pointer-events: auto; }
</style>

<div id="card" class="overlay">内容</div>
<script>
  const card = document.getElementById("card");
  function busy(on) { card.classList.toggle("is-busy", on); }
  busy(true); setTimeout(() => busy(false), 1000);
</script>
HTML

ここが重要です:覆いは“スペースを保ちつつ操作不可”にできるため、ちらつきなく処理中を伝えられます。


落とし穴と回避策(スペース、クリック、読み上げ)

スペースが残ることを忘れない

visibility: hidden は“空白が残る”ため、詰めたいレイアウトには不向きです。ここが重要です:詰めたいなら display: none、崩したくないなら visibility: hidden。

操作不能にしたいなら pointer-events を併用

見えないのにクリックできると事故につながります。ここが重要です:hidden 時は pointer-events: none をセットで。

アクセシビリティを揃える

読み上げ対象から外すなら aria-hidden を連動。フォーカスも適切に移動/解除します。ここが重要です:視覚・操作・読み上げの一貫性が UX の鍵です。


まとめ

visibility の切り替えは「見えないけれど場所は残す」非表示手段です。レイアウトを崩さずに隠したい場面で選び、操作不可にしたいときは pointer-events、読み上げ制御は aria-hidden を併用。アニメーションは opacity と組み合わせると滑らかで扱いやすい。display: none と目的を区別し、クラス方式で一元管理すれば、初心者でも意図通りで壊れにくい表示制御が書けます。

タイトルとURLをコピーしました