一、概述
一个元素最终只有一个样式对其生效,除了多处指定样式这种情况,还有一种就是元素会继承祖元素的样式,这是一个不简单,也不复杂的问题。
二、继承
一个元素如果本身没有被指定样式,那么它就会继承父元素的样式,继承是链式的,元素会向上查找,直到遇到指定样式的祖元素,并且继承它的样式:
<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』没有指定样式,往上遍历继承了『body』的样式;
- 元素『div』指定了自己的样式,没有再往上遍历;
- 元素『span』没有指定样式,往上遍历继承了『div』的样式;
- 元素『font』没有自己的样式,往上遍历『span』也没有自己的样式,于是继续遍历,最终继承了『div』的样式;
1.通过元素名称来指定的样式会被其本身和本身的子元素继承:
body { font-family: cursive; }
通过指定『body』元素的样式,所有属于『body』的后代元素都会继承这个样式(一些老旧版本浏览器除外)
2.单独指定元素属性可以摆脱继承:
<style> body{ font-family: unset; } div{ font-family: serif; } </style> <body> <div>div</div> </body>
现在『div』拥有了自己的样式,不再继承『body』的样式
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 |
类选择器 | 2 |
类指明后缀 | 2 |
属性指明后缀 | 2 |
id选择器 | 3 |
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』;