10日で覚えるCSSDay 2: セレクタとカスケード
books.chapter 210日で覚えるCSS

Day 2: セレクタとカスケード

今日学ぶこと

  • 結合セレクタと擬似クラス
  • 詳細度(Specificity)の仕組み
  • カスケードと優先順位
  • 継承(Inheritance)

結合セレクタ

子孫セレクタ(スペース)

/* article内のすべてのp */
article p {
    line-height: 1.8;
}

子セレクタ(>

/* ulの直接の子のliだけ */
ul > li {
    list-style: disc;
}

隣接兄弟セレクタ(+

/* h2の直後のp */
h2 + p {
    font-size: 1.2rem;
    color: #64748b;
}

一般兄弟セレクタ(~

/* h2の後のすべてのp */
h2 ~ p {
    margin-left: 16px;
}
flowchart TB
    subgraph Combinators["結合セレクタ"]
        Desc["子孫<br>A B"]
        Child["子<br>A &gt; B"]
        Adj["隣接兄弟<br>A + B"]
        Gen["一般兄弟<br>A ~ B"]
    end
    style Desc fill:#3b82f6,color:#fff
    style Child fill:#22c55e,color:#fff
    style Adj fill:#f59e0b,color:#fff
    style Gen fill:#8b5cf6,color:#fff

グループセレクタ(,

h1, h2, h3 {
    color: #1e293b;
}

属性セレクタ

/* href属性を持つa */
a[href] {
    color: #3b82f6;
}

/* 外部リンク */
a[target="_blank"] {
    text-decoration: underline;
}

/* httpsで始まるリンク */
a[href^="https"] {
    color: #22c55e;
}

/* .pdfで終わるリンク */
a[href$=".pdf"] {
    color: #ef4444;
}

/* "example"を含むリンク */
a[href*="example"] {
    font-weight: bold;
}
セレクタ 意味
[attr] 属性が存在する
[attr="val"] 値が一致
[attr^="val"] 値が~で始まる
[attr$="val"] 値が~で終わる
[attr*="val"] 値が~を含む

擬似クラス

リンク・インタラクション系

a:link    { color: #3b82f6; }    /* 未訪問 */
a:visited { color: #8b5cf6; }    /* 訪問済み */
a:hover   { color: #2563eb; }    /* マウスオーバー */
a:active  { color: #1d4ed8; }    /* クリック中 */
a:focus   { outline: 2px solid #3b82f6; }  /* フォーカス */

順序: リンクの擬似クラスは LVHA(Link, Visited, Hover, Active)の順で書きましょう。

構造系

li:first-child { font-weight: bold; }
li:last-child  { border-bottom: none; }
li:nth-child(2) { color: #3b82f6; }
li:nth-child(odd)  { background: #f8fafc; }
li:nth-child(even) { background: #f1f5f9; }
li:nth-child(3n)   { color: #ef4444; }    /* 3の倍数 */
擬似クラス 説明
:first-child 最初の子要素
:last-child 最後の子要素
:nth-child(n) n番目の子要素
:nth-child(odd/even) 奇数/偶数番目
:not(selector) 指定外の要素
:empty 中身が空の要素
:focus-visible キーボードフォーカス

:not() 擬似クラス

/* 最後の要素以外にborder-bottom */
li:not(:last-child) {
    border-bottom: 1px solid #e2e8f0;
}

擬似要素

/* 最初の文字を大きく */
p::first-letter {
    font-size: 2rem;
    font-weight: bold;
}

/* 最初の行を太字に */
p::first-line {
    font-weight: bold;
}

/* 要素の前に追加 */
.required::before {
    content: "* ";
    color: #ef4444;
}

/* 要素の後に追加 */
a[target="_blank"]::after {
    content: " ↗";
}
擬似要素 説明
::before 要素の前にコンテンツを挿入
::after 要素の後にコンテンツを挿入
::first-letter 最初の文字
::first-line 最初の行
::placeholder プレースホルダーテキスト
::selection 選択したテキスト

詳細度(Specificity)

CSSの核心的な概念です。複数のルールが同じ要素に適用される場合、詳細度が高いルールが優先されます。

詳細度の計算

flowchart LR
    subgraph Specificity["詳細度の重み"]
        Inline["インラインスタイル<br>1,0,0,0"]
        ID["IDセレクタ<br>0,1,0,0"]
        Class["クラス/擬似クラス<br>0,0,1,0"]
        Elem["要素/擬似要素<br>0,0,0,1"]
    end
    Inline --> ID --> Class --> Elem
    style Inline fill:#ef4444,color:#fff
    style ID fill:#f59e0b,color:#fff
    style Class fill:#22c55e,color:#fff
    style Elem fill:#3b82f6,color:#fff
セレクタ 詳細度 計算
p 0,0,0,1 要素 × 1
.highlight 0,0,1,0 クラス × 1
p.highlight 0,0,1,1 クラス × 1 + 要素 × 1
#main 0,1,0,0 ID × 1
#main .highlight p 0,1,1,1 ID + クラス + 要素

p { color: black; }                  /* 0,0,0,1 */
.text { color: blue; }              /* 0,0,1,0 → 勝つ */
#intro { color: red; }              /* 0,1,0,0 → さらに勝つ */
<p id="intro" class="text">このテキストは赤色です。</p>

!important: color: green !important; はすべての詳細度を上書きしますが、使用は最小限にしましょう。デバッグが困難になります。


カスケード

「カスケード(Cascade)」とは、複数のスタイルルールの優先順位を決定する仕組みです。

優先順位の決定順序

flowchart TB
    A["1. 重要度<br>!important > 通常"] --> B["2. 詳細度<br>ID > クラス > 要素"]
    B --> C["3. ソース順<br>後に書いたものが優先"]
    style A fill:#ef4444,color:#fff
    style B fill:#f59e0b,color:#fff
    style C fill:#22c55e,color:#fff
/* ソース順: 後に書いたものが優先される(詳細度が同じ場合) */
p { color: blue; }
p { color: red; }   /* ← こちらが適用される */

継承(Inheritance)

一部のCSSプロパティは、親要素から子要素に自動的に継承されます。

継承されるプロパティ

body {
    font-family: sans-serif;   /* ✅ 継承される */
    color: #333;               /* ✅ 継承される */
    line-height: 1.6;          /* ✅ 継承される */
}

継承されないプロパティ

.box {
    border: 1px solid #ccc;    /* ❌ 継承されない */
    padding: 16px;             /* ❌ 継承されない */
    margin: 16px;              /* ❌ 継承されない */
    background: #f0f0f0;       /* ❌ 継承されない */
}
継承される 継承されない
color margin
font-family padding
font-size border
line-height background
text-align width / height
cursor display

強制的に継承させる

.box {
    border: inherit;  /* 親のborderを継承 */
}

実践: カード型レイアウト

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>セレクタの実践</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>ニュース一覧</h1>
    <article class="card">
        <h2>記事タイトル1</h2>
        <p class="meta">2026年1月29日 | <span class="tag">CSS</span></p>
        <p>記事の本文テキストが入ります...</p>
        <a href="#" class="read-more">続きを読む</a>
    </article>
    <article class="card">
        <h2>記事タイトル2</h2>
        <p class="meta">2026年1月28日 | <span class="tag">HTML</span></p>
        <p>記事の本文テキストが入ります...</p>
        <a href="#" class="read-more">続きを読む</a>
    </article>
</body>
</html>
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: sans-serif;
    line-height: 1.6;
    color: #333;
    max-width: 600px;
    margin: 0 auto;
    padding: 32px 16px;
}

h1 {
    margin-bottom: 24px;
}

.card {
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    padding: 24px;
    margin-bottom: 16px;
}

.card:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.card h2 {
    color: #1e293b;
    margin-bottom: 8px;
}

.card .meta {
    color: #94a3b8;
    font-size: 0.875rem;
    margin-bottom: 12px;
}

.tag {
    background-color: #eff6ff;
    color: #3b82f6;
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 0.75rem;
}

.read-more {
    color: #3b82f6;
    text-decoration: none;
    font-weight: bold;
}

.read-more:hover {
    text-decoration: underline;
}

.card:first-child {
    border-left: 4px solid #3b82f6;
}

まとめ

概念 説明
結合セレクタ 子孫、子、兄弟を指定
擬似クラス :hover, :nth-child() など状態を指定
擬似要素 ::before, ::after で要素を追加
詳細度 セレクタの優先順位(ID > クラス > 要素)
カスケード 重要度 → 詳細度 → ソース順
継承 親から子へプロパティが伝わる仕組み

重要ポイント

  1. クラスセレクタを中心に使い、IDセレクタは避ける
  2. 詳細度は低く保つのがベストプラクティス
  3. !important最後の手段
  4. 継承されるプロパティとされないプロパティを把握する

練習問題

問題1: 基本

テーブルの偶数行と奇数行に異なる背景色をnth-childで設定してください。

問題2: 応用

ナビゲーションリンクに:hover:focus-visibleのスタイルを設定してください。現在のページのリンクには特別なクラスをつけましょう。

チャレンジ問題

5つのCSSルールの詳細度を計算し、適用される順番を予測してください。その後ブラウザで確認しましょう。


参考リンク


次回予告: Day 3では「ボックスモデル」について学びます。CSSレイアウトの基盤となる概念をマスターしましょう。