こんにちは!フロントエンドの現場を長年歩んできた者です。
Webサイトを作っていて、「あれ?なんでこのCSS、効かないんだろう……?」と頭を抱えた経験、ありませんか? 狙ったデザインにならないとき、私たちはついつい「CSSの書き方が悪いのかな」とコードばかりを疑ってしまいがちです。
でも、ちょっと待ってください。ブラウザがあなたの書いたHTMLやCSSを、画面に表示される美しいデザインに仕立て上げるまでには、裏側でドラマチックな大冒険が繰り広げられているんです。
今回は、その冒険の核心である「CSSOMツリーの構築とスタイル解決」について、難しい専門用語のジャングルを抜け出して、身近な例え話と一緒に楽しく紐解いていきましょう。大丈夫、一歩ずつ見ていけば絶対に怖くありませんよ!
—
1. ブラウザの頭の中:CSSOMってなに?
私たちが普段書いているCSSファイルは、ブラウザから見ると、ただの「英語がずらっと並んだ長文のテキスト」に過ぎません。これをそのままでは、画面のピクセルをどうこうすることはできないんです。
ブラウザは、このテキストを読み込んで、「誰に・どんなスタイルを適用すべきか」を整理整頓した「家系図」のようなものに作り替えます。これが、CSSOM(CSS Object Model / CSSオブジェクトモデル)です。
身近なたとえ:洋服の「コーディネート指示書」
ここで少し、お買い物の流れを想像してみてください。
あなたは今日、お出かけするための「トータルコーディネート(見た目)」を決めたいとします。
- 「帽子は赤色で、形はベレー帽にする」
- 「上着はデニムジャケットにする。ただし、Mサイズ以上の子だけね」
- 「靴はスニーカーで、すべてのアイテムの底に滑り止めをつける」
こんな風に、アイテムごとに「どういう見た目にするか」のルールがノートに箇条書きで書かれていますよね。ブラウザにとってのCSSファイルが、まさにこのノートです。そして、そのノートのルールを、実際の服(HTML要素)の形に合わせて綺麗に整理したファイリングデータがCSSOMツリーというわけです。
—
2. CSSOMが作られるとき、ブラウザで何が起きているのか?
ブラウザがHTMLを読み込み始めると同時に、CSSの読み込みも始まります。ここで知っておいてほしい、ブラウザのちょっとした「こだわり」があります。
それは、「CSSOMが完成するまで、画面の描画(レンダリング)をちょっと待つ」ということです。
なぜ待つかというと、もしCSSOMがないまま適当に画面を表示してしまうと、最初は素っ気ない文字だけの画面が表示され、CSSの読み込みが終わった瞬間に突然ページ全体がド派手にデザインされ直すという、目がチカチカする現象(FOUCと呼ばれるものです)が起きてしまうから。ブラウザは、私たちユーザーに綺麗な画面を最初から届けるために、裏で必死にCSSをパース(解析)してツリーを作っているんです。
スタイル解決の3大ルール:カスケード、継承、詳細度
CSSOMが組み上がり、HTMLの骨組みである「DOMツリー」と合体する瞬間、ブラウザの頭の中では「どの要素に、どのスタイルを最終的に採用するか」を決める会議が始まります。これをスタイル解決と呼びます。
この会議で使われるのが、有名な以下の3つのルールです。難しく考えず、優しく見ていきましょう。
1. カスケード(優先順位の流儀)
- 上から下へ水が流れるように、複数のルールがぶつかったときに「どれを一番優先するか」を決める仕組みです。ブラウザ標準のスタイル、ユーザーの設定、そして私たちが書いたCSS……と、いくつかの層(Cascade)を重ね合わせて決定します。
2. 継承(親から子へ受け継がれる想い)
- 例えば、お父さんやお母さんの遺伝で髪や目の色が似るように、HTMLでも「親要素」に指定したスタイル(文字の色やフォントの種類など)が、中の「子要素」にポコポコと引き継がれる仕組みです。全部のスタイルが引き継がれるわけではないのが、また人間味があって面白いところですね。
3. 詳細度(セレクタの強さ、本気度)
- 「すべてのpタグに適用するスタイル(ふんわりしたお願い)」よりも、「#mainにある特定のclassに適用するスタイル(名指しのガチなお願い)」の方が、ブラウザは「こっちの方が本気度が高いな!」と判断して優先します。この「名指しの強さ」をスコア化したものが詳細度です。
—
3. 実践!ブラウザの気持ちになってコードを眺めてみよう
百聞は一見にしかず。実際に私たちが書くコードが、ブラウザでどう解釈されるのかを見てみましょう。
以下のコードを、あなたのエディタの片隅に置いてみてください。
普通のカード
ここは親(body)から文字色が継承され、cardクラスのスタイルが適用されます。
特別なカード
ここは `#unique-card.card` という強い詳細度のおかげで、背景色が水色に上書きされます!
このコードでブラウザがやっていること
1. DOMとCSSOMの構築: ブラウザはHTMLのタグを上から順に読み込んでDOMツリーを作りつつ、`