2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🎨 CSSを基礎から深く学ぼう【第一回】CSSの基礎・セレクター・詳細度・カスケード・CSS変数

2
Posted at

1. 👋 はじめに

「CSSってなんとなく書けるけど、なぜこのスタイルが効かないのかわからない…」
「詳細度って何?」
!important を使いまくってしまっている…」

このシリーズでは CSSを基礎からしっかり深掘り して解説します!

このシリーズの目標:
「なんとなく書いていたCSS」から「仕組みを理解して自信を持って書けるCSS」へレベルアップすること!

この記事を読めば:

  • ✅ CSSの書き方と3種類の適用方法がわかる
  • ✅ セレクターの種類を理解できる
  • ✅ 詳細度(Specificity)の計算方法がわかる
  • ✅ カスケードと継承の仕組みがわかる
  • ✅ CSS変数(カスタムプロパティ)の使い方がわかる

2. 🎨 CSSとは?

一言で言うと

CSS(Cascading Style Sheets)とは「HTMLの見た目を装飾するためのスタイルシート言語」です。

HTMLとCSSの役割分担:

HTML → 🏗️ 骨格・構造
       「ここに見出しがある」「ここにリストがある」

CSS  → 🎨 見た目・デザイン
       「見出しは赤色」「リストの余白は16px」

CSSの基本構文

セレクター {
  プロパティ: ;
  プロパティ: ;
}
/* 例:h1タグのテキストを赤色・36pxにする */
h1 {
  color: red;
  font-size: 36px;
}
部分 説明
セレクター どの要素にスタイルを当てるか h1.card#header
プロパティ 何を変えるか colorfont-sizemargin
どう変えるか red36px16px

3. 📝 CSSの書き方(3種類)

① 外部ファイル(推奨)

<!-- HTMLのheadタグで読み込む -->
<head>
  <link rel="stylesheet" href="style.css" />
</head>
属性 意味 値の説明
rel このファイルとHTMLの関係性(relationship)を示す "stylesheet" = スタイルシートとして読み込む
href 読み込むファイルの場所(パス) を示す "style.css" = 同じフォルダのstyle.css
<!-- 同じフォルダにあるCSSファイル -->
<link rel="stylesheet" href="style.css" />

<!-- cssフォルダの中にあるCSSファイル -->
<link rel="stylesheet" href="css/style.css" />

<!-- 1つ上のフォルダのCSSファイル -->
<link rel="stylesheet" href="../style.css" />

<!-- URLを直接指定(外部CDNなど) -->
<link rel="stylesheet" href="https://example.com/reset.css" />
/* style.css */
h1 {
  color: red;
}

② 内部スタイル(styleタグ)

<head>
  <style>
    h1 {
      color: red;
    }
  </style>
</head>

③ インラインスタイル(原則避ける)

<h1 style="color: red;">タイトル</h1>

3種類の使い分け

方法 推奨度 向いている場面
外部ファイル ✅ 推奨 通常のWeb制作・複数ページで共有
内部スタイル ⚠️ 限定的 小さなページ・メールHTML
インライン ❌ 原則避ける JavaScriptで動的に変更するとき

⚠️ インラインスタイルを避ける理由

  • 詳細度が最も高く(後述)上書きしにくい
  • HTMLとCSSが混在して管理しにくい
  • 同じスタイルを複数箇所に書く羽目になる

4. 🎯 セレクター

基本セレクター

/* ① タグセレクター:そのタグすべてに適用 */
p {
  color: gray;
}

/* ② クラスセレクター:class属性が一致する要素に適用 */
.card {
  background: white;
  border: 1px solid gray;
}

/* ③ IDセレクター:id属性が一致する要素に適用(ページに1つ) */
#header {
  background: navy;
}

/* ④ ユニバーサルセレクター:すべての要素に適用 */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

複合セレクター

/* ⑤ 子孫セレクター(半角スペース):nav の中のすべての a */
nav a {
  text-decoration: none;
}

/* ⑥ 子セレクター(>):ulの直接の子のliのみ(孫は含まない) */
ul > li {
  list-style: none;
}

/* ⑦ 隣接兄弟セレクター(+):h2の直後のpのみ */
h2 + p {
  margin-top: 0;
}

/* ⑧ 一般兄弟セレクター(~):h2の後にあるすべてのp */
h2 ~ p {
  color: gray;
}

/* ⑨ 複数セレクター(,):h1とh2とh3すべてに適用 */
h1, h2, h3 {
  font-weight: bold;
}

