Css权威指南(4th,第四版中文翻译)-3.特异性和层级继承

html-css09

Css权威指南(4th,第四版中文翻译)-3.特异性和层级继承,第1张

第2章里面我们了解了document的结构和CSS选择器是如何查找定位对应的元素的。每一个合理的document都会生成一个结构树,基于此,选择器基于元素的祖先,属性,兄弟节点和更多的因素来定位元素。而且这一dom结构树也是CSS种实现继承的基础。

继承是(Inheritance)CSS属性如何从一个元素传递到它的所有子元素的过程。浏览器在决定给一个元素配置什么样式的时候,除了要考虑继承关系,同时也要考虑元素的特异性(Specificity,这个翻译需要斟酌下,但是意思很明显,存在于多个冲突样式中的优先级机制)。而考虑的这一过程就称为级联(cascade)。接下来我们就来探讨一下这三种机制-特异性,继承和级联。后两者的区别其实可以简单归纳为:h1{color:redcolor: blue}的结果就是级联,而在h1中创建一个span就是继承。

综上,别管这几个有多抽象,继续学习,会看到回报的。

从第二章我们看到选组元素的方式太多了,所有很有可能同一个元素被很多规则选中,来看看下面的例子:

上面的3对样式中每对都是作用在同一个元素上,那么到底浏览器该在元素上应用哪一个样式呢?结果就在每个选择规则的特异性中。浏览器逐条评估每条选择器规则的特异性,然后将样式声明应用到元素上。当同一个元素中包含多个存在冲突的属性声明时,有最高特异性的属性就会胜出,把其他冲突规则替换掉。

一个选择器的特异性有选择器的组成决定,而一个特异性的值可以分成4部分,就像这样:0,0,0,0。而真实的特异性是由下面这些决定的:

还是举例来说明吧,分别来看看不同的选择规则对应的特异性值:

既然刚学了如果计算特异性值,赶紧用在之前的例子上吧:

虽然我们一般在写CSS的时候会把多个属性都写在一起,例如:

然而实际上浏览器为了更好的计算特异性值实际会把聚合的属性进行单独的拆分:

咱们再来考虑一个稍微复杂的例子:

基于这个结构最终显示的效果是这样的:

从这个例子中,我们可以很好的看到浏览器按照之前说的特异性的规则展示对应不同值得样式结果。可以看到,浏览器要对每个元素进行拆分,然后计算特异性值后再确定对这个元素渲染那些样式,想想整个流程就很繁杂,幸好浏览器都自动帮我们做好了,而且这是我们后面讲到的级联的很重要的一环。同样,详细了解浏览器的渲染流程也对我们优美的书写CSS样式有很大助益。

通用选对特异性值是没有贡献的,但它是有值的,虽然值是0,0,0,0,但这和没有特异性值是有区别的,后面会在继承章节中详细讨论。所以下面的结果是显而易见的:

除了div的后代p显示为黑色外,其他都显示为灰色。而通用选择器是不贡献特异性值得,因此下面两个表达式的值也是一样的:

之前有提过直接的ID选择器和通过属性选择器设置ID值,他们最终计算的特异性值是不同的。我们先回到之前的一个例子:

因为直接用ID选择器贡献的特异性值为0,1,0,0,而属性贡献的值为0,0,1,0, 所以下面的结果也是显而易见的:

到现在肯定很多读者会想,之前计算的特异性值的4位里面第一位是什么时候设置的?答案就是为内联样式设计的,比其他的所有声明优先级都高。来看看下面的例子:

结果很明显h1就是绿的,因为内联样式的值更高,或者说优先级更高。

有时候特异性值更高的样式还并不是你想要的,这时候可使用!important来表示那些特别重要的样式,不过格式有严格的规定,就是必须在分号前面加,例如:

!important表达式必须正确,不然的话会报错。那如果存在对同一个样式有多个important声明会怎样呢?那么这些样式都不会被应用,所以需要保证important的唯一性。

其实浏览器是这么处理important样式和非important样式的:将它们单独分成两拨,important的一拨优先级更高,并且在这个组内处理自身的冲突啥的;同样的逻辑对应于非important组,组内采用特异性值来解决冲突。来看个例子:

继承,顾名思义就是属性在祖先-后代节点间的传递机制。比如说一个在h1标签中设定的颜色,那么h1中的所有后代文本都会继承。

上例中em就是继承了h1中的gray颜色。来看个ul标签的例子:

可以看到ul的所有li元素也都继承了这一特性。继承看似简单不过也需要注意几点:

有没有很意外em中的元素为啥还是灰的,照理说应该都是黑色才对,就是因为继承来的黑色属性没有特异性值,而被全局的样式给替换了。

有时候没有特异性值也会带来麻烦,比如看:

如果id=toolbar的元素下面有链接,那么就很有可能因为没有定义而采用浏览器的默认样式,一般来说是这样:

解决方案归根结底还是要有特异性值,可以有多种方法都是可以的:

再来考虑下个问题,如果两个具有完全相同特异性值的元素作用在同一个节点上,那该怎么办?比如说像这样:

还记得css为啥叫css么?Cascading Style Sheet,级联样式表,通过定义相关的规则来结合继承和特异性值。来看看都有哪些吧。

为了更好理解,我们对后四个规则进行详细说明:

虽然p本身有内联的样式,但因为标记了!important,所以还是显示为灰色。另外即使给内联样式加上了important也没啥用:

在上面权重相同的情况下对比源头,作者的优先级高于读者的。但如果在important情况下,读者的优先级要高于作者的,总结一下顺序就是:

