Go to comments

HTML+CSS宝典 CSS基础 层叠

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

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


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

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


一、声明冲突

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

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

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

好像没有什么声明冲突!

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    a{
      color: red;
      text-decoration: none;
    }
  </style>
  <title>声明冲突</title>
</head>
<body>
  <a href="">Lorem.</a>
  <a href="">Pariatur.</a>
  <a href="">Inventore.</a>
  <a href="">Quaerat.</a>
  <a href="">Velit!</a>
  <a href="">Porro.</a>
  <a href="">Et!</a>
  <a href="">Non.</a>
  <a href="">Necessitatibus!</a>
  <a href="">Quasi.</a>
</body>
</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元素被选中

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    a{
      color: red;
      text-decoration: none;
      font-style:italic;
    }
    .selected{
      color:#fff;
      background-color:red;
    }
  </style>
  <title>声明冲突</title>
</head>
<body>
  <a href="">Lorem.</a>
  <a href="">Pariatur.</a>
  <a href="">Inventore.</a>
  <a href="" class="selected">Quaerat.</a>
  <a href="">Velit!</a>
  <a href="">Porro.</a>
  <a href="">Et!</a>
  <a href="">Non.</a>
  <a href="">Necessitatibus!</a>
  <a href="">Quasi.</a>
</body>
</html>

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

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

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

image.png

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

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

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


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


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


二、权重计算

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


权重计算会经过三步过程

第一步,比较重要性

第二步,比较特殊性

第三步,比较源次序

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


1、第一步,比较重要性

重要性从高到底就看三步

第一步,

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

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

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

第二步,

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

第三步,

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


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

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    a{
      color: red !important;  /* !important 表示这是一个重要样式 */
      text-decoration: none;  /* 作者样式表中的普通样式 */
      font-style:italic;      /* 作者样式表中的普通样式 */
    }
    .selected{
      color:#fff;             /* 作者样式表中的普通样式 */
      background-color:red;   /* 作者样式表中的普通样式 */
    }
  </style>
  <title>声明冲突</title>
</head>
<body>
  <a href="">Lorem.</a>
  <a href="">Pariatur.</a>
  <a href="">Inventore.</a>
  <a href="" class="selected">Quaerat.</a>
  <a href="">Velit!</a>
  <a href="">Porro.</a>
  <a href="">Et!</a>
  <a href="">Non.</a>
  <a href="">Necessitatibus!</a>
  <a href="">Quasi.</a>
</body>
</html>

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

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

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

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

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

image.png

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


2、第二步,比较特殊性

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

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


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

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    a{
      color: red;
      text-decoration: none;
      font-style:italic;
    }
    .selected{
      color:#fff;
      background-color:red;
    }
  </style>
  <title>比较特殊性</title>
</head>
<body>
  <a href="">Lorem.</a>
  <a href="">Pariatur.</a>
  <a href="">Inventore.</a>
  <a href="" class="selected">Quaerat.</a>
  <a href="">Velit!</a>
  <a href="">Porro.</a>
  <a href="">Et!</a>
  <a href="">Non.</a>
  <a href="">Necessitatibus!</a>
  <a href="">Quasi.</a>
</body>
</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)

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    a{
      color: red;
      text-decoration: none;
      font-style:italic;
    }
    .selected{
      color:#fff;
      background-color:red;
    }
  </style>
  <title>比较千位</title>
</head>
<body>
  <a href="">Lorem.</a>
  <a href="">Pariatur.</a>
  <a href="">Inventore.</a>
  <a href="" class="selected" style="color:chocolate">Quaerat.</a>
  <a href="">Velit!</a>
  <a href="">Porro.</a>
  <a href="">Et!</a>
  <a href="">Non.</a>
  <a href="">Necessitatibus!</a>
  <a href="">Quasi.</a>
</body>
</html>


百位:

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

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


下面 a 元素有,

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

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    a{
      color: red;
      text-decoration: none;
      font-style:italic;
    }
    #mylink{
      color:yellow;    
    }
    .selected{
      color:#fff;
      background-color:red;
    }
  </style>
  <title>比较百位</title>
