doclist 阅读(35) 评论(0)

CSS的选择器和优先级

CSS的N种选择器

!important

其实这个玩意不算什么选择器,放在这只是为了突出这个选择器优先级或者说权重的从高到低而已。。

内联方式(行间样式)

 <div style="width:100px;height: 100px; background-color: red"></div>

详解见我的另一篇文章CSS的四种引用方式

ID选择器(ID selectors)

通过设置元素的 id 属性为该元素制定ID。ID名由开发者指定。每个ID在文档中必须是唯一的。在写样式表时,ID选择器是以#开头的。

类选择器(Class selectors)

通过设置元素的 class 属性,可以为元素指定类名。类名由开发者自己指定。 文档中的多个元素可以拥有同一个类名。在写样式表时,类选择器是以英文句号(.)开头的。

伪类/属性(Pseudo-classes selectors)

CSS伪类是加在选择器后面的用来指定元素状态的关键字。比如,:hover 会在鼠标悬停在选中元素上时应用相应的样式。(:checked:enabled:disabled。。。。)

元素选择器(类型选择器)

类型选择器匹配文档语言元素类型的名称。类型选择器匹配文档树中该元素类型的每一个实例
h1 {font-family: sans-serif;}

通用选择器(通配符)

通配符使用星号*表示,意思是“所有的”。*会匹配所有的元素,因此针对所有元素的设置可以使用*来完成,用的最多的例子如下:*{margin:0px; padding:0px;}

CSS选择器的优先级

 关于选择器优先级,很多人实际开发中遇到过坑,然后一般都是处在解决问题为上,而很少有机会扒拉一下到底里面是个啥,现在就这个问题谈谈我的理解。

权重计算法

 这是网上大多数人会采用的一种算法,搜搜博客园也是很多教程介绍的方法,首先来看看对于选择器权重的定义。

权重定义

 !important Infinity(无穷大)  
 行间样式 1000  
 id 100  
 class|属性|伪类 10  
 通配符 1

有了以上定义,就很好解释了当选择器应用的时候通过权重相加得出最终结论,然而现实总是残酷的,这种理论虽说解决了部分问题,但却是错误的理解,可能下面的俩个例子

     /* 按照这种计算方法,样式一的权重值是11,样式二的权重值是10,如果这两条规则用于同一个元素,则该元素应该是红色。实际结果却是蓝色。至于为什么会这样,见下面 */
 
     /* 样式一 */
     body header div nav ul li div p a span em {color: red}
     /* 样式二 */
     .count {color: blue}
/*   张鑫旭大佬曾经在Firefox做了这样一个demo
     256个class选择器可以干掉1个id选择器
     并总结Firefox等浏览器所有的类名(classes)都是以8字节字符串存储的,8字节所能hold的最大值就是255. 所以你想啊,当同时出现256个class, 势必会越过其边缘,溢出到id区域。
     Opera浏览器class类名的存储是以16字节的字符串。因此,该浏览器要想发生class溢出到id的话,需要连续65536个class。
 */
#id {
  background: darkblue;
}

.c000.c001.c002.c003.c004.c005.c006.c007.c008.c009.c010.c011.c012.c013.c014.c015.c016.c017.c018.c019.c020.c021.c022.c023.c024.c025.c026.c027.c028.c029.c030.c031.c032.c033.c034.c035.c036.c037.c038.c039.c040.c041.c042.c043.c044.c045.c046.c047.c048.c049.c050.c051.c052.c053.c054.c055.c056.c057.c058.c059.c060.c061.c062.c063.c064.c065.c066.c067.c068.c069.c070.c071.c072.c073.c074.c075.c076.c077.c078.c079.c080.c081.c082.c083.c084.c085.c086.c087.c088.c089.c090.c091.c092.c093.c094.c095.c096.c097.c098.c099.c100.c101.c102.c103.c104.c105.c106.c107.c108.c109.c110.c111.c112.c113.c114.c115.c116.c117.c118.c119.c120.c121.c122.c123.c124.c125.c126.c127.c128.c129.c130.c131.c132.c133.c134.c135.c136.c137.c138.c139.c140.c141.c142.c143.c144.c145.c146.c147.c148.c149.c150.c151.c152.c153.c154.c155.c156.c157.c158.c159.c160.c161.c162.c163.c164.c165.c166.c167.c168.c169.c170.c171.c172.c173.c174.c175.c176.c177.c178.c179.c180.c181.c182.c183.c184.c185.c186.c187.c188.c189.c190.c191.c192.c193.c194.c195.c196.c197.c198.c199.c200.c201.c202.c203.c204.c205.c206.c207.c208.c209.c210.c211.c212.c213.c214.c215.c216.c217.c218.c219.c220.c221.c222.c223.c224.c225.c226.c227.c228.c229.c230.c231.c232.c233.c234.c235.c236.c237.c238.c239.c240.c241.c242.c243.c244.c245.c246.c247.c248.c249.c250.c251.c252.c253.c254.c255 {
  background: darkred;
}

