タイトル: IDセレクタ
SEOタイトル: CSS ID セレクタ(#id)の使い方と Specificity・class との使い分け
この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。
<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;background:#fffbea;border:1px solid #f4c430;margin:1em 0;width:100%"><tr><td style="background:#f4c430;color:#000;font-weight:bold;padding:8px">この記事の要点</td></tr><tr><td style="padding:10px"><ul><li><strong>ID セレクタ</strong>は <code>#myId { ... }</code> の形式で、HTML 要素の <code>id</code> 属性を指す</li><li>Specificity(詳細度)が <strong>100</strong> と高く、class(10)や要素セレクタ(1)より優先される</li><li><strong>同 1 ページに同じ id は 1 つだけ</strong>。複数あると JavaScript の <code>getElementById</code> も最初の 1 つしか取れない</li><li>主な用途: <strong>JavaScript フック</strong> / <strong>アンカーリンク</strong>(<code><a href="#section"></code>)/ <strong>label の for 属性</strong></li><li>近年は <strong>CSS Modules</strong> / <strong>BEM</strong> の普及で、見た目用には class、JS や a タグ用には id と役割分離が一般化</li></ul></td></tr></table>
<h2>ID セレクタの基本</h2>
<p>CSS で要素を選択する 3 大セレクタ(要素・class・ID)のうち、ID セレクタは <code>#</code>(シャープ)から始まります:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><!-- HTML -->
<h1 id="page-title">ようこそ</h1>
<div id="main-content">本文...</div>
<button id="submit-btn">送信</button></code></pre><pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-css">/* CSS */
#page-title {
color: #333;
font-size: 2em;
}
#main-content {
max-width: 800px;
margin: 0 auto;
}
#submit-btn {
background: #1a73e8;
color: white;
padding: 10px 20px;
}</code></pre>
<h2>class セレクタとの違い</h2>
<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>項目</th><th>ID セレクタ <code>#id</code></th><th>class セレクタ <code>.class</code></th></tr></thead>
<tbody>
<tr><td>同 1 ページに何個</td><td><strong>1 つだけ</strong></td><td>何個でも</td></tr>
<tr><td>1 要素に何個付くか</td><td>1 つだけ</td><td>複数可(<code>class="a b c"</code>)</td></tr>
<tr><td>Specificity(詳細度)</td><td><strong>100</strong></td><td>10</td></tr>
<tr><td>主な用途</td><td>JS フック / アンカー / label for</td><td>見た目スタイル / 再利用</td></tr>
<tr><td>JS API</td><td><code>getElementById()</code> 高速</td><td><code>getElementsByClassName()</code> / <code>querySelectorAll('.x')</code></td></tr>
</tbody>
</table>
<h2>Specificity(詳細度)と優先順位</h2>
<p>CSS は同じ要素に複数のルールが当たるとき、<strong>Specificity が高い方が勝つ</strong>仕様です。ID セレクタは class より 10 倍強い扱いです:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-css">/* Specificity 計算式: (a, b, c, d)
* a = インラインスタイル (style="...")
* b = ID セレクタの数
* c = class / 属性 / 擬似クラスの数
* d = 要素 / 擬似要素の数
*/
* { } /* 0,0,0,0 */
p { } /* 0,0,0,1 */
p.warning { } /* 0,0,1,1 */
#page-title { } /* 0,1,0,0 */
#page-title.large { } /* 0,1,1,0 */
style="color: red" /* 1,0,0,0 */
!important /* 全てを上書き */</code></pre><pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><!-- 例: どの色になる? -->
<p id="title" class="red">Hello</p>
<style>
p.red { color: red; } /* 0,0,1,1 = 11 */
#title { color: blue; } /* 0,1,0,0 = 100 ← 勝つ */
</style>
<!-- → 青色になる --></code></pre>
<h2>JavaScript からのアクセス</h2>
<p>ID は<strong>高速・確実</strong>に DOM を取得できる:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// 最も高速・直接的
const title = document.getElementById('page-title');
// querySelector で # 記法
const title2 = document.querySelector('#page-title');
// HTML5 以降: window.<id> でグローバル参照可(非推奨)
console.log(window.pageTitle); // <h1 id="page-title">
// id にハイフンが入っていても OK(変数名と違ってよい)
const el = document.getElementById('my-section');</code></pre>
<p><strong>注意</strong>: HTML5 では id は <strong>任意の文字列</strong>でよく、CSS で使うときだけハイフン名がエスケープが要る場合があります。</p>
<h2>ID 命名のルール</h2>
<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e8f5e9"><th>ルール</th><th>HTML5</th><th>HTML4 / XHTML</th></tr></thead>
<tbody>
<tr><td>空文字 NG</td><td>○ 不可</td><td>○ 不可</td></tr>
<tr><td>数字始まり</td><td>OK</td><td>NG(英字必須)</td></tr>
<tr><td>日本語</td><td>OK(実用は微妙)</td><td>NG</td></tr>
<tr><td>ハイフン・アンダースコア</td><td>OK</td><td>OK</td></tr>
<tr><td>スペース</td><td>NG(区切り文字扱い)</td><td>NG</td></tr>
<tr><td>大文字小文字</td><td>区別される</td><td>区別される</td></tr>
</tbody>
</table>
<p>命名は <strong>kebab-case</strong>(<code>main-content</code>)または <strong>camelCase</strong>(<code>mainContent</code>)が一般的。チーム内で統一しましょう。</p>
<h2>アンカーリンク(ページ内ジャンプ)</h2>
<p>ID の代表的な活用例。<code><a href="#id"></code> で当該要素までスクロール:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><!-- 目次 -->
<nav>
<a href="#intro">はじめに</a>
<a href="#install">インストール</a>
<a href="#usage">使い方</a>
</nav>
<h2 id="intro">はじめに</h2>
<p>...</p>
<h2 id="install">インストール</h2>
<p>...</p>
<h2 id="usage">使い方</h2>
<p>...</p>
<!-- ページ先頭へ -->
<a href="#top">トップへ戻る</a></code></pre><pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-css">/* 固定ヘッダがある場合、id へ飛んだ位置が隠れないように */
html {
scroll-behavior: smooth;
}
h2 {
scroll-margin-top: 80px; /* 固定ヘッダの高さ分 */
}</code></pre>
<h2>label の for 属性</h2>
<p>フォームの label と input を紐付けるのにも ID を使います:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><label for="email">メールアドレス</label>
<input type="email" id="email" name="email">
<!-- ラベルをクリックすると input がフォーカスされる -->
<!-- アクセシビリティ的にも推奨 --></code></pre>
<h2>ARIA との関係</h2>
<p>WAI-ARIA 属性は ID を参照することが多い:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><!-- aria-describedby で説明文を紐付け -->
<input type="password" aria-describedby="pwd-help">
<p id="pwd-help">8 文字以上、英数字混在</p>
<!-- aria-labelledby で複数要素をラベル化 -->
<div role="dialog" aria-labelledby="dlg-title">
<h2 id="dlg-title">確認</h2>
...
</div>
<!-- aria-controls -->
<button aria-controls="menu" aria-expanded="false">メニュー</button>
<ul id="menu" hidden>...</ul></code></pre>
<h2>同 1 ページに同じ id を複数置くと</h2>
<ul>
<li>HTML 仕様違反(バリデータでエラー)</li>
<li><code>getElementById()</code> は<strong>最初の 1 つ</strong>しか返さない</li>
<li>アンカー <code>#id</code> も最初の 1 つにスクロール</li>
<li>CSS は<strong>全部に当たる</strong>(動くが規約違反)</li>
<li>スクリーンリーダーが混乱する</li>
</ul>
<h2>id と class、どちらを使うべきか</h2>
<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#fff3e0"><th>用途</th><th>推奨</th></tr></thead>
<tbody>
<tr><td>見た目スタイル(再利用したい)</td><td>class</td></tr>
<tr><td>ボタンの色を統一</td><td>class</td></tr>
<tr><td>ページ内ジャンプ先</td><td>id</td></tr>
<tr><td>label と input の紐付け</td><td>id</td></tr>
<tr><td>JavaScript で特定の 1 要素を操作</td><td>id or data-* 属性</td></tr>
<tr><td>同じスタイルを複数要素に</td><td>class</td></tr>
<tr><td>ARIA で参照したい</td><td>id 必須</td></tr>
</tbody>
</table>
<p>近年の SPA / コンポーネント設計では、<strong>見た目は class、JS フックは <code>data-testid</code> や <code>data-action</code></strong>、a タグや ARIA 用に id、と役割分離する設計が一般的です。</p>
<h2>CSS Modules / styled-components 時代の ID</h2>
<p>React / Vue で CSS Modules や styled-components を使うと、class 名が自動ハッシュ化されます。ID は<strong>ハッシュ化されない</strong>ので、ページ内アンカーや label/for で活用できます:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-jsx">// CSS Modules
import styles from './Form.module.css';
function Form() {
return (
<>
<label htmlFor="user-email">メール</label>
<input id="user-email" className={styles.input} />
</>
);
}
// → <input id="user-email" class="Form_input__abc123">
// id は素のまま、class はハッシュ化</code></pre>
<h2>FAQ</h2>
<p><strong>Q: ID セレクタは使わない方がいい?</strong><br />
A: 「見た目用途で使わない」のが現代のベストプラクティス。Specificity が高すぎて<strong>上書きが大変</strong>です。JS フック / アンカー / label 専用と割り切ると綺麗になります。</p>
<p><strong>Q: id を数字始まりにできる?</strong><br />
A: HTML5 では可能。ただし CSS で <code>#1title</code> と書くとエラーになるので、<code>#\31 title</code> とエスケープが要ります。実用上は英字始まりが無難。</p>
<p><strong>Q: CSS で <code>div#title</code> と書く意味は?</strong><br />
A: id は元々一意なので <code>#title</code> だけで十分。要素名を付けると Specificity が <code>0,1,0,1</code> に上がり、後の上書きが余計困難になります。</p>