</head>
<body>

  <a href="" class="selected" id="mylink">Quaerat.</a>

</body>
</html>

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

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

 a               0 0 ? ? 

#mylink     0 ? ?

.selected    0 0 ? ? 


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

image.png

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


十位:

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


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

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    /* 000? */
    a{
      color: red;
      text-decoration: none;
      font-style:italic;
    }
    /* 001? 这里千位是0,百位是0,十位类选择器是1,所以胜出 */
    .selected{
      color:#fff;
      background-color:red;
    }
  </style>
  <title>比较十位</title>
</head>
<body>

  <a href="" class="selected">Quaerat.</a>

</body>
</html>

 a                000?   

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


个位:

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

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    /* 不是内联、不是id、不是类选择器,只有一个元素选择器 0001 */
    a{
      color: red;
      text-decoration: none;
      font-style:italic;
    }
    /* 不是内联、不是id、不是类选择器,有两个元素选择器 0002,所以它胜出 */
    body a{
      color:yellow;
      background-color:red;
    }
  </style>
  <title>比较个位</title>
</head>
<body>

  <a href="">Quaerat.</a>

</body>
</html>

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

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


比较特殊性的练习,

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

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

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    /* 0001 */
    a{
      color: red;
    }
    /* 0003 */
    div ul a{
      color: green;
    }
    /* 0201 */
    #mydiv #myul a{
      color:#ccc;
    }
    /* 0211 */
    #mydiv #myul a:link{
      color:chocolate;
    }
    /* 0210 */
    #mydiv #myul .mylink{
      color:#008c8c;
    }
  </style>
  <title>练习—比较特殊性</title>
</head>
<body>
  <div id="mydiv">
    <ul id="myul">
      <li id="myli">
        <a href="http://163.com" class="mylink">
          举个例子
        </a>
      </li>
    </ul>
  </div>
  <!--
  div#mydiv
  ul#myul
  li*1#myli
  -->
</body>
</html>


 #mydiv  #myul  a:link  

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


这里有一个细节,

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


看一个例子

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

.tbh-nav h2{
  float:left;
  width:190px;
  text-align:center;
  font-size:16px;
  background:#ff5000;
}
.tbh-nav .tb-bg h2{
  background:#008c8c;
}


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

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

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


3、第三步,比较源次序

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


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

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    /* 0001 */
    a{
      color: red;
    }
    /* 0003 */
    div ul a{
      color: green;
    }
    /* 0201 */
    #mydiv #myul a{
      color:#ccc;
    }
    /* 0210 */
    #mydiv #myul :link{
      color:chocolate;
    }
    /* 0210 书写靠后的马尔斯绿色胜出 */
    #mydiv #myul .mylink{
      color:#008c8c;
    }
  </style>
  <title>比较源次序</title>
</head>
<body>

  <div id="mydiv">
    <ul id="myul">
      <li id="myli">
        <a href="http://163.com" class="mylink">
          举个例子
        </a>
      </li>
    </ul>
  </div>

</body>
</html>


三、层叠的应用

第一个应用,重置样式表


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

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


袁老师喜欢用这个 meyer.css

/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
  display: block;
}
body {
  line-height: 1;
}
ol, ul {
  list-style: none;
}
blockquote, q {
  quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}


第二个应用,爱恨法则


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

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    /* 没有访问过,颜色是绿色 */
    a:link{
      color: green;
    }
    /* 访问过了,颜色是红色 */
    a:visited{
      color: red;
    }
    /* 鼠标移上去的时候,颜色是巧克力色 */
    a:hover{
      color: chocolate; 
    }
    /* 鼠标按下去的时候,颜色是黑色 */
    a:active{
      color: #000;
    }
  </style>
  <title>爱恨法则</title>
</head>
<body>

  <a href="http://163.com" >网易</a>

</body>
</html>



Leave a comment 0 Comments.

Leave a Reply

换一张