ヨルフの日記

ヨルフといいます.知ったこと,体験したこと,考えたことなどを発信していきます.英語勉強中.Amazon.co.jpアソシエイト

【HTML&CSS】継承が行われない?→原因はデフォルトスタイルシートでした

最近、ProgateでHTML&CSSの学習をしており、「継承」に関して少しつまったことがありました。
その現象および原因について説明することで、同じようなことでつまっている方の参考になればと思います。

現象

まずは現象の説明を行います。
以下にHTML文書とそのスタイルシートChromeでの表示結果を示します。

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>test</title>
    <link rel="stylesheet" href="stylesheet.css">
  </head>
  <body>

    <div class="hoge0">
      <h1>ABC</h1>
    </div>

    <div class="hoge1">
      <h1>ABC</h1>
    </div>

    <div class="hoge2">
      <h1>ABC</h1>
    </div>

    <div class="hoge3">
      <h1>ABC</h1>
    </div>

  </body>
</html>

stylesheet.css

.hoge0 {
}

.hoge1 {
  font-weight: normal;
}

.hoge2 h1{
  font-weight: normal;
}

.hoge3 {
  color: red;
}

Chromeでの表示結果(①などの番号は便宜上つけたものでブラウザでは表示されません)
f:id:yoruhu:20200123202809p:plain

上記では4つの書き方で文字列「ABC」の表示方法を規定しています。

①はスタイルシートで何も指定していない状態
②は親要素のfont-weightの値を設定
③はhoge2に含まれるh1のfont-weightの値を設定
④は親要素のcolorの値を設定

まずは以下の2点に注目してください。

  • ①と②の表示に差がない
  • ②と③では表示に差がある(③の方が細い)

実は②では「ABC」に対して「font-weight: normal;」の指定が効いていないのです。そのため、①と②の表示が同じになります。

一方、③では「font-weight: normal;」が効いており、①,②に比べて「ABC」の文字が細くなっています。

僕としては、②の形で書けば、親要素から子要素にスタイルが継承されて、③と同じになると思っていたので「あれ?」という感じになりました。

そこで試しに④のような書き方をしてみると、文字の色についてはきちんと反映されています。つまり、親要素から子要素へスタイルが継承されています。

ここまでのことから以下の疑問が生まれました。

疑問1:なぜ②ではスタイルが継承されないのか?
疑問2:②と④の違いは何か?

以下では調べた情報をもとに段階を追ってこれらの疑問に答えます。

デフォルトスタイルシート

ブラウザによってあらかじめ設定されているスタイルが存在します。これをデフォルトスタイルシートと言います。下記ページによれば、Chromeではh1要素については、font-weightがboldに設定されているようです。

「各ブラウザごとのデフォルトのスタイルシート、user agent stylesheetのまとめ -Chrome, Safari, Firefox, Edge」
https://coliss.com/articles/build-websites/operation/css/user-agent-stylesheets.html


継承のルール

親要素に対して設定されたスタイルが子要素にも反映されることを「継承」と言いますが、どんな場合でも、どんなスタイルでも継承されるわけではなく、条件があります。そんな条件の一つが「子要素に対して同じプロパティの宣言がある場合、親要素の値は継承されない」というルールです。

疑問の解決

疑問1:なぜ②ではスタイルが継承されないのか?
→「デフォルトスタイルシート」の項目で触れた通り、h1要素にはデフォルトスタイルシートにより、font-weight: bold;という宣言があります。そのため、上述の「子要素に対して同じプロパティの宣言がある場合、親要素の値は継承されない」ルールにより親要素の値が継承されません。

疑問2:②と④の違いは何か?
→デフォルトスタイルシートではh1要素に対してcolorの値の宣言がありません。そのため、②の場合とは異なり、親要素の値が子要素に継承され、文字色が赤になっています。

補足:この場合、「優先順位」は関係ない

スタイル指定の優先順位として、「製作者スタイルシート(今回ならstylesheet.css)による指定」は「デフォルトスタイルシートによる指定」より優先されます。しかし、それは「指定が行われれば」の話であり、継承自体が行われない(すなわち、指定が行われない)②のケースには当てはまりません。

逆に③では「製作者スタイルシートによる指定」がなされているため、その値が「デフォルトスタイルシートによる指定」より優先されています。

まとめ
  • デフォルトスタイルシートによるスタイルの指定があることで、継承が行われない場合がある

なお、デフォルトスタイルシートが邪魔な場合は、「リセットCSS」を使えばいいみたいです。