test {
  display: block;
  height: 100px;
  width: 100px
}​
<test id="id" class="c000 c001 c002 c003 c004 c005 c006 c007 c008 c009 c010 c011 c012 c013 c014 c015 c016 c017 c018 c019 c020 c021 c022 c023 c024 c025 c026 c027 c028 c029 c030 c031 c032 c033 c034 c035 c036 c037 c038 c039 c040 c041 c042 c043 c044 c045 c046 c047 c048 c049 c050 c051 c052 c053 c054 c055 c056 c057 c058 c059 c060 c061 c062 c063 c064 c065 c066 c067 c068 c069 c070 c071 c072 c073 c074 c075 c076 c077 c078 c079 c080 c081 c082 c083 c084 c085 c086 c087 c088 c089 c090 c091 c092 c093 c094 c095 c096 c097 c098 c099 c100 c101 c102 c103 c104 c105 c106 c107 c108 c109 c110 c111 c112 c113 c114 c115 c116 c117 c118 c119 c120 c121 c122 c123 c124 c125 c126 c127 c128 c129 c130 c131 c132 c133 c134 c135 c136 c137 c138 c139 c140 c141 c142 c143 c144 c145 c146 c147 c148 c149 c150 c151 c152 c153 c154 c155 c156 c157 c158 c159 c160 c161 c162 c163 c164 c165 c166 c167 c168 c169 c170 c171 c172 c173 c174 c175 c176 c177 c178 c179 c180 c181 c182 c183 c184 c185 c186 c187 c188 c189 c190 c191 c192 c193 c194 c195 c196 c197 c198 c199 c200 c201 c202 c203 c204 c205 c206 c207 c208 c209 c210 c211 c212 c213 c214 c215 c216 c217 c218 c219 c220 c221 c222 c223 c224 c225 c226 c227 c228 c229 c230 c231 c232 c233 c234 c235 c236 c237 c238 c239 c240 c241 c242 c243 c244 c245 c246 c247 c248 c249 c250 c251 c252 c253 c254 c255"></test>​

所以上面的所谓的权重的定义是不符合实际的,但是不能否认它是对选择器权重值的一种总结,拿来理解下也不是不可,那有没有正确的解法呢,下面的四组计算法倒是可以作为一个答案

  • 1.如果规则是写在标签的style属性中(内联样式),则A=1,否则,A=0. 对于内联样式,由于没有选择器,所以B、C、D的值都为0,即A=1, B=0, C=0, D=0(简写为1,0,0,0,下同)。

  • 2.计算该选择器中ID的数量。如果有则B=1,没有B=0(例如,#header 这样的选择器,计算为0, 1, 0, 0)。

  • 3.计算该选择器中伪类及其它属性的数量(包括class、属性选择器等,不包括伪元素)。(例如, .logo[id='site-logo'] 这样的选择器,计算为0, 0, 2, 0)

  • 4.计算该选择器中伪元素及标签的数量。(例如,p:first-letter 这样的选择器,计算为0, 0, 0, 2)。

    按照四组计算的正确方法,上面第一个例子中的样式一权重值应该是0, 0, 0, 11,样式二的权重值是0, 0, 1, 0。
    根据规范,计算权重值时,A,B,C,D四组值,从左到右,分组比较,如果A相同,比较B,如果B相同,比较C,如果C相同,比较D,如果D相同,后定义的优先

    特殊的!important

    上面最初定义了一个!important的无穷大的概念,其实总结起来就是css2中的规定:!important 用于单独指定某条样式中的单个属性。对于被指定的属性,有 !important 指定的权重值大于所有未用 !important 指定的规则。如果多条规则中都对同一个属性指定了 !important。这时候 !important 的作用相互抵销,依然按照ABCD四组计算比较。
    综上所述:!important 的作用只有在具有唯一性时才能提现,但是我们永远无法预料自己什么时候又需要覆盖一个已经指定了 !important 的属性,所以最好的办法就是:不要使用 !important。

关于inherit(继承)

<style>
  .list .item { color: red }
</style>
<ul class="list">
    <li class="item">
        <span>某些文字</span>
    </li>
</ul>
 上例中,样式规则并未针对 span 标签指定 color 属性, 但是 span 中的文字会显示为红色, 这就是因为 span 的 color 属性默认值为 inherit.对于 inherit 的属性,只要记住一点:继承而来的属性值,权重永远低于明确指定到元素的定义。只有当一个元素的某个属性没有被直接指定时,才会继承父级元素的值。 例如:
<style>
  span { color: blue }
  .list .item { color: red }
</style>
<ul class="list">
    <li class="item">
        <span>某些文字</span>
    </li>
</ul>
 同样的例子, 第一条规则的权重是 0,0,0,1, 第二条规则的权重是 0,0,2,0. 虽然第二条规则的权重更高,但是它是针对 li 元素的直接指定,并不是针对 span 元素定义的,所以计算 span 的 color 属性权重值时,实际上就是 inherit 的红色与直接指定的蓝色的对比。按照规则,只要有直接指定的值(蓝色),就不会再取继承的值(红色),所以 span 中的文字显示为蓝色。

以上就是对于css选择器和优先级的总结,

参考:
关于CSS权重(优先级)的理解
深入理解CSS权重