CSS

CSSとは

CSS(Cascading Style Sheets)は、[[HTML]] で作った構造に見た目を与える言語です。色・フォント・余白・配置・アニメーションまで、画面上の表現のほぼすべてを担当します。

h1 {
  color: teal;
  font-size: 2rem;
}

初学者向けポイント

  • 「セレクタ { プロパティ: 値; }」が基本形。セレクタで「どこに」、プロパティで「何を」指定する
  • カスケード(Cascading) = 複数のスタイルが重なったとき、詳細度や記述順で勝敗が決まる仕組み
  • レイアウトの主役は Flexbox(1方向の並び)と Grid(格子状の配置)

よく使う概念

概念説明
ボックスモデル要素は content + padding + border + margin の箱として描画される
レスポンシブ@media で画面幅ごとにスタイルを切り替える
疑似クラス:hover :focus など状態に応じたスタイル
CSS変数--main-color: teal; のように値を再利用できる

なぜスタイルが効かないのか

CSSで最初につまずくのは、たいてい「書いたのに反映されない」場面です。原因の多くはカスケードの勝敗ルールにあります。同じ要素に複数の宣言が当たったとき、CSSは次の順で勝者を決めます。

  1. !important が付いているか
  2. 詳細度が高いか — インラインの style 属性 > id(#main)> クラス・疑似クラス・属性(.card:hover)> 要素(p)
  3. それでも同点なら、後に書かれた方が勝つ
#sidebar p { color: gray; } /* id 1個 */
.note      { color: red; }  /* クラス1個 */

.note を後から書いても、#sidebar p のほうが詳細度が高いため文字はグレーのままです。ここで !important を足せば目の前は直りますが、次に上書きしたいときにさらに強い宣言が必要になり、やがて誰も安全に触れないCSSになります。セレクタは必要最小限の強さで書く、idではなくクラスで当てる、というのが実務の定石です。開発者ツールで要素を選ぶと負けた宣言に取り消し線が付くので、まずそこを見ると原因がすぐ分かります。

ボックスモデルの落とし穴

width: 100% を指定した要素に padding: 16px を足すと、多くの初学者が「はみ出した」と驚きます。既定の box-sizing: content-box では width が指すのはcontentの幅だけで、paddingとborderはその外側に加算されるためです。親が400pxなら実際の占有幅は 400 + 16 × 2 = 432px になり、横スクロールが出ます。

*,
*::before,
*::after {
  box-sizing: border-box;
}

border-box にすると width はpaddingとborderを含んだ値になり、400pxは400pxのままです。今のプロジェクトはほぼ例外なくこの指定から始めます。

単位の選び方

長さの単位は、固定したいのか、何かに追従させたいのかで選びます。

単位基準向く用途
px絶対値境界線の太さなど、伸縮させたくないもの
remルート要素の文字サイズ文字サイズ・余白の全体的な基準
emその要素自身の文字サイズボタン内の余白など、文字に比例させたいもの
%親要素のサイズ幅を親に追従させたいとき
vw / vhビューポートの幅・高さ画面いっぱいに広げたい領域

迷ったら、文字サイズと余白は rem、幅は % から始めると崩れにくくなります。文字サイズを px で固定すると、ブラウザの既定文字サイズを大きく設定している利用者の意図が反映されなくなる点にも注意が必要です。

カスタムプロパティでまとめる

-- で始まるカスタムプロパティは、CSS標準の変数です。

:root {
  --brand: #0d9488;
  --space: 8px;
}

.button {
  background: var(--brand);
  padding: var(--space) calc(var(--space) * 2);
}

:root に定義すれば文書全体で使え、1か所を変えるだけで配色や余白のスケールをまとめて入れ替えられます。重要なのは継承することです。.dark { --brand: #5eead4; } のように途中の要素で再定義すると、その配下だけ値が差し替わります。ダークテーマの切り替えがこれだけで書けるのは、ビルド時に値が確定してしまうプリプロセッサの変数にはない性質です。

次に読むCSSの地図

CSSは範囲が広く、どこから手をつけるか迷いやすい領域です。目的別に3つの方向で整理します。

レイアウトを組む

画面の骨格を作る段階です。まず [[FlexboxとGrid]] で「一列に並べる」と「格子に配置する」という2つの道具を押さえ、続いて [[レスポンシブデザイン]] で画面幅に応じた切り替え方を学ぶと、座標を手で合わせるやり方から抜け出せます。

書き方を選ぶ

CSSが増えると、記述量とクラス名の管理が課題になります。[[CSSプリプロセッサ(Sass)]] は変数やネストで整理する方向、[[Tailwind CSS]] はそもそもCSSファイルを書かずクラスの組み合わせで済ませる方向です。どちらも最終的には素のCSSに変換されるため、この記事の内容がそのまま土台になります。

見え方の質を上げる

書いたスタイルが「速く」「誰にでも」届くかを見る段階です。[[ブラウザレンダリングの仕組み]] を知ると、どのプロパティを変えると描画がやり直しになるかが判断でき、アニメーションで使うプロパティの選び方が変わります。[[Webアクセシビリティ]] は、コントラスト比やフォーカス表示といった、CSSの指定がそのまま「使えるかどうか」を左右する部分を扱います。

関連技術とのつながり

  • [[HTML]] — CSSがスタイルを当てる対象
  • [[Tailwind CSS]] — CSSをユーティリティクラスとして提供するフレームワーク
  • [[JavaScript]] — クラスの付け替えなどでCSSと連携して動きを作る
  • [[FlexboxとGrid]] / [[レスポンシブデザイン]] — レイアウトを担うCSSの中核機能
  • [[ブラウザレンダリングの仕組み]] — 書いたCSSが画面になるまでの流れ
Q: 同じ要素に当たる `#sidebar p { color: gray; }` と、その後に書いた `.note { color: red; }` では、どちらの色が適用される?
- [x] gray(id を含むセレクタのほうが詳細度が高いため)
- [ ] red(後に書かれた宣言が常に勝つため)
- [ ] どちらも適用されず既定の色になる
解説: 記述順で決まるのは詳細度が同点のときだけです。id を含むセレクタはクラスや要素より詳細度が高く、後から書いたクラスの宣言では上書きできません。

Q: `box-sizing: border-box` を指定すると何が変わる?
- [ ] padding と border が要素の外側に加算されるようになる
- [x] width に padding と border を含めて計算されるようになる
- [ ] margin も width に含まれるようになる
解説: 既定の content-box では width が content の幅だけを指すため padding が外側に加算されますが、border-box では padding と border を含んだ値が width になります。

Q: CSSカスタムプロパティがプリプロセッサの変数と違う点として本文で挙げられているのはどれ?
- [ ] ブラウザに読み込まれる前にビルドで値が確定する
- [x] 継承するため、途中の要素で再定義すると配下だけ値が差し替わる
- [ ] 色の値しか入れられない
解説: カスタムプロパティは継承するので、`.dark { --brand: ...; }` のように途中で再定義すればその配下だけ値が変わります。ビルド時に確定するプリプロセッサの変数にはない性質です。