Go to comments

HTML+CSS宝典 CSS基础 层叠

css 叫做层叠样式表 ( 英文全称:Cascading Style Sheets ),

层叠 css 里面不仅是一个重要的知识,也是一个非常基础的知识,了解层叠知识过后,以后面对某些场景的时候才知道该怎么去处理。


要理解层叠,先要理解一个概念叫声明冲突

声明冲突的意思就是同一个样式,多次应用到了同一个元素,就叫做声明冲突。


一、声明冲突

看这个例子,给10个a元素设置样式

1. color: red  a元素的颜色设置成红色

2. text-decoration: none  去掉下滑线

好像没有什么声明冲突!

01<!DOCTYPE html>
02<html>
03<head>
04  <meta charset="UTF-8">
05  <style>
06    a{
07      color: red;
08      text-decoration: none;
09    }
10  </style>
11  <title>声明冲突</title>
12</head>
13<body>
14  <a href="">Lorem.</a>
15  <a href="">Pariatur.</a>
16  <a href="">Inventore.</a>
17  <a href="">Quaerat.</a>
18  <a href="">Velit!</a>
19  <a href="">Porro.</a>
20  <a href="">Et!</a>
21  <a href="">Non.</a>
22  <a href="">Necessitatibus!</a>
23  <a href="">Quasi.</a>
24</body>
25</html>

右键检查(F12)看一下,随便找一个a元素,点击选中a元素

image.png

看右边的样式表里面有两个样式应用到了a元素

1. 一个是我们自己写的样式

2. 一个是浏览器默认的样式(user agent stylesheet)也设置了颜色


a 元素具备了两个样式,两个样式怎么办呢?

有的时候一个元素可能有多个样式影响到它,而这些样式里面有一些相同的属性,这些相同的属性就产生了冲突,这就是声明冲突。

这个例子里,a元素有两个声明冲突,一个是 color 属性、一个是 text-decoration 属性,这是关于声明冲突的概念。


声明冲突是不是只会发生在 我们写的样式 跟浏览器默认的样式表之间,

其它的情况就不会发生声明冲突了,因为我们写的代码应该尽量的避免声明冲突,实际上不是这样子的,

有时候我们的代码就是要 声明冲突 为什么呢?


看一个例子,

比如下面的 a 元素全部应用了一些统一的样式

1. 文字颜色是红色  color: red 

    没有下划线 text-decoration: none

    斜体 font-style: italic 

2. 但其中一个 a 元素比较特殊,专门给这个特殊的 a 元素加一个类样式 .selected(表示被激活的),

    文字颜色为白色 color:  #fff、背景为红色 background-color: red ,表示这个a元素被选中

01<!DOCTYPE html>
02<html>
03<head>
04  <meta charset="UTF-8">
05  <style>
06    a{
07      color: red;
08      text-decoration: none;
09      font-style:italic;
10    }
11    .selected{
12      color:#fff;
13      background-color:red;
14    }
15  </style>
16  <title>声明冲突</title>
17</head>
18<body>
19  <a href="">Lorem.</a>
20  <a href="">Pariatur.</a>
21  <a href="">Inventore.</a>
22  <a href="" class="selected">Quaerat.</a>
23  <a href="">Velit!</a>
24  <a href="">Porro.</a>
25  <a href="">Et!</a>
26  <a href="">Non.</a>
27  <a href="">Necessitatibus!</a>
28  <a href="">Quasi.</a>
29</body>
30</html>

3. 我们希望有些 统一的样式 是要保留的,有些是要被 特殊的样式 覆掉盖的

4. 这个特殊的a元素( .selected )大部分样式和其它a元素是一样的,

    斜体属性保留了,去掉下划线样式保留了,我们只是改了字体颜色 和 背景颜色

image.png

开发中我们经常遇到这样的场景,

上面的代码还是一个简单的场景,实际上很多时候在更复杂的场景,我们会人为的去制造冲突,

当这些重复发生的时候,我们要解决冲突,这个解决冲突的过程就叫做层叠


层叠的意思:解决声明冲突的过程,这个层叠是浏览器自动处理的。


我们要学习浏览器是怎么处理声明冲突的,我们了解了浏览器的处理过程,我们才能在人为的制造冲突的时候很好的控制,才能把我们希望覆盖的样式给覆盖掉。


二、权重计算

层叠在有些地方叫权重计算( 是一样的意思但叫法不一样 )


权重计算会经过三步过程

第一步,比较重要性

第二步,比较特殊性

第三步,比较源次序

上面这三个步骤非常简单,经过这三个步骤的比较,比较完成之后一定能够有一个最终的样式胜出


1、第一步,比较重要性

重要性从高到底就看三步

