5.

CSS 属性セレクタ完全ガイド([attr=val] / 前方一致 / 後方一致 / 中間一致 / 大文字無視)

編集
この記事の要点
  • CSS の 属性セレクタ: [attr] / [attr=value] / [attr^=value] / [attr$=value] / [attr*=value] / [attr~=word] / [attr|=value]
  • ^= 前方一致 / $= 後方一致 / *= 中間一致(文字列を含む)
  • ~= はスペース区切りリストの1 単語完全一致|= はハイフン区切りリストの前方一致
  • [attr=value i]case insensitive(大文字小文字無視)、s で sensitive
  • モダン CSS では class を増やしすぎず、data-* 属性と組み合わせて状態を表現するのが定石

7 種類の属性セレクタ

記法意味例 マッチ
[attr]属性を持つ<a href> 全部
[attr=value]完全一致type="submit"
[attr^=value]前方一致href="https://" で始まる
[attr$=value]後方一致href=".pdf" で終わる
[attr*=value]中間一致(含む)hrefyoutube 含む
[attr~=word]スペース区切り単語classbtn 単語含む
[attr|=value]ハイフン区切り前方lang="ja" or lang="ja-JP"

基本例

/* href 属性を持つ a タグ全部(href 無しの a を除外) */
a[href] { color: blue; }

/* required 属性を持つフォーム要素 */
input[required] { border-color: red; }
input[required] + label::after { content: " *"; color: red; }

/* type が submit のボタン */
input[type="submit"] { background: blue; color: white; }
button[type="submit"] { /* 同様 */ }

/* disabled 状態(属性が値無しで存在) */
input[disabled] { opacity: 0.5; }

前方一致 ^=

/* 外部リンクに矢印 */
a[href^="http"] { /* http, https, http://example.com */ }

/* https のみ */
a[href^="https://"]::after { content: " 🔒"; }

/* 電話リンク */
a[href^="tel:"] { color: green; }

/* メール */
a[href^="mailto:"] { color: orange; }

/* 自サイト内リンク(先頭 / または ./ で始まる) */
a[href^="/"], a[href^="./"], a[href^="#"] { /* 内部リンクスタイル */ }

後方一致 $=

/* PDF へのリンク */
a[href$=".pdf"]::after { content: " 📄 PDF"; }

/* 画像ファイル */
a[href$=".jpg"],
a[href$=".png"],
a[href$=".webp"] { /* 画像リンク */ }

/* ZIP / アーカイブ */
a[href$=".zip"]::after { content: " ⬇️ ZIP"; }

中間一致 *=

/* YouTube のリンク */
a[href*="youtube.com"]::before { content: "▶ "; color: red; }
a[href*="youtu.be"]::before    { content: "▶ "; color: red; }

/* 検索結果のハイライト(jQuery 風) */
a[href*="?q="] { background: yellow; }

/* GitHub のリンク */
a[href*="github.com"]::after { content: " 🐙"; }

単語一致 ~=

スペース区切りのリストの中に「その単語が完全に含まれる」とき。これは class 属性に最適:

/* class="btn primary large" のような並びの "btn" を狙う */
[class~="btn"] { padding: 8px 16px; }

/* これは .btn と本質的に同じ */

/* ⚠️ "*=" と異なる */
[class*="btn"]  /* "button" や "btn-primary" 全部マッチ */
[class~="btn"]  /* スペース区切りで "btn" ピッタリのときだけ */

ハイフン一致 |=

ハイフン区切りで「その値か、その値から始まる」とき。lang 属性で典型的に使う:

/* 日本語: lang="ja" または lang="ja-JP" 等 */
[lang|="ja"] { font-family: 'Noto Sans JP', sans-serif; }

/* 英語: lang="en", en-US, en-GB ... */
[lang|="en"] { font-family: Georgia, serif; }

/* 中国語簡体・繁体は別 */
[lang|="zh"] { font-family: 'Noto Sans SC', sans-serif; }

case insensitive i / sensitive s

/* デフォルトは sensitive(HTML 属性は大文字小文字無視のものが多いが) */

/* 大文字小文字を無視 */
a[href$=".PDF" i],
a[href$=".pdf" i] { /* どちらでもマッチ */ }

/* 拡張子マッチでは "i" を付けるのが安全 */
a[href$=".jpg" i] { /* .JPG .jpg .Jpg 全部 */ }

/* XML / SVG の属性は大文字小文字を区別するので "s" を明示することも */
[viewBox] { }                  /* 標準は s 扱い */
[viewBox="0 0 24 24" s] { }    /* s 明示 */

data-* 属性と組み合わせ

モダンな書き方では class を増やさず、状態を data 属性で表現します:

<div class="card" data-status="active">アクティブ</div>
<div class="card" data-status="inactive">非アクティブ</div>
<div class="card" data-status="pending">保留</div>
.card[data-status="active"]   { border-color: green; }
.card[data-status="inactive"] { border-color: gray; opacity: .6; }
.card[data-status="pending"]  { border-color: orange; }

/* 数値範囲を含めるのは難しいが、複数値の前方一致は使える */
.score[data-value^="9"],
.score[data-value^="10"] { color: gold; }  /* 90点台以上 */

jQuery セレクタとの比較

jQueryCSS
$('[name=email]')[name="email"]
$('[name!=email]')無し:not([name="email"]) で代用
$('a[href^=https]')a[href^="https"]
$('a[href$=.pdf]')a[href$=".pdf"]
$('a[href*=youtube]')a[href*="youtube"]
$('div[data-foo]')div[data-foo]

複数属性セレクタの組合せ

/* 複数条件 AND(連結で書く) */
input[type="text"][required] { border: 2px solid red; }

/* 必須かつ未入力 */
input[required]:placeholder-shown { background: #fff3e0; }

/* 外部リンクで PDF(前方+後方両方マッチ) */
a[href^="http"][href$=".pdf"] {
  background: url(/icon/pdf.svg) right center no-repeat;
  padding-right: 20px;
}

/* type="checkbox" の選択時 */
input[type="checkbox"]:checked + label { font-weight: bold; }

パフォーマンス考慮

属性セレクタは class よりわずかに遅いですが、現代のブラウザでは実質体感差なし。気にせず使えます。ただし:

  • 大量要素(数千〜)の [attr*=...] による中間一致は若干コストがかかる
  • 同じ目的が class で達成できるなら class のほうがシンプル
  • HTML 構造に影響しないUI 状態の表現には属性セレクタが優位(class 操作不要)

FAQ

Q: [class~="btn"].btn、どちらが良い?
A: 動作は同じ。.btn のほうが短くて速いので通常はそちら。属性セレクタは class 以外を含めて統一したい時に。

Q: 属性に値が無いとき(checked など)の判定
A: [checked] で OK。値の有無は問わず、属性が存在するだけでマッチ。

Q: !=(否定)は使える?
A: 単体ではなし。:not([attr=value]) で書きます: input:not([type="hidden"])

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. タイプセレクタ
  2. ユニバーサルセレクタ
  3. クラスセレクタ
  4. IDセレクタ
  5. CSS属性セレクタで要素を絞り込む
  6. 疑似クラス

最近更新/作成されたページ