属性セレクター

/* 属性が存在する要素 */
a[target] {
  color: blue;
}

/* 属性の値が完全一致 */
input[type="text"] {
  border: 1px solid gray;
}

/* 属性の値が前方一致(〜で始まる) */
a[href^="https"] {
  color: green;  /* httpsリンクを緑色に */
}

/* 属性の値が後方一致(〜で終わる) */
a[href$=".pdf"] {
  color: red;    /* PDFリンクを赤色に */
}

/* 属性の値を部分一致(〜を含む) */
a[href*="example"] {
  font-weight: bold;
}

疑似クラスセレクター

疑似クラスとは「要素の状態や位置に基づいてスタイルを当てる」セレクターです。

/* ホバー時(マウスが乗ったとき) */
button:hover {
  background: darkblue;
  cursor: pointer;
}

/* フォーカス時(キーボードやクリックで選択されたとき) */
input:focus {
  outline: 2px solid blue;
}

/* 訪問済みリンク */
a:visited {
  color: purple;
}

/* 最初の子要素 */
li:first-child {
  font-weight: bold;
}

/* 最後の子要素 */
li:last-child {
  border-bottom: none;
}

/* n番目の子要素 */
li:nth-child(2) {
  color: red;      /* 2番目のli */
}
li:nth-child(odd) {
  background: #f5f5f5;  /* 奇数番目のli(縞模様テーブルに使う) */
}
li:nth-child(even) {
  background: white;    /* 偶数番目のli */
}

/* 唯一の子要素のとき */
p:only-child {
  font-style: italic;
}

/* 否定(〜以外) */
li:not(:last-child) {
  border-bottom: 1px solid gray;  /* 最後の要素以外に下線 */
}

/* 必須入力フィールド */
input:required {
  border-left: 4px solid red;
}

/* 無効化された要素 */
button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* チェックされたチェックボックス */
input[type="checkbox"]:checked {
  accent-color: blue;
}

疑似要素セレクター

疑似要素とは「HTML要素の特定の部分にスタイルを当てる」セレクターです。
:: (コロン2つ)で書きます。

💡 ::: どちらでも動く?
CSS3から疑似クラス(:)と疑似要素(::)を区別するために
コロン2つ(::)が標準になりました。
ただしブラウザの互換性のため、古い書き方のコロン1つ(例::before:after)でも動作します。
既存のコードで :before を見かけることがありますが、
新規開発では必ず ::before と書きましょう。

/* テキストの最初の1文字 */
p::first-letter {
  font-size: 2em;
  font-weight: bold;
  float: left;
  margin-right: 4px;
}

/* テキストの最初の行 */
p::first-line {
  font-weight: bold;
}

/* 要素の前に内容を追加 */
.card::before {
  content: "★ ";
  color: gold;
}

/* 要素の後に内容を追加 */
.required::after {
  content: " ※必須";
  color: red;
  font-size: 0.8em;
}

/* テキスト選択時のスタイル */
::selection {
  background: yellow;
  color: black;
}

/* placeholderのスタイル */
input::placeholder {
  color: lightgray;
  font-style: italic;
}

5. ⚖️ 詳細度(Specificity)

詳細度とは?

詳細度とは「複数のCSSルールが競合したとき、どちらが優先されるかを決めるスコア」です。
「なぜこのスタイルが効かないのか」の原因の多くがここにあります!

詳細度の計算方法

詳細度は 4つの数字(A, B, C, D) で表されます。

A  - B  - C  - D
↑    ↑    ↑    ↑
│    │    │    └─ タグセレクター・疑似要素の数
│    │    └─ クラス・属性・疑似クラスの数
│    └─ IDセレクターの数
└─ インラインスタイル(あれば1)

具体的な計算例

セレクター A B C D スコア
p 0 0 0 1 0,0,0,1
.card 0 0 1 0 0,0,1,0
p.card 0 0 1 1 0,0,1,1
#header 0 1 0 0 0,1,0,0
#header .nav 0 1 1 0 0,1,1,0
style="" 1 0 0 0 1,0,0,0

💡 疑似クラス・疑似要素の詳細度

種類 詳細度
疑似クラス クラスと同じ(0,0,1,0) :hover:nth-child():focus
疑似要素 タグと同じ(0,0,0,1) ::before::after::first-line

:not():is():where() の特殊なルール:

/* :not() 自体は詳細度を持たない
   ただしカッコの中身の詳細度が加算される */