第一步,

  作者样式表中的 !important 样式( 作者样式表的意思是,开发者写的样式 )

   color: red !important   加了 !important 后的样式,重要性是最高的,

  但是不建议加 !important,因为它的重要程度太高了,今后要想覆盖覆盖不掉,想覆盖也要加 !important

第二步,

  作者样式表中的普通样式(就是没有加 !important 的样式)

第三步,

  浏览器默认样式表( 浏览器代理 )中的样式


上面这三步从高到底排序,高的就一定把底的淘汰掉

01<!DOCTYPE html>
02<html>
03<head>
04  <meta charset="UTF-8">
05  <style>
06    a{
07      colorred !important;  /* !important 表示这是一个重要样式 */
08      text-decorationnone;  /* 作者样式表中的普通样式 */
09      font-style:italic;      /* 作者样式表中的普通样式 */
10    }
11    .selected{
12      color:#fff;             /* 作者样式表中的普通样式 */
13      background-color:red;   /* 作者样式表中的普通样式 */
14    }
15  </style>
16  <title>声明冲突</title>
17</head>
18<body>
19  <a href="">Lorem.</a>
20  <a href="">Pariatur.</a>
21  <a href="">Inventore.</a>
22  <a href="" class="selected">Quaerat.</a>
23  <a href="">Velit!</a>
24  <a href="">Porro.</a>
25  <a href="">Et!</a>
26  <a href="">Non.</a>
27  <a href="">Necessitatibus!</a>
28  <a href="">Quasi.</a>
29</body>
30</html>

color 属性发生了冲突,color 属性出现在三个地方,

1. 一个作者样式表(普通样式)

2. 一个是作者样式表的重要样式 !important ( 胜出 )

3. 一个是浏览器默认样式表中的样式

一定是作者样式表的重要样式胜出

image.png

作者样式表的重要样式胜出,冲突已经解决了第二步比较特殊性、第三步比较源次序,就不在进行了


2、第二步,比较特殊性

第二步比较特殊性,什么时候发生呢?

发生的时间在第一步比较重要性完成之后冲突还没有解决,还剩下几个有冲突的属性没有解决,它们的重要性是一样,这个时候进入第二步比较特殊性


把 css 代码中重要样式 !important 去掉

01<!DOCTYPE html>
02<html>
03<head>
04  <meta charset="UTF-8">
05  <style>
06    a{
07      colorred;
08      text-decorationnone;
09      font-style:italic;
10    }
11    .selected{
12      color:#fff;
13      background-color:red;
14    }
15  </style>
16  <title>比较特殊性</title>
17</head>
18<body>
19  <a href="">Lorem.</a>
20  <a href="">Pariatur.</a>
21  <a href="">Inventore.</a>
22  <a href="" class="selected">Quaerat.</a>
23  <a href="">Velit!</a>
24  <a href="">Porro.</a>
25  <a href="">Et!</a>
26  <a href="">Non.</a>
27  <a href="">Necessitatibus!</a>
28  <a href="">Quasi.</a>
29</body>
30</html>

color 属性出现了三次,

1. 两个是作者样式表的普通样式,这两个的重要性是一样的,

2. 所以只能淘汰浏览器的默认样式,

3. 因此第一步比较完了之后还有冲突,进入第二步的比较比较特殊性

image.png

比较特殊性有一个总体规则,总体规则就是看选择器


总体规则,

选择器选中的范围越窄,越特殊。


比如id选择器只能选中一个,他选择的范围太窄所以很特殊,

有些选择器选择的范围很广,比如通配符选择器、元素选择器,这些选择器选择的范围很广,那么它们就不太特殊,

所以按照总体规则就已经可以解决很多问题了。


a{} 和 .selected{} 都是作者样式表,重要性是一样的,进入第二步比较特殊性,谁特殊?

1.  a{} 是元素选择器选择范围很广

2.  .selected{} 是类选择器范围要窄一些,所以 .selected{} 更特殊最终胜出


很多时候比较特殊性这块,记住总体规则就已经能搞定了,

但是哪些选择器更窄,哪些选择器更特殊,这里要理解透彻,浏览器具体是怎么比较特性的,浏览器怎么做的的呢?

浏览器要确定一个四位数(千位、百位、十位、个位),怎么来计算这4位数呢?


具体规则,

通过选择器,计算出一个4位数(千位、百位、十位、个位),比较这四位数( 这四位数哪个大哪个就越特殊 )。


千位:

如果内联样式,记作1,否则记0


如果样式是写在元素里面内联样式  style="color: chocolate"

 <a href="" class="selected" style="color: chocolate">Quaerat.</a> 

在比较四位数的时候,这个四位数的千位是1,

其它样式的千位是0,因为其它的都不是内联样式(千位都是0)

