CSS Podcast - 005:繼承
假設您剛剛寫了一些 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
- color
- cursor
- 方向
- empty-cells
- font-family
- font-size
- font-style
- font-variant
- font-weight
- font
- letter-spacing
- line-height
- list-style-image
- list-style-position
- list-style-type
- list-style
- 孤兒
- 引文
- text-align
- text-indent
- text-transform
- 能見度
- 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
設為 900
,而非預設的 bold
值 (相當於 font-weight: 700
)。
.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>
元素現在會有 500
的 font-weight
。
您可以明確設定這個值,但如果您使用 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
則會還原為繼承的計算值。
您也可以將 unset
值與 all
屬性一起使用。回到上述範例,如果全域 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;
}
進行隨堂測驗
測驗您對繼承的瞭解
根據預設,系統會繼承下列哪些屬性?
animation
font-size
color
text-align
line-height
在沒有任何可繼承的值時,哪個值會像 inherit
一樣運作,然後像 initial
一樣運作?
reset
unset
superset