iT邦幫忙

2024 iThome 鐵人賽

DAY 6
0

概念

<html>
  <body>
    <article>
      This article has<p>paragraph</p>in it.
    </article>
  </body>
</html>

根元素(<html>) 因為是文件中的第一個元素,所以不會做任何屬性的繼承(inherit)

如果接著替 html 元素增加 CSS 樣式

html {
  color: red;
}

其他元素預設會去繼承 color 這個屬性值,因此所有元素顏色都會變為 red

接著在 body 上設定字體大小

body {
  font-size: 30px;
}

body 底下的 article 和 p 會去繼承 font-size 的值,所以即使在 p 身上沒有寫任何樣式規則,"paragraph" 這段文字的 color 和 font-size 會去繼承父元素的值,最後顏色為紅色且字體大小為 30px。

但如果在 article 上設定 border

article {
    border: 1px solid #cdcdcd;
}

p 元素上看不見 border,也就是 p 並沒有繼承寫在 article 身上的 border-style 值。

因為 CSS 的屬性有分成 inheritednon-inherited 這兩類:

  • inherited 會以父元素的 computed value 作為預設值
  • non-inherited 會是以這個屬性的初始值為預設值
    • 例如:border-style 屬於為 non-inherited,而 border-style 的初始值為 none,所以 p 元素上的 border-style 會是 initial 也就是 none

如果改成

article {
  color: red;
  border: 1px solid #cdcd;
}

p {
  border-style: solid
}

p 元素會是有框線的,且寬度為 medium 的紅實線!

拆解 border: 1px solid #cdcd; 是 border-width、border-style 以及 border-color 的縮寫,而這三個屬性都屬於 non-inherited,所以會去找屬性的初始值作為預設。border-width 的初始值為 medium、border-style 初始值為 none、border-color 初始值為 currentcolor (指的是當前標籤所繼承的文字顏色)

也就可以想像成

p {
  border-width:initial --> medium;
  border-style: solid;
  border-color: initial --> red
}

*順序是下層的元素去繼承上層元素
*不是所有的屬性都會繼承
*MDN 有把每個屬性是否會繼承、初始值又是什麽寫在 Formal definition 這個區塊,例如:MDN Web Docs - border-width

常使用的屬性中:

  • 會繼承的屬性
    • font 相關 (例如:font-size、font-family ...)
    • color
  • 不會繼承的屬性
    • width/ height
    • border
    • margin/ padding

如何有效控制繼承?

為了避免 "繼承"這個特性,讓元素產生預期外的樣式,有幾種方式:

1. inherit

任何屬性值都可以使用 inherit 這個關鍵字,代表要繼承父元素的值,可以使用在inheritednon-inherited 這兩類屬性,也就是強迫屬性做繼承,例如:

如果同一段 HTML,想要讓裡面的 p 也具有跟 article 一樣的框線樣式

<html>
  <body>
    <article>
      This article has<p>paragraph</p>in it.
    </article>
  </body>
</html>
article {
  color: red;
  border: 1px solid #cdcd;
}

p {
  /* border 的 width, style, color 通通繼承 */
  border: inherit;
}

initial

initial 可以用來 reset 屬性值回到預設,例如:

讓 p 元素的顏色回到瀏覽器預設,而不要繼承 article

article {
  color: red;
  border: 1px solid #cdcd;
}

p {
  color: initial;
}

*對於 inherited 類型的屬性,使用 initial 容易會有非預期的樣式,因為我們通常不會去記得瀏覽器的預設值為何

unset

如果是 inherited 屬性,設定 unset 的效果和 inherit 一樣,去找父元素繼承。
如果是 non-inherited 屬性,設定 unset 的效果則會和 initial 一樣,會去找預設值。

例如:

<p>This text is red.</p>
<div class="foo">
  <p>This text is also red.</p>
</div>
<div class="bar">
  <p>This text is green (default inherited value).</p>
</div>
.foo {
  color: blue;
}

.bar {
  color: green;
}

p {
  color: red;
}

/* color 為 inherited 屬性,unset 代表會去找父層的 bar 去繼承顏色,也就是 green */
.bar p {
  color: unset;
}

例如:

<p>This text has a red border.</p>
<div>
  <p>This text has a red border.</p>
</div>
<div class="bar">
  <p>This text has a black border (initial default, not inherited).</p>
</div>
div {
  border: 1px solid green;
}

p {
  border: 1px solid red;
}

/* border 為 non-inherited 屬性,unset 代表會去找瀏覽器預設值,等同於 initial */
.bar p {
  border-color: unset;
}

參考資源

MDN Web Docs - Inheritance


上一篇
Specificity
下一篇
Color
系列文
一個人的朝聖:重啟對 CSS 的認識14
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言