01<!DOCTYPE html>
02<html>
03<head>
04  <meta charset="UTF-8">
05  <style>
06    a{
07      color: red;
08      text-decoration: none;
09      font-style:italic;
10    }
11    .selected{
12      color:#fff;
13      background-color:red;
14    }
15  </style>
16  <title>比较千位</title>
17</head>
18<body>
19  <a href="">Lorem.</a>
20  <a href="">Pariatur.</a>
21  <a href="">Inventore.</a>
22  <a href="" class="selected" style="color:chocolate">Quaerat.</a>
23  <a href="">Velit!</a>
24  <a href="">Porro.</a>
25  <a href="">Et!</a>
26  <a href="">Non.</a>
27  <a href="">Necessitatibus!</a>
28  <a href="">Quasi.</a>
29</body>
30</html>


百位:

等于选择器中所有 id 选择器的数量,

意思是样式表里面有没有 id 选择器,比如加一个 id 选择器 #mylink,id 选择器只能选择一个元素,所以 id 选中器很特殊


下面 a 元素有,

元素选择器、类选择器、id选择器,他们都有color属性的冲突,color属性的值用什么颜色?

01<!DOCTYPE html>
02<html>
03<head>
04  <meta charset="UTF-8">
05  <style>
06    a{
07      color: red;
08      text-decoration: none;
09      font-style:italic;
10    }
11    #mylink{
12      color:yellow;    
13    }
14    .selected{
15      color:#fff;
16      background-color:red;
17    }
18  </style>
19  <title>比较百位</title>
20</head>
21<body>
22 
23  <a href="" class="selected" id="mylink">Quaerat.</a>
24 
25</body>
26</html>

1. 都不是内联样式,千位都是0,比较百位,

2. 百位等于是id选择器的数量,#mylink  id选择器的数量百位是1,其它选择器的百位是0

 a               0 0 ? ? 

#mylink     0 ? ?

.selected    0 0 ? ? 


所以得到的结果是 color: yellow 黄颜色胜出

image.png

如果百位都一样,那么比较十位


十位:

等于选择器中所有 类选择器、属性选择器、伪类选择器 的数量。


类选择器、属性选择器、伪类选择器,这三种选择器他们的特殊性都差不多,这些选择器的数量加起来就是十位的数量

01<!DOCTYPE html>
02<html>
03<head>
04  <meta charset="UTF-8">
05  <style>
06    /* 000? */
07    a{
08      colorred;
09      text-decorationnone;
10      font-style:italic;
11    }
12    /* 001? 这里千位是0,百位是0,十位类选择器是1,所以胜出 */
13    .selected{
14      color:#fff;
15      background-color:red;
16    }
17  </style>
18  <title>比较十位</title>
19</head>
20<body>
21 
22  <a href="" class="selected">Quaerat.</a>
23 
24</body>
25</html>

 a                000?   

 .selected    001?  千位没有内联是0,百位没有id是0,十位类选择器有一个是1,十位比上面的高所以胜出


个位:

等于选择器中所有 元素选择器、伪元素选择器 的数量

01<!DOCTYPE html>
02<html>
03<head>
04  <meta charset="UTF-8">
05  <style>
06    /* 不是内联、不是id、不是类选择器,只有一个元素选择器 0001 */
07    a{
08      colorred;
09      text-decorationnone;
10      font-style:italic;
11    }
12    /* 不是内联、不是id、不是类选择器,有两个元素选择器 0002,所以它胜出 */
13    body a{
14      color:yellow;
15      background-color:red;
16    }
17  </style>
18  <title>比较个位</title>
19</head>
20<body>
21 
22  <a href="">Quaerat.</a>
23 
24</body>
25</html>

 body a    不是内联千位是0、没有id百位是0、没有类选择器十位是0,元素选择器有两个为 2 ,0002 这个胜出 

 a             不是内联千位是0、没有id百位是0、没有类选择器十位是0,元素选择器只有一个为1,0001        


比较特殊性的练习,

下面样式的重要性是一样的,都是作者样式表,

但是特殊性是不一样的,比较更特殊性谁最高,最后 a 元素是什么颜色?

01<!DOCTYPE html>
02<html>
03<head>
04  <meta charset="UTF-8">
05  <style>
06    /* 0001 */
07    a{
08      colorred;
09    }
10    /* 0003 */
11    div ul a{
12      colorgreen;
13    }
14    /* 0201 */
15    #mydiv #myul a{
16      color:#ccc;
17    }
18    /* 0211 */
19    #mydiv #myul a:link{
20      color:chocolate;
21    }
22    /* 0210 */
23    #mydiv #myul .mylink{
24      color:#008c8c;
25    }
26  </style>
27  <title>练习—比较特殊性</title>
28</head>
29<body>
30  <div id="mydiv">
31    <ul id="myul">
32      <li id="myli">
33        <a href="http://163.com" class="mylink">
34          举个例子
35        </a>
36      </li>
37    </ul>
38  </div>
39  <!--
40  div#mydiv
41  ul#myul
42  li*1#myli
43  -->
44</body>
45</html>


 #mydiv  #myul  a:link  

