一、概述
一個元素最終只有一個css屬性對其生效,除了多處指定屬性這種情況,還有一種就是元素會繼承祖元素的屬性,這是一個不簡單,也不復雜的問題。
二、繼承
一個元素如果本身沒有被指定css屬性,那么它就會繼承父元素的屬性,繼承是鏈式的,元素會向上查找,直到遇到指定樣式的祖元素,並且繼承它的屬性:
<style> body{ font-family: cursive; } div{ font-family: monospace; } </style> </head> <body> <p>p</p> <div>div</div> <div><span>div->span <font>div->span->font</font></span></div> </body>
- 元素『p』沒有指定font-family屬性,往上遍歷繼承了『body』的font-family屬性;
- 元素『div』指定了自己的font-family屬性,沒有再往上遍歷;
- 元素『span』沒有指定font-family屬性,往上遍歷繼承了『div』的font-family屬性;
- 元素『font』沒有自己的font-family屬性,往上遍歷『span』也沒有自己的樣式,於是繼續遍歷,最終繼承了『div』的font-family屬性;
1.通過元素名稱來指定的屬性會被其本身和本身的子元素繼承:
body { font-family: cursive; }
通過指定『body』元素的樣式,所有屬於『body』的后代元素都會繼承這個樣式(一些老舊版本瀏覽器除外)
2.單獨指定元素屬性可以擺脫繼承:
<style> body{ font-family: unset; } div{ font-family: serif; } </style> <body> <div>div</div> </body>
現在『div』擁有了自己的font-family屬性,不再繼承『body』的font-family屬性
3.多重路徑指定
先來看看一段聲明:
<style> div span font{ font-family: unset; } body div font{ font-family: serif; } span font{ font-family: serif; } font{ font-family: fantasy; } </style> <body> <div><span>div->span<font>div->span->font</font></span></div> </body>
以上所有聲明都指向了『font』元素的情況下,究竟最終會是哪個生效?
通常選擇器的優先級遵循以下規則:
- 更詳細的選擇器優先級更高,所以無論是『body font』還是『span font』都比『font』的優先級更高,同理『body div font』比『span font』優先級更高;
- 同詳細的選擇器,最后的一個聲明會覆蓋上面的聲明,如同上述例子中,『div span font』與『body div font』中,后者的優先級是最高的,它覆蓋了前者;
三、選擇器的優先級
css中有3種元素選擇器,2種元素指明后綴,如果聲明被重疊,那么優先級更高的選擇器會覆蓋優先級別更低的聲明,這也是影響元素樣式繼承的一個因素;
類型 | 優先級(數字越大優先級越高) | 示例 |
派生選擇器 | 1 | div{...} ul li{...} h1 > strong {...} li + li {...} |
類選擇器 | 2 | .foo{...} |
類指明后綴 | 2 | div.foo{...} |
屬性指明后綴 | 2 | div[title="1"]{...} |
id選擇器 | 3 | #bar{...} |
1.元素選擇器
舉個例子:
<style> .c-2 .c-3{ font-family: serif; } span .c-3{ font-family: serif; } </style> </head> <body> <div class="c-1"><span class="c-2">div->span <font class="c-3">div->span->font</font></span></div> </body>
示例中,盡管『span .c-3』的路徑跟『.c-2 .c-3』一樣詳細並且在『.c-2 .c-3』的下面,但是由於類選擇器的優先級比派生選擇器的優先級更高,所以『.c-2 .c-3』是最終生效的樣式。
同理,如果給示例增加『.c-1 .c-2 .c-3』和『.c-1 span .c-3』兩個聲明,最終生效的也只會是『.c-1 .c-2 .c-3』。
2.元素指明后綴
給一個選擇器加上一個指明后綴,的繼承優先級,等價這個選擇器后面接一個類選擇器:
<style> font[title="1"]{ font-family: serif; } span font{ font-family: serif; } </style> <body> <div title="1" class="c-1" id="i_1"><span class="c-2">div->span<font class="c-3 c-3-1" id="i_1" title="1">div->span->font</font></span></div> </body>
所以上述例子『font[title="1"]』的優先級是比『span font』要高的;
根據以上規則,同路徑長度同級的聲明,后面的聲明會覆蓋前面的聲明:
<style> .c-2 .c-3{ font-family: serif; } .c-3[title="1"]{ font-family: serif; }
.c-3.c-3-1{
font-family: serif;
} </style> <body> <div title="1" class="c-1" id="i_1"><span class="c-2">div->span<font class="c-3 c-3-1" id="i_1" title="1">div->span->font</font></span></div> </body>
示例中『.c-2 .c-3』和『.c-3[title="1"]』和『.c-3.c-3-1』是等價的,所以最終生效取決於誰聲明在最后,這里是『.c-3.c-3-1』;