CSS 繼承:哪些屬性會傳給子元素
繼承(Inheritance)是指子元素自動沿用父元素的某些屬性值,不必逐層重寫。它讓我們可以在一個地方設好文字樣式,整份文件就跟著套用。判斷的原則很單純:文字相關的屬性多半會繼承,版面相關的則不會,因為前者影響的是內容怎麼呈現,後者一旦往下複製,版面會整個亂掉。
body {
color: #333;
font-family: "Noto Sans TC", sans-serif;
line-height: 1.7;
}會繼承與不會繼承
| 會繼承 | 不會繼承 |
|---|---|
color | margin、padding |
font-family、font-size、font-weight、font-style | border、background |
line-height、letter-spacing、word-spacing | width、height |
text-align、text-indent、text-transform | display、position、float |
list-style、white-space、visibility、cursor | overflow、box-shadow、z-index |
一句話判斷
把這個屬性複製給每一個子元素,版面會不會壞掉?會壞的就不繼承。
自訂屬性(CSS 變數)也會繼承,這正是它適合拿來做主題切換的原因:在 :root 換一次值,整份文件都跟著變。
有些元素不吃繼承
繼承只在「元素自己沒有值」的時候才看得出效果。瀏覽器的 預設樣式表 已經替某些元素指定了顏色與字型,這些值屬於元素本身,優先於繼承而來的值:
| 元素 | 情況 |
|---|---|
| 超連結 | 有自己的預設顏色,不會跟著父層的 color 改變。 |
| 表單欄位、按鈕 | 有自己的預設字型與字級,不會跟著內文。 |
| 文字區域、下拉選單 | 同上,字型需要自己指定。 |
所以現代的 樣式重置 幾乎都會補上這一段:
input,
button,
select,
textarea {
font: inherit;
color: inherit;
}用關鍵字手動控制
任何屬性都可以用這四個關鍵字明確指定「要不要繼承」:
| 關鍵字 | 說明 |
|---|---|
inherit | 強制沿用父層的計算值,不可繼承的屬性也能這樣用。 |
initial | 還原成該屬性在規範中的初始值,與瀏覽器預設樣式無關。 |
unset | 可繼承的比照 inherit、不可繼承的比照 initial。 |
revert | 還原成瀏覽器預設樣式表的值。 |
/* 讓區塊容器的框線跟著父層,border 本來是不繼承的 */
.child {
border: inherit;
}
/* 清掉先前套用的樣式,回到規範的初始值 */
.reset-color {
color: initial;
}initial 不等於「原本的樣子」
initial 回到的是 規範定義的初始值,不是瀏覽器預設樣式。例如 display 的初始值是 inline,所以對 <div> 寫 display: initial 會讓它變成行內元素,而不是回到 block。想回到瀏覽器預設請用 revert。
繼承沒有權重
這是最容易搞混的一點:繼承而來的值 不參與 優先權 的計分。只要元素自己有任何一條宣告,就會蓋掉從父層繼承來的值,即使那條宣告的權重極低:
/* 權重很高,但只作用在 .article 自己身上 */
#main .article { color: red; }
/* 權重很低,卻贏了,因為 p 自己有值,紅色只是繼承來的 */
p { color: black; }換句話說,繼承是「沒人設定時的預設來源」,一旦有人開口,它就退場。
行高的單位會影響繼承結果
line-height 寫成不帶單位的倍數與帶單位的長度,繼承下去的東西不一樣:
/* ✅ 子元素依自己的字級換算 */
body { line-height: 1.7; }
/* ❌ 子元素繼承到固定的 27.2px,字級變大就會擠 */
body { line-height: 1.7rem; }不帶單位時,子元素繼承的是 比例;帶單位時,繼承的是 算好的長度。內文的行高建議一律寫成倍數,詳見 文字與字體。
常見問題
哪些屬性會被子元素繼承?
文字相關的屬性多半會,例如:顏色、字級、字型、行高、對齊方式;版面相關的則不會,例如:外距、內距、框線、背景與寬高。判斷的方式很簡單:如果這個屬性往下複製會讓版面亂掉,它就不會繼承。
為什麼表單欄位的字型跟內文不一樣?
因為瀏覽器的 預設樣式表 已經替表單元素指定了字型,元素本身有值就不會用繼承來的值。標準做法是在樣式重置裡替表單元素寫上 font: inherit,讓它跟著內文。
inherit、initial 與 unset 差在哪?
inherit 強制沿用父層的計算值;initial 還原成該屬性在規範中的初始值;unset 則看屬性本身,可繼承的比照 inherit、不可繼承的比照 initial。
繼承來的值權重是多少?
沒有權重。繼承不參與 優先權 的計分,只要元素自己有任何一條宣告,就會蓋掉從父層繼承來的值,即使那條宣告的權重很低。