CSS继承与权重值

CSS中所说的继承与其它面向对象的编程语言所说的继承属性是完全不同的。这种“奇特”的继承属性在某些时候会带来一些麻烦。因此,弄清楚继承的机制,了解哪些属性可以被继承是很有必要的(因为并不是所有的属性都会被继承)。

<!--more-->

1. 继承

继承机制是基于元素的,块状元素里面可以嵌套块及内联元素,但是内联元素并不能嵌套块状元素。此外块与内联元素又可以相互转换,因此需要牢记各种能被继承的属性,不能能继承的属性,内联元素能继承的属性,块状元素能继承的属性等等花式规定。

1.1. 继承属性分类

下面的继承属性总结来源于网络,出处已不可考。

  • 不可继承的:display、margin、border、padding、background、height、min-height、max- height、width、min-width、max-width、overflow、position、left、right、top、 bottom、z-index、float、clear、table-layout、vertical-align、page-break-after、 page-bread-before和unicode-bidi。
  • 所有元素可继承:visibility和cursor。
  • 内联元素可继承:letter-spacing、word-spacing、white-space、line-height、color、font、font-family、font-size、font-style、font-variant、font-weight、text- decoration、text-transform、direction。
  • 块状元素可继承:text-indent和text-align。
  • 列表元素可继承:list-style、list-style-type、list-style-position、list-style-image。
  • 表格元素可继承:border-collapse。

1.2. 关于继承性的思考

书里面关于继承的解释只点到了一点点:影响文本外观的样式,如字体颜色值,字体,字体大小,字体宽度,字体样式等都可以被继承,其他的属性比如边框等不能被继承...上面的资料总结的还是挺详细的,有些属性我甚至都没用到过。可以看见可以继承的属性的确大多数都是内联元素的字体样式等,而跟定位布局相关的属性是无法被继承的,我的理解就是布局需要自己手动去设计,而文本外观等可以选择让浏览器帮我们完成,如果需要可以自己另外更改。

2. 权重值

了解了继承性之后,需要考虑的问题是:当多个样式同时应用到同一个对象上时,这些样式的优先级比较。

2.1. 权重值计算

样式表中权重值ABCD的比较:

  • 如果是内联样式,千位+1;
  • 如果有id选择器,百位+1;
  • 如果有类、伪类或者属性选择器,十位+1;
  • 如果有标签名或伪元素选择器,个位+1; 最后依次比较对应位置上的数字大小,需要注意的是并不会十进制进位(不是单纯的比较最后总数大小,虽然书上是这么说的,但是貌似不是完全正确。),也就是说0,0,1,0与0,0,0,11比较的话,前者的权重值仍然比后面高(但是一般应该没有连续嵌套11个标签名的做法吧,大概会被打死的...) 对于!important,其权重值非常高,但是只当其是唯一存在的时候才有效果,当多次指定时将会抵消,仍按照上述计算公式计算比较。一般不使用!Important,前辈的经验。
  • 当多个规则应用在同一个元素上时,权重越高的样式将被优先采用;
  • 当权重值相同的时候,在样式表中后定义的样式将覆盖先前定义的样式;

2.2. 继承的权重值

但是!!!继承而来的属性值权重值是非常低的,权重值永远低于明确指定到元素的定义。只有当一个元素的某个属性没有被直接指定时,才会继承父级元素的值,也就是说可以使用一个更“具体的”选择符属性覆盖继承自祖先的属性而忽略权重值的问题。比如下面的代码:

    #r{color:red}
    span{color:blue}

    <p id="r"><span> hello</span></p>

尽管前者的权重值远大于后者,但是span里面的字体颜色仍然是蓝色。

2.3. 多类选择器

此外需要注意多类选择器的一个小问题。比如下面的例子:

    ul.red { color: red }
    li { color: green; }
    <ul class="red">
        <li class="red">hello</li>
        <li>hello</li>
    </ul>

所有的li都是绿色的,注意这里的ul和.red之间没有空格,有空格的话就看不见效果了,这里引申出另外一个关于选择器中空格的问题,在jQuery也经常碰到,而带有red类的ul,虽然看似有red类,而实际上是一个ul的多类选择器(),因此该也li为绿色,这种情况也应当归属于继承样式权重值非常低的缘故。当ul 与.red之间存在空格的时候,就变成了普通的权重值比较问题,此时.red的li显示正确的红色。

3. 最后

权重值是CSS中除了布局之外另一个很重要的特性,毕竟人家名字就叫做“层叠样式表”,层叠这个词表示的就是每个元素应用的就是最具体最顶层的那个样式。而继承,是占据在权重值最底层的,甚至低于通配符所设置的样式,啊可怜的孩子。 最后,在保证优先级的前提下,应尽量减少选择器的个数,这跟CSS渲染效率有关,关于选择器嵌套,这也是一个挺深的坑。