JavaScript | DOM 操作:CSS / クラス操作 – className

JavaScript
スポンサーリンク

className とは何か

className は、要素の class 属性(CSS クラス名の一覧)を「文字列として」読み書きするためのプロパティです。p, div などの要素に対して、クラスをまとめて設定したり、現在のクラス名を取得できます。ここが重要です:className は“文字列まるごと”を扱うため、上書きが基本。部分的な追加・削除には向いていません。


基本の使い方(読み取り・書き込み)

現在のクラスを読む

<div id="box" class="card highlight"></div>
<script>
  const box = document.getElementById("box");
  console.log(box.className); // "card highlight"
</script>
HTML

className は今付いているクラス名をスペース区切りの文字列で返します。分割して扱いたいなら文字列を split します。

クラスを丸ごと設定する

<div id="box"></div>
<script>
  const box = document.getElementById("box");
  box.className = "card highlight"; // まとめて付ける
</script>
HTML

ここが重要です:className に代入すると“既存のクラスを全て置き換え”ます。追加だけのつもりでも、他のクラスを消してしまう事故が起きがちです。


複数クラスの扱い(文字列としての注意点)

追加・削除・判定を文字列でやると壊れやすい

<div id="box" class="card"></div>
<script>
  const box = document.getElementById("box");

  // 文字列連結で追加(スペース忘れの事故が起きやすい)
  box.className += " highlight";    // OK
  box.className += "hidden";        // NG: "highlighthidden" になってしまう

  // 判定も文字列検索だと不正確になりがち
  const hasHighlight = box.className.includes("highlight"); // "super-highlight" でも true になる
</script>
HTML

ここが重要です:className は“生の文字列”。スペースや部分一致の罠が多く、追加・削除・判定には不向きです。細かい操作が必要なら classList を使うのが定石です。


classList との使い分け(上書きか、部分操作か)

className(まとめて上書きしたいとき)

  • 一度に「このクラス群にしたい」という意図が明確。
  • サーバーやテンプレートから受け取った固定の文字列をそのまま適用。
el.className = "card is-active theme-dark";
JavaScript

classList(部分的な追加・削除・切り替え)

  • add/remove/toggle/contains で安全に操作できる。
  • スペースや部分一致の罠がない。
el.classList.add("is-active");
el.classList.remove("hidden");
el.classList.toggle("selected", condition);
JavaScript

ここが重要です:普段の UI 制御は classList が基本。className は「全置換したいときだけ」に限定すると事故が減ります。


実践パターン(className を安全に使うコツ)

既存クラスを保ったまま“テーマだけ”置き換える

<div id="box" class="card theme-light"></div>
<script>
  const box = document.getElementById("box");
  const classes = box.className.split(/\s+/).filter(Boolean);

  // 既存から theme-* を除去
  const next = classes.filter(c => !/^theme-/.test(c));
  // 新テーマを追加
  next.push("theme-dark");
  box.className = next.join(" ");
</script>
HTML

ここが重要です:className を使いつつ部分的に変更したいなら、“配列化→加工→再結合”のパターンで意図を明確に。正規表現で対象グループを絞ると安全です。

状態セットを一括で適用する(“全置換”が正しい場面)

<button id="btn" class="btn"></button>
<script>
  const btn = document.getElementById("btn");

  function setState(state) {
    // 状態に応じて完全なクラスセットを決める
    if (state === "loading") btn.className = "btn is-loading";
    else if (state === "success") btn.className = "btn is-success";
    else btn.className = "btn";
  }

  setState("loading");
</script>
HTML

ここが重要です:状態マシンのように「クラスの正解集合」を常に再設定するなら className が向いています。差分を考えず“いつも正解にする”設計は読みやすく、ズレません。


命名と設計の深掘り(クラスは“意味”を持たせる)

見た目と役割を分ける

  • 見た目(色・余白)は CSS のユーティリティやテーマクラス。
  • 役割(状態・意味)は is-active, is-error, is-loading のようなプレフィックスで明確に。
<button class="btn is-active theme-dark">保存</button>
HTML

ここが重要です:クラスは“意味のラベル”。JS は状態クラスだけを触り、テーマやレイアウト系は触らない。責務分離で保守性が上がります。

競合と衝突を避ける命名

  • コンポーネント名の接頭辞(card-, menu-, modal-*)で範囲を示す。
  • 正規表現でグループ削除するときに判定しやすい命名にする。

ここが重要です:命名が整理されていれば、className の一括置換でも安全に扱えます。


例:ドロワーの開閉(classList と className の併用)

<button id="toggle" class="btn">開く</button>
<aside id="drawer" class="drawer is-hidden theme-light">内容</aside>
<script>
  const toggle = document.getElementById("toggle");
  const drawer = document.getElementById("drawer");

  toggle.addEventListener("click", () => {
    // 開閉は部分操作(classList)
    const hidden = drawer.classList.toggle("is-hidden");
    toggle.textContent = hidden ? "開く" : "閉じる";

    // テーマ切り替えは全置換(className)
    const base = "drawer";
    drawer.className = `${base} ${hidden ? "theme-light" : "theme-dark"} ${hidden ? "is-hidden" : ""}`.trim();
  });
</script>
HTML

ここが重要です:動的状態は classList で差分更新、テーマセットは className で“正解集合”を常に再適用。どちらが適切かを役割で分けると、コードが明確になります。


まとめ

className は「クラス一覧を文字列で丸ごと扱う」ためのプロパティで、全置換・一括適用に向いています。追加・削除・判定の細かい操作は classList が安全で確実。className を使うときは、配列化してから加工する、正規表現で対象グループを絞る、状態の正解集合を毎回再設定する——この設計を意識すると事故が減ります。クラスは“意味のラベル”。JS は状態だけを触り、見た目は CSS に任せる。役割を分けて使いこなせば、初心者でも読みやすく壊れにくい UI を作れます。

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