:not(.card) { }     /* → 0,0,1,0(.cardの詳細度が加算) */
:not(p) { }         /* → 0,0,0,1(pの詳細度が加算) */

/* :is() → カッコ内で最も高い詳細度を採用 */
:is(.card, #header) { }  /* → 0,1,0,0(#headerの詳細度を採用) */

/* :where() → 常に詳細度が0!上書きしやすいスタイルを書くときに便利 */
:where(.card, #header) { }  /* → 0,0,0,0 */
/* 詳細度の競合例 */
p { color: blue; }          /* 0,0,0,1 */
.text { color: red; }       /* 0,0,1,0 ← こちらが勝つ */

.text { color: red; }       /* 0,0,1,0 */
#main .text { color: green; } /* 0,1,1,0 ← こちらが勝つ */

詳細度が同じ場合は?

/* どちらも 0,0,1,0 */
.red { color: red; }
.blue { color: blue; }  /* ← 後に書いた方が勝つ(カスケード) */

💡 詳細度の高い順:
インライン > ID > クラス・属性・疑似クラス > タグ・疑似要素

!important について

/* !important:詳細度を無視して最優先にする */
p {
  color: red !important;  /* どんな詳細度のルールよりも優先される */
}

⚠️ !important は最終手段!
使いすぎると:

  • どのスタイルが効いているのか追いにくくなる
  • 上書きするために !important をさらに使う悪循環になる
  • チームでの保守が困難になる

「なぜスタイルが効かないのか」を詳細度の観点から調べて解決するのが正しいアプローチです。


6. 🌊 カスケードとは?

カスケード(Cascade)とは「複数のCSSルールを決まった順序で適用する仕組み」です。
CSSの「C」はCascadeの頭文字です!

カスケードの優先順位

優先度が高い順(上が最優先):

① !important のルール
② インラインスタイル(style属性)
③ IDセレクター
④ クラス・属性・疑似クラスセレクター
⑤ タグ・疑似要素セレクター
⑥ 詳細度が同じ場合は後に書いたもの

💡 現代CSS:@layer でレイヤーごとに優先順位を管理できる!
近年のモダンCSSでは @layer(カスケードレイヤー)を使うことで、
詳細度の競合を気にせずレイヤー単位で優先順位を制御できます。

/* レイヤーの優先順位を宣言(後に書いたレイヤーが優先) */
@layer base, components, utilities;

@layer base {
  p { color: gray; }       /* 優先度:低 */
}

@layer components {
  .card p { color: blue; } /* 優先度:中 */
}

@layer utilities {
  .text-red { color: red; } /* 優先度:高(詳細度に関係なく勝つ!) */
}

Tailwind CSS v4などの最新フレームワークでも @layer が活用されています。
詳しくは第四回のフレームワーク解説で触れます!

ソースの順序

/* 同じ詳細度のとき:後に書いたものが勝つ */
.button {
  background: blue;
}

.button {
  background: red;  /* ← こちらが適用される */
}

7. 🔗 継承とは?

一言で言うと

継承とは「親要素のスタイルが子要素に引き継がれる仕組み」です。

<div class="container">
  <p>このテキストは青色になる</p>
  <span>これも青色になる</span>
</div>
.container {
  color: blue;  /* 子要素の p・span にも引き継がれる */
}

継承されるプロパティ・されないプロパティ

継承される(テキスト系) 継承されない(ボックス系)
color margin
font-size padding
font-family border
font-weight width / height
line-height background
text-align position

継承を制御するキーワード

.child {
  /* 親のスタイルを明示的に引き継ぐ */
  color: inherit;

  /* プロパティの初期値に戻す */
  color: initial;

  /* 継承可能なら inherit・そうでなければ initial */
  color: unset;
}

8. 🎨 CSS変数(カスタムプロパティ)

CSS変数とは?

CSS変数(カスタムプロパティ)とは「CSSの中で値を変数として管理できる仕組み」です。
色・サイズ・フォントなどを一元管理できます。

基本的な使い方

/* 変数の定義(:root = HTML全体で使える) */
:root {
  --color-primary: #3b82f6;     /* メインカラー */
  --color-secondary: #10b981;   /* サブカラー */
  --color-text: #1f2937;        /* テキストカラー */
  --color-bg: #f9fafb;          /* 背景色 */

  --font-size-sm: 14px;
  --font-size-md: 16px;
  --font-size-lg: 20px;
  --font-size-xl: 24px;

  --spacing-sm: 8px;
  --spacing-md: 16px;
  --spacing-lg: 24px;
  --spacing-xl: 32px;

  --border-radius: 8px;
  --shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* 変数の使用(var(--変数名)) */
.button {
  background: var(--color-primary);
  color: white;
  padding: var(--spacing-sm) var(--spacing-md);
  border-radius: var(--border-radius);
  font-size: var(--font-size-md);
}

.card {
  background: var(--color-bg);
  padding: var(--spacing-lg);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow);
}

CSS変数のメリット

/* ❌ 変数なし:色を変えるときに全箇所を修正する必要がある */
.button { background: #3b82f6; }
.link { color: #3b82f6; }
.border { border-color: #3b82f6; }

/* ✅ 変数あり:1箇所だけ変えれば全部変わる! */
:root {
  --color-primary: #3b82f6;
}
.button { background: var(--color-primary); }
.link { color: var(--color-primary); }
.border { border-color: var(--color-primary); }

CSS変数はコンポーネント単位で上書きできる!

CSS変数は親要素で定義した値が子要素に継承されます。
この特性を利用すると、コンポーネント単位でテーマを動的に変えられます。

/* ベースのカードスタイル */
.card {
  --color-primary: #3b82f6;  /* デフォルトは青 */
}

/* dangerクラスがつくと内部の変数だけ変わる */
.card.danger {
  --color-primary: #ef4444;  /* 赤に上書き */
}

/* .card .button は親の変数を参照するので自動的に色が変わる! */
.card .button {
  background: var(--color-primary);
}

/*
  <div class="card">
    <button class="button">青いボタン</button>   ← #3b82f6(青)
  </div>

  <div class="card danger">
    <button class="button">赤いボタン</button>   ← #ef4444(赤)
  </div>
*/

フォールバック値

/* var(--変数名, フォールバック値) */
/* 変数が未定義のときに使われる値 */
.button {
  background: var(--color-primary, blue);  /* --color-primaryがなければblue */
}

ダークモードの実装例

/* ライトモード(デフォルト) */
:root {
  --color-bg: #ffffff;
  --color-text: #1f2937;
  --color-card: #f9fafb;
}

/* ダークモード */
@media (prefers-color-scheme: dark) {
  :root {
    --color-bg: #111827;
    --color-text: #f9fafb;
    --color-card: #1f2937;
  }
}

/* コンポーネントはそのまま(変数が自動的に切り替わる!) */
body {
  background: var(--color-bg);
  color: var(--color-text);
}

.card {
  background: var(--color-card);
}

💡 CSS変数はJavaScriptからも操作できます!

// CSS変数の値を変更する
document.documentElement.style.setProperty('--color-primary', '#ef4444');

// CSS変数の値を取得する
const primary = getComputedStyle(document.documentElement)
  .getPropertyValue('--color-primary');

9. 🎯 まとめ

概念 一言で言うと
🎨 CSS HTMLの見た目を装飾するスタイルシート言語
🎯 セレクター どの要素にスタイルを当てるかを指定する
⚖️ 詳細度 CSSルールの優先順位を決めるスコア
🌊 カスケード 複数のCSSルールを順序で適用する仕組み
🔗 継承 親要素のスタイルが子要素に引き継がれる仕組み
🎨 CSS変数 値を変数として管理できる仕組み

詳細度で迷ったときの覚え方

インライン > ID > クラス > タグ
  (1,0,0,0)  (0,1,0,0)  (0,0,1,0)  (0,0,0,1)

「いい(ID)クラス(class)タグ(tag)」

CSSで「なぜ効かないのか」の原因の多くは詳細度にあります。
ブラウザの開発者ツール(F12)でどのスタイルが適用されているか確認しながら、詳細度を意識してCSSを書く習慣をつけましょう💪

次回は ボックスモデル・Flexbox・Grid・position・レスポンシブ を解説します!
レイアウトの仕組みを完全に理解しましょう🌟

💬 質問や感想があれば、コメント欄でお気軽にどうぞ!
👍 役に立ったら、いいね&ストックをお願いします!
🎓 ここまで読んでくださって、本当にありがとうございました!


🔗 シリーズ記事

  • 【第一回】CSSの基礎・セレクター・詳細度・カスケード・CSS変数(この記事)
  • 【第二回】ボックスモデル・Flexbox・Grid・レスポンシブ(近日公開)
  • 【第三回】アニメーション・疑似クラス・高度なCSS(近日公開)
  • 【第四回】Tailwind CSS・shadcn/ui・CSSフレームワーク完全解説(近日公開)
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?