前言
最近在读《深入解析CSS》。
读到第2章的时候发现自己对于选择器优先级的概念和继承的概念混为一谈了。
借用第2章“自定义属性”的例子,利用自定义属性为两块面板设置不同的颜色。我的困惑出现在给第二个面板设置不同字体颜色和背景颜色后,第二个面板原来的字体颜色和背景颜色都被新颜色覆盖。
当时的想法是::root
是伪类选择器,优先级相当于类,.dark
是类选择器,二者优先级相等,然后考虑代码顺序,但将:root
声明块移至.dark
下面,发现效果还是和之前一样。为了进一步明确我的困惑,在外层又加了一个id="test"
的div元素,定义了自定义属性,设置不同的颜色,此时#test
的优先级高于.dark
,总该会出现#test
的效果了吧,结果却还是和之前一样。
上面的”折腾“忽略了一个重要的前提:上述的选择器并非直接作用于同一个元素。因此考虑它们的优先级是毫无意义的。
HTML部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <body> <div id="test"> <div class="panel"> <h2>Single-origin</h2> <div class="body"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Aperiam cumque deserunt omnis sed autem molestias et reprehenderit voluptatum odit voluptas fugiat reiciendis, corrupti nihil maiores. Pariatur laboriosam doloribus aspernatur. Accusamus! </div> </div>
<aside class="dark"> <div class="panel"> <h2>Single-origin</h2> <div class="body"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Aspernatur sunt perspiciatis fugit. Fuga nostrum ea error, autem officiis dolores tenetur necessitatibus doloribus mollitia qui veritatis cumque, saepe impedit inventore ab? </div> </div> </aside> </div> </body>
|
CSS部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| :root { --main-bg: #fff; --main-color: #000; }
#test { --main-bg: #365; --main-color: #000; }
.panel { font-size: 1rem; padding: 1em; border: 1px solid #999; border-radius: .5em; background-color: var(--main-bg); color: var(--main-color); }
.panel > h2 { margin-top: 0; font-size: .8em; font-weight: bold; text-transform: uppercase; }
.dark { margin-top: 2em; padding: 1em; background-color: #999; --main-bg: #333; --main-color: #fff; }
|
总结
选择器优先级和继承,最终出现的效果可能都会导致原来的样式变化,但两者是不同的概念。
选择器优先级本质上是用来解决声明冲突的规则。因此在考虑选择器优先级的时候,首先看这两个选择器是否都(至少)作用于同一个元素,因为只有作用于同一个元素才有可能发生声明冲突,如果作用于同一个元素,那么就根据优先级规则预测元素的效果;
而继承本质上是添加样式的一种方式,与选择器的优先级和声明块的顺序没有直接关系。如果一个元素的某个属性(可继承的属性)没有层叠值,则会继承父元素的值,将属性加到body上会在整个网页上生效,而将属性加到特定元素上,则只会被它的后代元素继承,并且继承属性会顺序传递给后代元素,直到它被层叠值覆盖。