モダンなWeb開発において、JavaScriptを使用してHTML要素にクラスを追加・操作する技術は、ユーザーインターフェースの動的な変化を実現するための基礎となります。
CSSで定義したスタイルを動的に適用することで、アニメーションの開始、要素の表示・非表示、ダークモードの切り替えなど、多様なインタラクションが可能になります。
かつては複雑な文字列操作が必要だったクラス操作も、現代のブラウザ標準APIであるclassListの登場により、非常にシンプルかつ安全に記述できるようになりました。
本記事では、JavaScriptでクラスを追加する基本から、2026年のWeb標準に即した高度な活用術までを詳しく解説します。
JavaScriptでクラスを追加する基本メソッド
JavaScriptで特定の要素にCSSクラスを追加する最も標準的で推奨される方法は、classListプロパティを使用することです。
classListは、要素が持っているクラス名をリストとして扱うための読み取り専用プロパティですが、専用のメソッドを通じて内容を操作できます。
classList.add() を使ったクラスの追加
最も頻繁に使用されるのが、classList.add()メソッドです。
このメソッドを使用すると、既存のクラスを保持したまま、新しいクラスを安全に追加できます。
// 対象の要素を取得
const element = document.querySelector('.my-element');
// 'active' というクラスを追加
element.classList.add('active');
// 複数のクラスを同時に追加することも可能
element.classList.add('fade-in', 'highlight');
このコードを実行すると、HTML要素のclass属性に指定した文字列が追加されます。
<!-- 実行前 -->
<div class="my-element"></div>
<!-- 実行後 -->
<div class="my-element active fade-in highlight"></div>
classList.add()の優れた点は、既に同じクラスが存在している場合には重複して追加しないという点にあります。
これにより、開発者は事前にクラスの有無を確認するロジックを記述する必要がなくなり、コードの堅牢性が向上します。
classList.remove() によるクラスの削除
追加したクラスを取り除くには、classList.remove()メソッドを使用します。
特定の状態が解除されたときや、アニメーションが終了したタイミングでクラスを削除する場合に便利です。
const element = document.querySelector('.my-element');
// 'active' クラスを削除
element.classList.remove('active');
// 複数のクラスを一度に削除
element.classList.remove('fade-in', 'highlight');
存在しないクラスを削除しようとしてもエラーは発生せず、単に無視されるため、安全に利用できます。
classList.toggle() でクラスの切り替えを効率化する
クリックするたびに「開く・閉じる」といったトグル動作を実装する場合、classList.toggle()が非常に有効です。
このメソッドは、指定したクラスが存在すれば削除し、存在しなければ追加するという処理を一行で完結させます。
const button = document.querySelector('#menu-button');
const menu = document.querySelector('#side-menu');
button.addEventListener('click', () => {
// クラスがあれば削除、なければ追加
menu.classList.toggle('is-open');
});
さらに、第2引数に論理値(true/false)を渡すことで、特定の条件下でのみクラスを付与するといった制御も可能です。
// 画面幅が768px以上の場合のみ 'desktop-view' クラスを強制する
const isDesktop = window.innerWidth >= 768;
element.classList.toggle('desktop-view', isDesktop);
classListとclassNameの違いを理解する
JavaScriptには、クラスを操作するもう一つの方法としてclassNameプロパティが存在します。
しかし、現代の開発においては特別な理由がない限りclassListを使用するのが一般的です。
classNameの特性とリスク
classNameは、要素のclass属性全体を一つの文字列として取得または書き換えるプロパティです。
const element = document.querySelector('.box');
// クラスを上書き(既存のクラスは消える)
element.className = 'new-style';
この方法の問題点は、既存のクラスをすべて消去してしまうリスクがあることです。
一部のクラスだけを操作したい場合、文字列の連結や正規表現を駆使する必要があり、バグの温床になりがちでした。
classListが推奨される理由
classListが推奨される主な理由を以下の表にまとめました。
| 機能 | classList | className |
|---|---|---|
| 部分的な操作 | メソッド(add/remove)で容易に可能 | 文字列操作が必要で困難 |
| 重複の防止 | 自動的に処理される | 手動でのチェックが必要 |
| コードの可読性 | 直感的で分かりやすい | 代入文のため意図が不明確になりやすい |
| パフォーマンス | DOMTokenListとして最適化されている | 文字列の再解析が発生する |
現代のブラウザ環境では、IE(Internet Explorer)のサポートを考慮する必要がなくなったため、classListを全面的に採用して問題ありません。
最新のJavaScriptにおけるクラス操作の実践パターン
2026年のWeb開発シーンでは、単にクラスを追加するだけでなく、リアクティブな設計やアクセシビリティへの配慮が求められます。
状態管理とクラスの連動
現代的なアプリケーションでは、データの状態(State)に基づいて自動的にクラスが適用される仕組みが好まれます。
ネイティブのJavaScriptでも、Proxyや最新のSignals API的なアプローチ(提案仕様を含む)を活用して、状態とDOMを同期させることができます。
// 状態を管理する簡易的なオブジェクト
const state = {
isLoading: false
};
// 状態が変化したときにクラスを更新する関数
function updateUI() {
const spinner = document.querySelector('.spinner');
spinner.classList.toggle('visible', state.isLoading);
}
// データの読み込み開始
state.isLoading = true;
updateUI();
複数要素への一括クラス追加
リスト形式のUIなどで、複数の要素に対して一括でクラスを操作したい場面は多々あります。
querySelectorAllで取得したノードリストに対して、forEachメソッドを使用するのが最も確実な方法です。
const items = document.querySelectorAll('.list-item');
items.forEach((item, index) => {
// 0.1秒ずつずらしてアニメーション用クラスを追加
setTimeout(() => {
item.classList.add('animate-up');
}, index * 100);
});
アクセシビリティ属性(WAI-ARIA)との同期
クラスの追加は視覚的な変化のみを伴うことが多いですが、アクセシビリティの観点からはARIA属性の更新も同時に行うべきです。
例えば、アコーディオンメニューの開閉時にはクラスだけでなくaria-expanded属性も切り替えます。
const accordionHeader = document.querySelector('.accordion-header');
const content = document.querySelector('.accordion-content');
accordionHeader.addEventListener('click', () => {
const isExpanded = content.classList.toggle('is-visible');
// クラスの状態に合わせてARIA属性を更新
accordionHeader.setAttribute('aria-expanded', isExpanded);
});
パフォーマンスを意識したクラス操作のコツ
DOMの操作はブラウザにとって比較的コストの高い処理です。
特に大量の要素を操作する場合や、頻繁にクラスを切り替える場合には工夫が必要です。
リフローとリペイントの最小化
クラスを追加すると、ブラウザは要素のスタイルを再計算し、必要に応じて「リフロー(レイアウト計算)」や「リペイント(描画)」を行います。
短時間に何度もclassList.add()を呼び出すのではなく、可能な限りまとめて操作することが推奨されます。
const el = document.querySelector('.target');
// 悪い例:個別に何度も呼び出す
el.classList.add('style-1');
el.classList.add('style-2');
el.classList.add('style-3');
// 良い例:一度の呼び出しで複数のクラスを指定する
el.classList.add('style-1', 'style-2', 'style-3');
requestAnimationFrameの活用
スクロールイベントなどでクラスを動的に付与する場合、実行頻度が高すぎてパフォーマンスを低下させることがあります。
このようなケースでは、requestAnimationFrameを使用してブラウザの描画タイミングに合わせて処理を実行するとスムーズになります。
let ticking = false;
window.addEventListener('scroll', () => {
if (!ticking) {
window.requestAnimationFrame(() => {
const header = document.querySelector('header');
if (window.scrollY > 100) {
header.classList.add('scrolled');
} else {
header.classList.remove('scrolled');
}
ticking = false;
});
ticking = true;
}
});
よくあるミスとデバッグ方法
クラス操作が期待通りに動かない場合、いくつかの典型的な原因が考えられます。
ドット(.)を含めてしまうミス
もっとも初心者が陥りやすいミスは、classListのメソッドにドットを含めてしまうことです。
// 誤り
element.classList.add('.active');
// 正解
element.classList.add('active');
セレクタとしての記述(.active)とクラス名そのものの指定を混同しないように注意しましょう。
DOMの読み込み完了前に実行している
HTML要素がまだ生成されていないタイミングでJavaScriptが実行されると、querySelectorがnullを返し、エラーが発生します。
スクリプトを<body>の最後で読み込むか、DOMContentLoadedイベント内で処理を実行するようにしましょう。
document.addEventListener('DOMContentLoaded', () => {
// ここでクラス操作を行うと安全
const btn = document.querySelector('.btn');
btn.classList.add('ready');
});
まとめ
JavaScriptによるクラスの追加と操作は、ユーザー体験を向上させるための極めて重要なスキルです。
classList.add()、remove()、toggle()を使いこなすことで、複雑なUIの切り替えも簡潔に記述できるようになります。
また、2026年現在の開発においては、単なる見た目の変更にとどまらず、パフォーマンスの最適化やアクセシビリティへの配慮も欠かせません。
常に最新のブラウザ標準機能を活用し、クリーンでメンテナンス性の高いコードを目指しましょう。
この記事で紹介したテクニックを活用して、よりダイナミックで魅力的なWebサイトを構築してください。
