CSS講座 / 基本セレクター:要素・クラス・ID・属性

CSSセレクターは、規則を適用するHTML要素を選ぶ条件です。要素名、再利用するクラス、一意のID、属性の有無や値を使い分け、見た目ではなく実際のHTMLに一致するかを判断します。

同じHTMLで選ばれる対象を比較する

次のAとBはnoticeクラスのpで、Bにはurgentもあります。Cはクラスのないp、Dはnoticeクラスのdivです。A〜Dは対象を説明するための表示文字であり、CSSの構文ではありません。

<p id="opening" class="notice" data-tags="garden visit">A: Operating hours</p>
<p class="notice urgent">B: Rainy weather notice</p>
<p>C: What you need</p>
<div class="notice">D: Information box</div>

pはA・B・C、.noticeはA・B・D、p.noticeはA・Bを選びます。.notice.urgentは両方のクラスがあるBだけです。#openingはAのIDに、[data-tags~="visit"]はAの空白区切りの単語visitに一致します。

p.noticeの二条件は同じ要素について調べます。p .noticeはpの内側にある別の要素を探します。空白による違いは結合子と擬似クラスの構造図とも比較してください。

要素セレクターと全称セレクター

p { color: #333; }
* { box-sizing: border-box; }

pはp要素全体を選びます。案内文と本文の段落を別に装飾するにはクラスなどの条件を加えます。*はすべての要素を選ぶ全称セレクターで、擬似要素まで自動的に含める指定ではありません。

ここでのbox-sizing: border-boxは、幅や高さにpaddingとborderを含めて計算する補助設定です。全称セレクターを使うからといって、全要素の文字色や背景色を同じにする必要はありません。共通の基礎設定と、個別に装飾する部分を分けます。

クラスとIDを選ぶ

.notice { background-color: #e9f7ef; }
p.notice { border-left: 4px solid #087f5b; }
.notice.urgent { font-weight: bold; }
#opening { color: #087f5b; }

class="notice urgent"は空白を含む一つの名前ではなく、二つのクラスです。クラスは複数の要素で再利用でき、.notice.urgentは両方を持つ場合だけ一致します。

IDは一つのHTML文書内で一意にします。同じ案内を十個作るとき、すべてにid="opening"を付けないでください。再利用する装飾にはクラス、一意の識別やフラグメントの移動先にはIDが適しています。

IDセレクターはクラスより詳細度が高いものの、その比較より前に出所・重要度・レイヤーなどを判断します。強くするためにIDを増やすと後で管理しにくくなります。詳細度の比較条件を確認し、必要な範囲を選べる最小限の条件を使います。

属性の有無と値を比較する

input[required] { border: 2px solid #087f5b; }
input[type="email"] { background-color: #fff4cc; }
[data-tags~="visit"] { outline: 1px dashed #777; }
a[href^="https://"] { color: #1d4ed8; }

[required]は属性があれば値が空でも一致します。[type="email"]は値の完全一致、[data-tags~="visit"]は空白区切りの一単語との一致です。garden visitには一致してもrevisitには一致しません。

[href^="https://"]は文字列の先頭を調べる条件で、外部サイトを識別する機能ではありません。同じサイトのURLでもhttpsで始まります。また[data-tags="visit"]は属性値全体を比較するのでgarden visitには一致しません。MDNの属性セレクターで比較演算子を確認できます。

完全な例を保存して実行する

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Small Garden</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 24px; font-family: sans-serif; line-height: 1.7; }
    p { color: #333; }
    .notice { background-color: #e9f7ef; padding: 12px; }
    p.notice { border-left: 4px solid #087f5b; }
    .notice.urgent { font-weight: bold; }
    #opening { color: #087f5b; }
    [data-tags~="visit"] { outline: 1px dashed #777; }
    a[href^="https://"] { color: #1d4ed8; }
    input[required] { border: 2px solid #087f5b; }
    input[type="email"] { background-color: #fff4cc; }
  </style>
</head>
<body>
<h1>Small Garden</h1>
  <p id="opening" class="notice" data-tags="garden visit">A: We open at 9am every day.</p>
  <p class="notice urgent">B: In case of rain, the outdoor program will be canceled.</p>
  <p>C: Bring a water bottle and comfortable shoes.</p>
  <div class="notice">D: This is an information box.</div>
  <p><a href="https://example.com/">E: External guidance link</a></p>
  <form>
    <label for="email">Email (required)</label>
    <input id="email" type="email" name="email" required>
    <button type="submit">Request information</button>
  </form>
</body>
</html>

全体をindex.htmlに保存して開きます。A・B・Dに薄い背景と12pxの余白、A・Bだけに左枠が付きます。Bは複数クラスで太字になり、AはIDで緑になって属性条件による点線の輪郭も付きます。Cは普通の段落のままです。

メール入力はrequired条件で枠が太くなり、type条件で背景が黄色になります。実際の必須入力の検証はHTML属性の役割で、CSSは見た目を変えているだけです。例の外部アドレスは表示用で、実在サービスの案内リンクとして使うものではありません。

属性があることと、検証結果が正しいことは別の条件です。実際の状態の装飾はフォームの状態セレクターで比較します。

条件を変え、予想してから確認する

  1. 左枠のp.noticeを.noticeに変えます。対象が広がり、Dにも左枠が付くことを確認して戻します。
  2. Bをclass="urgent"だけにします。pであることは変わりませんが、notice条件を失うので背景・左枠・複合クラスによる太字が外れます。確認後はクラスを戻します。
  3. Aのdata-tagsをgarden revisitに変えます。独立したvisitという単語がないので点線が消えます。部分文字列の一致と混同しないようにします。

保存してから再読み込みし、一つの条件を確認するごとに元へ戻します。対象が予想どおり変わらなければclass・id・属性名を実際のHTMLと照合し、開発者ツールで規則の一致と競合を分けて確認します。