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{} 类选择器范围要窄一些

3). 所以  .selected{}  更特殊最终胜出


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

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

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


具体规则:

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


千位

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


如果样式是写在元素里面的内联样式

 <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,0比较百位,

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

 a               00?? 

#mylink     01??

.selected    00?? 


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

image.png

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


十位

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


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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
    a{
        /* 000? */
        color: red;
        text-decoration: none;
        font-style:italic;
    }
    .selected{
        /* 001? 这里千位是0,百位是0,十位类选择器是1,所以胜出 */
        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">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
    a{
        /* 不是内联、不是id、不是类选择器,只有一个元素选择器 0001 */
        color: red;
        text-decoration: none;
        font-style:italic;
    }
    body a{
        /* 不是内联、不是id、不是类选择器,有两个元素选择器 0002,所以它胜出 */
        color:yellow;
        background-color:red;
    }
</style>
<title>比较个位</title>
</head>
<body>
    <a href="">Quaerat.</a>
</body>
</html>

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

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


比较特殊性的练习

下面样式的重要性是一样的,都是作者样式表,但是特殊性是不一样的,比较更特殊性谁最高,最后a元素是什么颜色?

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
    <style>

        a{                   /* 0001 */
            color: red;
        }
        div ul a{            /* 0003 */
            color: green;
        }
        #mydiv #myul a{      /* 0201 */
            color:#ccc;
        }
        #mydiv #myul a:link{ /* 0211 */
            color:chocolate;
        }
        #mydiv #myul .mylink{/* 0210 */
            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  有两个百位id选择器,一个十位的伪类选择器,一个的个位元素选择器


这里有一个细节:

这四位数不是逢十进一,专门有人测过是逢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>
        a{                   /* 0001 */
            color: red;
        }
        div ul a{            /* 0003 */
            color: green;
        }
        #mydiv #myul a{      /* 0201 */
            color:#ccc;
        }
        #mydiv #myul :link{  /* 0210 */
            color:chocolate;
        }
        #mydiv #myul .mylink{ /* 0210 书写靠后的“马尔斯绿色”胜出*/
            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>

三、层叠的应用

1、第一个应用,重置样式表

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

网上有这样一些常见的重置样式表 normalize.css、reset.css、meyer.css(袁老师喜欢用这个meyer.css,http://meyerweb.com/eric/tools/css/reset/)

/* 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%; /* 可以理解为1em */
	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; /* 行高是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;
}

2、第二个应用,爱恨法则

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<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

换一张