CSSの ::before / ::after 擬似要素はjQueryや通常のJavaScriptからDOMとして直接アクセスできません。しかし data-*属性・CSS変数・クラス切り替え・styleタグの挿入 という間接的なアプローチでJavaScriptから動的に変更できます。
- jQueryから擬似要素を直接変更できない理由
- data-*属性 + CSS attr()で contentを変更する(最も汎用的)
- CSSクラスの切り替えで擬似要素のスタイルを変える
- CSS変数(カスタムプロパティ)で任意のプロパティを変更する
- styleタグを動的に挿入する(あらゆるプロパティに対応)
- 実用例:カウンターバッジ・ステータスラベル・装飾の切り替え
jQueryから擬似要素を直接変更できない理由
擬似要素(::before / ::after)はCSSで生成される仮想的な要素であり、実際のDOM要素ではありません。そのため $("#el::before") などでセレクトしてもjQueryには何も返ってきません。
// これはどれも動作しない
$('#target::before').css('content', '★'); // NG: 空のjQueryオブジェクト
$('#target').find('::before').text('★'); // NG: 擬似要素はDOMにない
document.querySelector('#target::before'); // NG: null が返る
- data-*属性 + attr(): contentをdata属性経由で変更(文字列のみ)
- クラス切り替え: 事前にCSSでパターンを用意しておきクラスで切り替える
- CSS変数:
style.setProperty()でカスタムプロパティを上書き(任意のプロパティ対応) - styleタグ挿入:
<style>タグを動的に生成(任意のプロパティ対応・最終手段)
data-*属性 + CSS attr()でcontentを変更する
CSS の content: attr(data-xxx) を使うと、HTMLのdata属性の値をそのまま content に表示できます。jQueryでdata属性を書き換えることで擬似要素のテキストが変わります。
CSSの設定
.badge::after {
content: attr(data-count); /* data-count属性の値を表示 */
display: inline-block;
background: #ef4444;
color: #fff;
border-radius: 50%;
padding: 2px 6px;
font-size: 12px;
margin-left: 4px;
}
HTMLとjQuery
<button class="badge" data-count="3">通知</button>
$(function () {
// data-count属性を変更 → ::after の content が変わる
$('#update-btn').on('click', function () {
var current = parseInt($('.badge').attr('data-count')) || 0;
$('.badge').attr('data-count', current + 1);
});
// 0件の時はバッジを非表示にする
function updateBadge(count) {
$('.badge')
.attr('data-count', count)
.toggleClass('badge--empty', count === 0);
}
});
content: attr(data-xxx) はテキスト文字列のみ表示できます。数値に単位を付けたり(attr(data-width)px)、画像URLを指定したりは基本的にできません(CSS Values Level 5で拡張予定)。content以外のプロパティ(background-color・widthなど)もattr()では変更できません。それらはCSS変数を使う方法で対応してください。attr()の詳細はattr()完全ガイドを参照してください。CSSクラスの切り替えで擬似要素のスタイルを変える
複数の状態(通常・ホバー・アクティブ・エラーなど)に対応するCSSを事前に書いておき、jQueryでクラスを切り替えます。content以外のプロパティ(色・サイズ・アイコン)も変更できます。
/* デフォルトの ::before */
.status-item::before {
content: "●";
color: #94a3b8; /* グレー */
margin-right: 6px;
}
/* 成功状態 */
.status-item.is-success::before {
content: "✓";
color: #10b981; /* 緑 */
}
/* エラー状態 */
.status-item.is-error::before {
content: "✕";
color: #ef4444; /* 赤 */
}
$(function () {
// バリデーション結果に応じてクラスを切り替え
function setStatus($item, status) {
$item
.removeClass('is-success is-error')
.addClass(status === 'success' ? 'is-success' : 'is-error');
}
$('#submit-btn').on('click', function () {
var val = $('#name-input').val();
var $status = $('.status-item');
if (val.length >= 2) {
setStatus($status, 'success');
} else {
setStatus($status, 'error');
}
});
});
あらかじめCSSで全パターンを定義しておくため、jQueryはクラスを付け替えるだけです。ブラウザの再描画コストが最小限で、コードも明確に分離されます。クラス操作の詳細はaddClass/removeClass/toggleClass完全ガイドを参照してください。
CSS変数(カスタムプロパティ)で任意のプロパティを変更する
CSS変数を使うと content 以外のプロパティ(色・サイズ・背景画像など)もJavaScriptから動的に変更できます。element.style.setProperty("--変数名", 値) で設定します。
.highlight {
--pseudo-color: #0284c7; /* デフォルト色 */
--pseudo-width: 3px; /* デフォルト幅 */
}
.highlight::before {
content: "";
display: block;
width: var(--pseudo-width);
height: 100%;
background: var(--pseudo-color);
position: absolute;
left: 0;
top: 0;
}
$(function () {
// CSS変数を変更して擬似要素の色・幅を動的に変える
$('#color-red').on('click', function () {
document.querySelector('.highlight').style
.setProperty('--pseudo-color', '#ef4444');
});
$('#color-green').on('click', function () {
document.querySelector('.highlight').style
.setProperty('--pseudo-color', '#10b981');
});
// jQueryと組み合わせる場合は [0] でネイティブDOM要素を取得
$('.highlight').each(function () {
var color = $(this).data('color') || '#0284c7';
this.style.setProperty('--pseudo-color', color);
});
});
content: var(--pseudo-text) のようにCSS変数を content にも使えます。特定の要素だけ変更したい場合はその要素に直接 style.setProperty() を呼び、ページ全体の変数を変えたい場合は document.documentElement.style.setProperty() で:root の変数を上書きします。styleタグを動的に挿入する(最終手段)
上記の方法が使えない場合、<style> タグを動的にDOMに追加する方法があります。IDセレクターと組み合わせることで特定要素の擬似要素だけを対象にできます。
$(function () {
function setPseudoContent(selector, pseudoEl, content) {
var id = 'dynamic-pseudo-style';
var $style = $('#' + id);
// 既存のstyleタグを再利用(なければ作成)
if ($style.length === 0) {
$style = $('<style>').attr('id', id).appendTo('head');
}
// CSSを上書き
$style.text(selector + pseudoEl + ' { content: "' + content + '"; }');
}
// 使用例
setPseudoContent('#target', '::before', '新しいテキスト');
});
styleタグを動的に追加する方法はどのプロパティでも変更できますが、コンテンツとスタイルが混在し管理が難しくなります。また、content文字列に
"(ダブルクォート)が含まれるとCSSが壊れるためエスケープが必要です。CSS変数やクラス切り替えで対応できる場合はそちらを優先してください。方法の比較と使い分け
| 方法 | 変更できるプロパティ | コード量 | 向いているケース |
|---|---|---|---|
| data-* + attr() | contentのみ(文字列) | 少ない | バッジ・カウンター・ラベルテキスト変更 |
| クラス切り替え | 事前に定義したCSS全て | CSS多め・JS少ない | 状態表示・アイコン切り替え・パターンが決まっている場合 |
| CSS変数 | 変数を使ったプロパティ全て | 中程度 | 色・サイズを動的に変えたい場合・パターンが多い場合 |
| styleタグ挿入 | 全てのCSSプロパティ | 多め(エスケープ必要) | 上記で対応できない場合の最終手段 |
まとめ
jQueryから擬似要素を直接変更することはできませんが、間接的な4つのアプローチで動的な変更が実現できます。
- テキストを変えたい: data-*属性 +
content: attr(data-xxx) - パターンが決まっている: CSSクラスを切り替える(最もシンプルで高パフォーマンス)
- 色・サイズなど任意のプロパティ: CSS変数 +
style.setProperty() - それでも対応できない場合: styleタグを動的に挿入(エスケープに注意)
関連記事: attr()完全ガイド / addClass/removeClass/toggleClass完全ガイド
よくある質問(FAQ)
.css() は実際のDOM要素にインラインスタイルを設定しますが、擬似要素はDOMに存在しないため $(el).css("content", ...) は擬似要素に効きません。要素本体に content プロパティを設定しても、擬似要素の content は別のスタイルルールで管理されているためです。content: attr(data-xxx) が正しく設定されているか確認してください。また、$(el).data("xxx", val)(jQueryのdata()メソッド)はjQueryの内部キャッシュを更新するだけでHTML属性は変更されません。$(el).attr("data-xxx", val) を使うとHTML属性が実際に更新されCSSに反映されます。el.style.setProperty("--var", val) は対象の要素に直接インラインスタイルとして設定されます。ページ全体の擬似要素を変えたい場合は document.documentElement.style.setProperty() で:root 変数を上書きしてください。また、CSS変数を擬似要素が参照できるスコープに設定されているか確認してください。el.style.setProperty("--pseudo-bg", "url(image.jpg)") を設定し、CSSで ::after { background-image: var(--pseudo-bg); } のように参照します。または背景画像が複数パターンある場合はクラス切り替えで対応してください。::before: 要素の先頭(前)にコンテンツを追加。ラベル・アイコン・装飾などに使われます。::after: 要素の末尾(後)にコンテンツを追加。バッジ・カウンター・引用符の閉じなどに使われます。どちらも content プロパティが必須です(content: "" でも可)。