如果上面的类型相同,则会进入到这一步,判断特异性值。

如果特异性值也一致,最后判断下出现的顺序,后出来的覆盖先前的。

结果就是blue颜色。而这一顺序对import进来的样式也是一样的。

而就是因为这个原因才会有链接推荐样式的顺序方案,一般称为LVFHA,就像下面这样:

这个顺序还可以有另一种玩法,实现的效果是只有未访问的链接才会有hover样式,而且所有链接都会有active样式,就像下面这样:

不过最好的办法就是使用串联的伪类来彻底消除这种情况,为不同的状态设定不同的样式:

不过如果引入了active类的话还是会触发冲突:

如果我们把最后两个active状态移到hover前面,那么它们就会被忽略,当然也是有办法解决的,就是引入更多的伪类:

可能对CSS来说最基本的就是本章所讲的级联机制本身,如何解决冲突,如何实现继承,如何实现排序,都有一套底层的规则在作用。

一、Css书写顺序:

1.位置属性(position, top, right, z-index, display, float等) 

2.大小(width, height, padding, margin)

3.文字系列(font, line-height, letter-spacing, color- text-align等) 

4.背景(background, border等)

5.其他(animation, transition等)

二、Css语法:

命名一般为小写英文字母。

为了代码的易读性,在每个声明块的左花括号前添加一个空格。

每条声明语句的 : 后应该插入一个空格。

所有声明语句都应当以分号结尾。最后一条声明语句后面的分号是可选的,但是,如果省略这个分号,你的代码可能更易出错。

对于属性值或颜色参数,省略小于 1 的小数前面的 0 (例如,.5 代替 0.5;-.5px 代替 -0.5px)。

十六进制值应该全部小写,例如,#fff。

尽量使用简写形式的十六进制值,例如,用 #fff 代替 #ffffff。

避免为 0 值指定单位,例如,用 margin: 0 代替 margin: 0px。

Css常用的一些命名:

可参考:CSS 常用命名 - 彼岸时光 - 博客园。

三、Css的引入:

Css的引入一般有两种,link和@import,一般建议使用link引入。这样可以避免考虑@import的语法规则和注意事项,避免产生资源文件下载顺序混乱和http请求过多的烦恼。

四、Css的命名规范(BEM,OOCSS):

什么是BEM:BEM的意思就是块(block)、元素(element)、修饰符(modifier),是由Yandex团队提出的一种前端命名方法论。这种巧妙的命名方法让你的CSS类对其他开发者来说更加透明而且更有意义。

命名约定如下:

.block{} // 块即是通常所说的 Web 应用开发中的组件或模块。每个块在逻辑上和功能上都是相互独立的。

.block__element{} // 元素是块中的组成部分。元素不能离开块来使用。BEM 不推荐在元素中嵌套其他元素。

.block--modifier{} // 修饰符用来定义块或元素的外观和行为。同样的块在应用不同的修饰符之后,会有不同的外观。

优点:

BEM 的优点在于所产生的 CSS 类名都只使用一个类别选择器,可以避免传统做法中由于多个类别选择器嵌套带来的复杂的属性级联问题。在 BEM 命名规则中,所有的 CSS 样式规则都只用一个类别选择器。因此所有样式规则的特异性(specificity)都是相同的,也就不存在复杂的优先级问题。这可以简化属性值的层叠规则。代码清单中的命名规则的好处在于每个 CSS 类名都很简单明了,而且类名的层次关系可以与 DOM 节点的树型结构相对应。

缺点:

这样类名过于长,且复杂。

什么是OOCSS(面向对象CSS):

OOCSS 表示的是面向对象 CSS(Object Oriented CSS),是一种把面向对象方法学应用到 CSS 代码组织和管理中的实践。 OOCSS最关键的一点就是:提高他的灵活性和可重用性。这个也是OOCSS最重要的一点。OOCSS主张是通过在基础组件中添加更多的类,从而扩展基础组件的CSS规则,从而使CSS有更好的扩展性。

OOCSS的优点:

减少CSS代码。

具有清洁的HTML标记,有语义的类名,逻辑性强的层次关系。

语义标记,有助于SEO。

更好的页面优化,更快的加载时间(因为有很多组件重用)。

可扩展的标记和CSS样式,有更多的组件可以放到库中,而不影响其他的组件。

能轻松构造新的页面布局,或制作新的页面风格。

OOCSS的缺点:

OOCSS适合真正的大型网站开发,因为大型网站用到的可重用性组件特别的多,如果运用在小型项目中可能见不到什么成效。所以用不用OOCSS应该根据你的项目来决定。如果没用巧妙的使用,创建组件可能对于你来说是一堆没用的东西,成为一烂摊子,给你的维护带来意想不到的杯具,说不定还是个维护的噩梦。

  欢迎到优就业来了解

所谓层叠性是指多种CSS样式的叠加:

结果是:.two样式生效

所谓继承性是指书写CSS样式表时,子标签会继承父标签的某些样式,如文本颜色和字号。想要设置一个可继承的属性,只需将它应用于父元素即可。

与文字有关的属性都可以,实现继承:

特殊点:

结果:a标签会继承div的样式

定义CSS样式时,经常出现两个或更多规则应用在同一元素上,这时就会出现优先级的问题。

关于CSS权重,我们需要一套计算公式来计算,这个就是CSS Specificity,我们称为CSS特性或称非凡性,它是一个衡量CSS值优先级的一个标准。具体规范如下:

注意:

总结: