【JavaScript】要素の表示/非表示を切り替える方法

ボタンで要素を出したり隠したりする「表示/非表示の切り替え」は、JavaScriptで頻出の処理です。方法はいくつかありますが、大事なのは「どれを使うか」より「隠したとき場所を残すかどうか」です。

この記事では、各手法の違いと使い分けを整理したうえで、スニペット(必要な部分だけ)の動くコードで解説します。

この記事の結論:基本は element.classList.toggle("hidden")element.hidden = !element.hidden でOK。隠したときに場所も消したいなら display:none場所を残したいなら visibility:hidden を選びます。style.display の直接操作には判定の落とし穴があるので注意します。
スポンサーリンク

まず違いを理解する(場所が残るかどうか)

「非表示」と言っても、レイアウト上の場所が消えるか残るかで結果が変わります。ここを押さえると手法選びで迷いません。

方法 見え方 レイアウトの場所 こんな時に
display:none 完全に消える 残らない(詰まる) 通常の表示/非表示
visibility:hidden 見えないだけ 残る(空白で占有) 場所をズラしたくない
hidden属性 / el.hidden 消える(=display:none相当) 残らない 最短・意味的に隠す
opacity:0 透明(操作は可能) 残る フェードなどの演出

classList.toggle で切り替える(基本・推奨)

もっとも素直な方法です。display:none を持つ .hidden クラスを用意し、classList.toggle()付いていれば外す・無ければ付けるを1行で行います。

CSS
.hidden {
  display: none;
}
JavaScript:toggleで1行切り替え
const btn = document.getElementById("toggle");
const box = document.getElementById("box");

btn.addEventListener("click", () => {
  box.classList.toggle("hidden"); // 付け外しを1行で
});

古い記事では if (classList.contains(...)) remove() else add() と書きがちですが、toggle() ならその分岐は不要です。classList の詳しい使い方はclassListの使い方を参照してください。

element.hidden で最短に切り替える

専用クラスすら用意せず、HTML標準の hidden 属性で切り替える方法です。el.hidden = truedisplay:none 相当になります。

JavaScript:hidden を反転
btn.addEventListener("click", () => {
  box.hidden = !box.hidden; // true/false を反転するだけ
});
注意:要素に display を指定するCSS(例:#box { display: flex; })があると、そちらが hidden 属性より優先されて隠れないことがあります。その場合は [hidden] { display: none; } をCSSに足すか、前述の .hidden クラス方式を使います。

style.display を直接操作する(罠に注意)

インラインstyleの display を直接書き換える方法です。一見シンプルですが、判定に落とし穴があります

JavaScript:style.display を切り替える
btn.addEventListener("click", () => {
  if (box.style.display === "none") {
    box.style.display = "";   // 空文字でCSS既定の表示に戻す
  } else {
    box.style.display = "none";
  }
});
落とし穴:box.style.displayインラインstyleしか読みません。表示状態をCSS(スタイルシート)側で指定していると初期値は空文字 "" になり、=== "none" の判定が外れて初回クリックが逆に動くことがあります。また戻すときは "block" 固定にすると元が flex などでも強制的にblockになってしまうため、""(空文字)でCSS既定に戻すのが安全です。確実さを求めるなら classListhidden を使いましょう。

visibility で場所を残して隠す

隠してもレイアウトの場所を保ちたいとき(隣の要素をズラしたくないとき)は visibility を使います。display:none と違い、空白として領域が残ります。

CSS
.invisible {
  visibility: hidden;
}
JavaScript
box.classList.toggle("invisible");

jQueryなら toggle() 一発

すでにjQueryを使っているプロジェクトなら、toggle() 一行で切り替えられます(新規でこのためだけにjQueryを入れる必要はありません)。

jQuery
$("#box").toggle();

アニメーション付きの表示切り替えなど、jQueryでの実装はボタンクリックで要素の表示・非表示を切り替える完全ガイドで詳しく解説しています。

アクセシビリティに配慮する(aria-expanded)

開閉ボタンには aria-expanded を付け、状態に合わせて更新すると、スクリーンリーダーにも開閉が正しく伝わります。要素自体は hidden 属性(または display:none)で隠すと、読み上げ対象からも外れます。

JavaScript:aria-expanded を同期
btn.addEventListener("click", () => {
  const willOpen = box.hidden;     // 今が非表示なら開く
  box.hidden = !willOpen;
  btn.setAttribute("aria-expanded", String(willOpen));
});
補足:opacity:0visibility:hidden は見た目は隠れても、opacity:0 の要素はクリックでき読み上げ対象にも残るため、「本当に隠す」目的には display:none / hidden が適しています。

フェードで切り替えたいとき

display は基本的にアニメーションできません。ふわっと消すフェードをしたいときは、opacityvisibilitytransition で組み合わせます(透明にしてから場所を消す)。opacity / visibility の挙動は要素を点滅させる方法でも具体的に扱っています。

よくある質問(FAQ)

QJavaScriptで要素の表示・非表示を切り替えるには?
Aelement.classList.toggle("hidden") でCSSの display:none クラスを付け外しするか、element.hidden = !element.hidden で切り替えます。CSSと分離できる前者がメンテナンスしやすくおすすめです。
Qdisplay:none と visibility:hidden の違いは?
Adisplay:none は要素がレイアウトから消え、場所も詰まりますvisibility:hidden場所を残したまま見えなくなるだけです。隣の要素をズラしたくないときは visibility を使います。
Q表示切り替えにアニメーションを追加するには?
Adisplay はアニメーションできないため、opacityvisibility を組み合わせます。opacitytransition でフェードさせ、終了後に visibility:hidden にする形が定番です。
Qアクセシブルに表示切り替えを実装するには?
A隠す要素は hidden 属性(または aria-hidden="true")で読み上げ対象から外し、開閉ボタンの aria-expanded を状態に合わせて更新します。これでスクリーンリーダーにも開閉状態が正しく伝わります。

まとめ

要素の表示/非表示は、まず「場所を残すかどうか」で考えると手法が決まります。場所も消すなら display:noneclassList.toggleel.hidden で操作)、場所を残すなら visibility:hidden です。

実装は classList.toggle("hidden")element.hidden が基本style.display の直接操作は判定の罠があるため、確実さを求めるならクラス方式が無難です。開閉UIでは aria-expanded も忘れずに更新しましょう。