有2个百位id选择器,1个十位的伪类选择器,1个的个位元素选择器


这里有一个细节,

这四位数不是逢十进一,专门有人测过是逢 256 进一,所以比较的时候不用考虑进位的问题。


看一个例子

 .tbh-nav h2  是淘宝中的css代码, .tbh-nav .tb-bg h2   可以多写了一个类选择器 .tb-bg,特殊性高了有冲突的样式就被覆盖掉了

01.tbh-nav h2{
02  float:left;
03  width:190px;
04  text-align:center;
05  font-size:16px;
06  background:#ff5000;
07}
08.tbh-nav .tb-bg h2{
09  background:#008c8c;
10}


不要去改别人的代码,我们通常是用冲突的方式,利用层叠的规则覆盖之前的代码,

比如临近春节重大节日的时候,网站的皮肤都会改版,这个时候往往加一个 link 样式表,把之前的一些样式、颜色覆盖掉,

过完年把这个 link 文件去掉就可以了。


3、第三步,比较源次序

特殊性一样的时候,冲突还是解决不了,这个时候就比较源次序


源次序的意思是代码靠后的胜出 ,到了这一步一定只能剩一个样式了,因为书写代码总有一个前后顺序

01<!DOCTYPE html>
02<html>
03<head>
04  <meta charset="UTF-8">
05  <style>
06    /* 0001 */
07    a{
08      colorred;
09    }
10    /* 0003 */
11    div ul a{
12      colorgreen;
13    }
14    /* 0201 */
15    #mydiv #myul a{
16      color:#ccc;
17    }
18    /* 0210 */
19    #mydiv #myul :link{
20      color:chocolate;
21    }
22    /* 0210 书写靠后的马尔斯绿色胜出 */
23    #mydiv #myul .mylink{
24      color:#008c8c;
25    }
26  </style>
27  <title>比较源次序</title>
28</head>
29<body>
30 
31  <div id="mydiv">
32    <ul id="myul">
33      <li id="myli">
34        <a href="http://163.com" class="mylink">
35          举个例子
36        </a>
37      </li>
38    </ul>
39  </div>
40 
41</body>
42</html>


三、层叠的应用

第一个应用,重置样式表


作者样式的重要性要高于浏览器的默认样式的,

网上有这样一些常见的重置样式表 normalize.css、reset.css、meyer.css


袁老师喜欢用这个 meyer.css

02   v2.0 | 20110126
03   License: none (public domain)
04*/
05 
06html, body, div, span, applet, object, iframe,
07h1, h2, h3, h4, h5, h6, p, blockquote, pre,
08a, abbr, acronym, address, big, cite, code,
09del, dfn, em, img, ins, kbd, q, s, samp,
10small, strike, strong, sub, sup, tt, var,
11b, u, i, center,
12dl, dt, dd, ol, ul, li,
13fieldset, form, label, legend,
14table, caption, tbody, tfoot, thead, tr, th, td,
15article, aside, canvas, details, embed
16figure, figcaption, footer, header, hgroup, 
17menu, nav, output, ruby, section, summary,
18time, mark, audio, video {
19  margin0;
20  padding0;
21  border0;
22  font-size100%;
23  font: inherit;
24  vertical-alignbaseline;
25}
26/* HTML5 display-role reset for older browsers */
27article, aside, details, figcaption, figure, 
28footer, header, hgroup, menu, nav, section {
29  displayblock;
30}
31body {
32  line-height1;
33}
34ol, ul {
35  list-stylenone;
36}
37blockquote, q {
38  quotesnone;
39}
40blockquote:before, blockquote:after,
41q:before, q:after {
42  content'';
43  contentnone;
44}
45table {
46  border-collapsecollapse;
47  border-spacing0;
48}


第二个应用,爱恨法则


a 元素在写伪类的时候的顺序 link -> visited -> hover -> active ,为什么要这个顺序呢?跟源次序有关

01<!DOCTYPE html>
02<html>
03<head>
04  <meta charset="UTF-8">
05  <style>
06    /* 没有访问过,颜色是绿色 */
07    a:link{
08      colorgreen;
09    }
10    /* 访问过了,颜色是红色 */
11    a:visited{
12      colorred;
13    }
14    /* 鼠标移上去的时候,颜色是巧克力色 */
15    a:hover{
16      color: chocolate; 
17    }
18    /* 鼠标按下去的时候,颜色是黑色 */
19    a:active{
20      color#000;
21    }
22  </style>
23  <title>爱恨法则</title>
24</head>
25<body>
26 
27  <a href="http://163.com" >网易</a>
28 
29</body>
30</html>



Leave a comment 0 Comments.

Leave a Reply

换一张