The CSS Podcast - 005: Inheritance
要素をボタンのように見せる CSS を作成したとします。
<a href="http://example.com" class="my-button">I am a button link</a>
.my-button {
display: inline-block;
padding: 1rem 2rem;
text-decoration: none;
background: pink;
font: inherit;
text-align: center;
}
次に、class
の値が .my-button
のリンク要素をコンテンツの記事に追加します。しかし、テキストの色が期待どおりになっていないという問題があります。どうしてそうなったのでしょうか?
一部の CSS プロパティは、値を指定しないと継承されます。このボタンの場合、この CSS から color
を継承しています。
article a {
color: maroon;
}
このレッスンでは、その理由と、継承が CSS の記述量を減らすのに役立つ強力な機能である理由について学びます。
継承フロー
次の HTML スニペットを使用して、継承の仕組みを見てみましょう。
<html>
<body>
<article>
<p>Lorem ipsum dolor sit amet.</p>
</article>
</body>
</html>
ルート要素(<html>
)はドキュメント内の最初の要素であるため、何も継承しません。HTML 要素に CSS を追加すると、ドキュメントにカスケードされます。
html {
color: lightslategray;
}
color
プロパティは、デフォルトで他の要素に継承されます。html
要素に color: lightslategray
があるため、色を継承できるすべての要素の色が lightslategray
になります。
body {
font-size: 1.2em;
}
p {
font-style: italic;
}
最も深くネストされた要素である <p>
のみが斜体になります。継承は下方向にのみ流れ、親要素には戻りません。
デフォルトで継承されるプロパティ
すべての CSS プロパティがデフォルトで継承されるわけではありませんが、継承されるプロパティはたくさんあります。参考までに、すべての CSS プロパティの W3 リファレンスから取得した、デフォルトで継承されるプロパティの完全なリストを次に示します。
- azimuth
- border-collapse
- border-spacing
- caption-side
- 色
- cursor
- direction
- empty-cells
- font-family
- font-size
- font-style
- font-variant
- font-weight
- フォント
- letter-spacing
- line-height
- list-style-image
- list-style-position
- list-style-type
- list-style
- orphans
- 引用符
- text-align
- text-indent
- text-transform
- visibility
- white-space
- widows
- word-spacing
継承の仕組み
すべての HTML 要素には、デフォルトで初期値が設定されたすべての CSS プロパティがあります。初期値は継承されないプロパティで、カスケードでその要素の値を計算できない場合にデフォルトとして表示されます。
継承可能なプロパティは下方向にカスケードされ、子要素は親の値を表す計算値を取得します。つまり、親の font-weight
が bold
に設定されている場合、すべての子要素は太字になります。ただし、子要素の font-weight
が別の値に設定されている場合や、ユーザー エージェントのスタイルシートにその要素の font-weight
の値が設定されている場合は除きます。
継承を明示的に行い、継承を制御する方法
継承は要素に予期しない影響を与える可能性があるため、CSS にはそれを防ぐためのツールが用意されています。
inherit
キーワード
inherit
キーワードを使用すると、任意のプロパティで親の計算値を継承できます。このキーワードの便利な使い方は、例外を作成することです。
strong {
font-weight: 900;
}
この CSS スニペットは、すべての <strong>
要素の font-weight
を、デフォルトの bold
値(font-weight: 700
と同等)ではなく 900
に設定します。
.my-component {
font-weight: 500;
}
.my-component
クラスは、代わりに font-weight
を 500
に設定します。.my-component
内の <strong>
要素も font-weight: 500
にするには、次のように追加します。
.my-component strong {
font-weight: inherit;
}
これで、.my-component
内の <strong>
要素の font-weight
は 500
になります。
この値を明示的に設定することもできますが、inherit
を使用し、.my-component
の CSS が将来変更された場合、<strong>
は自動的に最新の状態に保たれます。
initial
キーワード
継承は要素に問題を引き起こす可能性があるため、initial
には強力なリセット オプションが用意されています。
CSS では、すべてのプロパティにデフォルト値があることを学習しました。initial
キーワードは、プロパティを初期のデフォルト値に戻します。
aside strong {
font-weight: initial;
}
このスニペットは、<aside>
要素内のすべての <strong>
要素から太字の重みを削除し、代わりに初期値である通常の重みにします。
unset
キーワード
プロパティがデフォルトで継承されるかどうかによって、unset
プロパティの動作が異なります。プロパティがデフォルトで継承される場合、unset
キーワードは inherit
と同じになります。プロパティがデフォルトで継承されない場合、unset
キーワードは initial
と等しくなります。
どの CSS プロパティがデフォルトで継承されるかを覚えるのは難しい場合があります。そのような場合に unset
が役立ちます。たとえば、color
はデフォルトで継承されますが、margin
は継承されないため、次のように記述できます。
/* Global color styles for paragraph in authored CSS */
p {
margin-top: 2em;
color: goldenrod;
}
/* The p needs to be reset in asides, so you can use unset */
aside p {
margin: unset;
color: unset;
}
margin
が削除され、color
が継承された計算値に戻ります。
all
プロパティで unset
値を使用することもできます。前の例に戻ると、グローバル p
スタイルにいくつかのプロパティが追加された場合はどうなるでしょうか?margin
と color
に設定されたルールのみが適用されます。
/* Global color styles for paragraph in authored CSS */
p {
margin-top: 2em;
color: goldenrod;
padding: 2em;
border: 1px solid;
}
/* Not all properties are accounted for anymore */
aside p {
margin: unset;
color: unset;
}
aside p
ルールを all: unset
に変更すると、今後 p
に適用されるグローバル スタイルに関係なく、常に設定が解除されます。
aside p {
margin: unset;
color: unset;
all: unset;
}
revert
キーワード
カスケードのレッスンで学習したように、スタイルはさまざまなオリジン(ユーザー エージェントの基本スタイル、ユーザー設定のスタイル、作成者のスタイル)から取得されます。revert
キーワードは、revert
キーワードが使用されている同じオリジンで設定されたスタイルを元に戻します。
これは、スタイルを設定したものの、一部のインスタンスには適用したくない場合に便利です。inherit
、initial
、unset
はスタイルの値を計算する方法を指定しますが、revert
は記述した他のスタイルを適用しないことのみを指定します。
p {
padding: 2em;
}
aside p {
padding: revert;
}
このスニペットでは、<p>
要素にパディングが設定されますが、<p>
要素が <aside>
内にある場合は、padding
がまったく指定されません。代わりに、ユーザー設定のスタイル(設定されている場合)またはユーザー エージェントの基本スタイルに戻ります。
revert-layer
キーワード
カスケード レイヤは、スタイルを整理し、カスケードの作成者オリジン内でスタイルの優先順位を設定するのに役立ちます。revert-layer
キーワードは revert
と似ていますが、プロパティに作成者スタイルを適用しないことを指定するのではなく、現在のレイヤのスタイルのみを元に戻します。
サードパーティの UI ライブラリを使用している場合、便利なパターンは、ライブラリをレイヤにインポートし、オーバーライドを優先度の高いレイヤに追加することです。その後、revert-layer
を使用してオーバーライドを削除すると、代わりに UI ライブラリのデフォルトが使用されます。
他のレイヤでプロパティの値が指定されていない場合、revert
のように動作し、以前のオリジンの値を使用します。
理解度を確認する
継承に関する知識をテストする
次のプロパティのうち、デフォルトで継承されるものはどれですか?
text-align
color
line-height
animation
font-size
継承するものがなければ inherit
のように動作し、その後 initial
のように動作する値はどれですか?
unset
reset
superset