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
|
| プロパティ | 何を変えるか |
color・font-size・margin
|
| 値 | どう変えるか |
red・36px・16px
|
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フレームワーク完全解説(近日公開)