CSS基础笔记系列
前言
Cascading Style Sheets,关键就在于这个cascading,对于这个术语理解,感觉对于我这种CSS新手有点儿不太friendly。本文记录下我对这个术语的理解,同时会以文章标题的三个单词为切入点,综合起来理解可能相对会准确一些吧。
三个术语的"开胃菜"
cascade: 有翻译"层叠"或"级联"的意思。
specificiy:有翻译"优先级"的,我个人觉得这种翻译不太合适,可能会丢失该术语原本想表达的意思,我更倾向于使用"具体性"来表达。
inheritance: 翻译为"继承性"没啥分歧,也是三个术语中最容易理解的。
三个术语的"主菜"
按照由易到难的原则,先解释inheritance,然后specificity,最后结合起来解释cascade。
inheritance
继承。是指属性的可继承性。
通过一个例子来解释什么是继承性。
css
<ul class="main">
<li>Item One</li>
<li>Item Two
<ul>
<li>2.1</li>
<li>2.2</li>
</ul>
</li>
<li>Item Three
<ul class="special">
<li>3.1
<ul>
<li>3.1.1</li>
<li>3.1.2</li>
</ul>
</li>
<li>3.2</li>
</ul>
</li>
</ul>
css
.main {
color: red;
border: 2px solid green;
}
.special {
color: black;
}
上例定义了三层无序列表ul
,最外层ul
定义了main
class并设置了字体颜色为红色和边框样式。由于color
属性是可以继承的,border
属性是不可继承的。因此,最外层ul
的子节点或后代节点的文字都是红色的。然后,由于中间层的ul
定义了special
class并设置字体颜色为黑色,它阻断了前面的color样式,采用了自己的special
样式,中间层的ul的后代节点则会继承新的color样式。
所以,继承的有以下几个特点:
- 层次性,子代继承父代(或祖先代)的属性样式,这里其实也有点"级联"的那味儿了。
- 不可继承的常用属性:
width
,margin
,padding
,border
;除了查阅css标准的属性详细信息外,一般也可以感性地来判断一个属性是否可继承。如果某些属性可继承的话,直观上会使得渲染的效果变得更糟,那么一般这个属性可能就不能被继承。
specificity
英文词典对该词的英英释义为:"the quality of being specific rather than general"。
如果理解了 "什么是一般"、"什么是具体",那么这个术语也就基本理解了。
html
<p class="paragraph">
第一个段落
</p>
<p>
第二个段落
</p>
<p>
第三个段落
</p>
css
p {
color: blue;
}
.paragraph {
color: red;
}
上例定义了三个p标签,第一个标签定义了一个"paragraph"类并将"paragraph"的字体颜色设置为红色;定义了一个p元素选择器并将字体颜色设置为蓝色。也就是说 所有的p标签的字体颜色都为蓝色;所有的p标签且class为"paragraph"的元素,字体颜色为红色。从这个例子来看,"第二个段落"和"第三个段落"只有一个p选择器来样式化(相对通用一些),"第一个段落"的样式是:p元素且class为paragraph(相对更具体一些);只要是p元素 其字体颜色就是蓝色,只要是p元素且class为paragraph其字体颜色就是红色,多了一个更明确、更具体的条件(class为paragraph)。
我们知道CSS 是一门基于规则(rule)的语言,本质上就是定义(或描述)网页中特定元素的样式的一组规则。既然是规则,当规则的条数多了之后,就有可能出现规则冲突的情况。所谓"冲突",就好比上面这个例子,p标签的文本颜色为蓝色,而paragraph类有定义了文本颜色为红色,那么对于"第一个段落"来说它到底应该选择哪个颜色,这时就需要做决策了,做决策的依据就是specificity,看谁描述的更具体更明确,就决策用哪条规则。因为"p.paragraph"比"p"更具体并明确,类选择器比元素选择器更具体。
当然了直观上是可以这样去判断的,其实specificity有其更专业性的定义和计算方法(计算出specificity的值,我把它称为"具体值")。但是,我们再实际编程时不可能总是去计算"具体值",必须有比较直观的方式去判断,因此通过对规则的具体程度的直观感受就能判断出来啦。
具体的计算方法我也列出以下:
- id选择器:一个分值(权重)为100;
- class选择器:一个分值为10;
- element选择器:一个分值为1;
再结合前面的例子,我将"第二个段落"添加一个id属性,设置为id="second",文本颜色设置为绿色。
html
<p class="paragraph">
第一个段落
</p>
<p id="second">
第二个段落
</p>
<p>
第三个段落
</p>
css
p.paragraph {
color: red;
}
p {
color: blue;
}
#second{
color: green;
}
效果如下:
可以看到"第二个段落"文字的颜色变成了绿色,说明id选择器的"具体值"更大。
selector | id选择器 | class选择器 | element选择器 |
---|---|---|---|
p | 0 | 0 | 1 |
.paragraph | 0 | 1 | 0 |
#second | 1 | 0 | 0 |
我这里的给出的示例都非常简单,主要是为了减少复杂度,尽量把自己的理解描述清楚,我相信实际工程中,样式规则会更复杂,那就得结合具体情况分析了。
写到这里可能还有个问题,如果对同一元素,有两条规则对它进行样式化,但是,这两条规则的"具体值"都是一样的,又该怎么决策呢?带着这个问题,我们进入"cascade"。
cascade
当两条规则的"具体值"都是一样的,又该怎么决策呢?不妨写个代码看看样式化的效果。
css
<div>
第一个DIV
</div>
<div>
第二个DIV
</div>
<div>
第三个DIV
</div>
css
div{
color: blue;
}
div{
color: red;
}
从运行结果来看,第一个规则(color为blue)似乎并没有生效,第二个规则(color为red)生效了。根据编程语言的"编译"或"解释"的"自上而下"经验来直观判断,当出现相同的规则时,浏览器会采用最后出现的规则来样式化元素。
这里引出一个概念叫"source order",它的作用就是上面这个例子描述的那样,当相同规则(权重值相同)样式化同一个元素时,后出现的规则将会被采用。也就是由源码 书写的顺序决定。
结合inheritance、specificity,我尝试表述下对cascade的理解:
"cascade"是指当存在多个样式规则时,确定哪种样式应该应用于元素的过程。意味着样式可以从一个规则流(或级联)到另一个规则,不同级别的规则会影响元素的最终表示;级联的目的是提供一种系统的方法来解决冲突,并根据具体性和源顺序等因素对样式进行优先排序;它涉及考虑样式的源顺序、具体性、继承性等因素,以解决冲突并决定元素的最终样式。使用这个术语似乎能捕捉到应用样式规则的顺序、流动的本质,此刻,瞬间我是似乎有点儿get到"倾泻"、"瀑布"状的感觉了。
总结
本文对级联(cascade),具体性(specificity),源顺序(source order),继承性(inheritance)作了系统性的理解和学习。当理解了术语的本质含义后,我再看到这几个单词或翻译,内心就一点儿都不"虚"了,不管它文字上怎么表示,我都知道它在说什么。今后遇到复杂的规则表示,我该怎么去用它、去调试它,剩下的就是熟练使用的问题了。当然,阅读了本文的读者如果其他角度或更深入的理解,也希望能在评论区提出来,大家一起进步,增进对CSS的理解。