面试常考——CSS选择器和权重问题

152 阅读22分钟

CSS选择器

  在网页开发领域,CSS 选择器可是重中之重,随着用户对于视觉体验要求的不断提升,以及网页功能的日益丰富复杂,如何精准地定位并装扮每一个网页元素,成为了摆在开发者面前的关键挑战。你还在被面试不知道如何回答CSS选择器相关问题而困扰吗?别担心,今天就来为你详细梳理常考的CSS选择器要点,让你轻松应对,胸有成竹地拿下心仪的工作机会!

一、基本选择器

1.1 元素选择器(标签选择器)

元素选择器是CSS中最基本的选择器之一,它通过标签名来选中元素,语法格式如下:

- tagName{}

其中tagName就是HTML中的标签名(例如:p、div、h1等)

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        p{
            color:red;
        }
    </style>
</head>
<body>
    <h1>标题元素</h1>
    <p>段落元素1</p>
    <p>段落元素2</p>
</body>
</html>

解析代码:

p{ color:red; } 这个样式规则就会应用到所有的 <p>标签上,使得它们里面的文字都显示为红色(这里选中的是15 16行)

ps:

 (1)优点:与名字一致,比较简便

 (2)局限性:无法区分相同标签的问题(例如这里两个p元素都会被选中),很难为相同标签里的特定元素单独设置差异化样式

  用于对文档中相同标签的元素进行批量样式设置

那有没有其他选择器来弥补这一局限性呢?

1.2 类选择器

类选择器是一种很实用的选择器,语法格式如下:

- .xx{}

(1)前提得先有一个标签,再给这个标签添加一个class属性(例如:<p class="xx"></p>

(2)需要配合class属性来规定一个类(这里用xx举例),通过类来选中元素,选中方式是在类名前加上一个点号( .

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .xx{
            color:blue;
        }
    </style>
</head>
<body>
    <h1>标题元素</h1>
    <p>段落元素1</p>
    <p class="xx">段落元素2</p>
    <span class="xx">span元素</span>
</body>
</html>

解析代码:

我们定义了一个类选择器 .xx,并设置其文字颜色为蓝色。给第二个 <p> 标签和 <span> 标签都添加了 class="xx" 属性,这样它们就会应用 .xx 类选择器所定义的样式(16 17行)

ps:

 (1)可以在众多个一样的标签中进行区分,能够针对不同需求为部分相同标签设置独特样式

 (2)可以跨标签名去分类(例如:这里的<p>标签和<span>标签,虽然标签名不同,但是具有相同的class 值,就能归为一类)

  为页面样式的多样化设置提供了很大的灵活性,只要它们有相同的类名,就可以使用类选择器来统一设置。

1.3 ID选择器

语法格式:- #xx{}

(1)需要通过标签中的id属性配合使用,即先给标签取唯一的名字(例如:<p id="xx"></p>

(2)再通过id的方式来选中元素,选择方式是在id名称前加上#(例如:#p1{ color:green; }

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
       #p1{
        color:green;
       }
    </style>
</head>
<body>
    <h1>标题元素</h1>
    <p id="p1">段落元素</p>
    <span>span元素</span>
</body>
</html>

解析代码:

我们给<p> 标签设置了id="p1",然后在样式部分通过#p1这个 ID 选择器定义了样式规则,所以只有这个带有 id="p1"<p>标签会应用该样式(15行)

ps:

 (1)能选中唯一的元素,id更像是给元素赋予了一个独一无二的标识,在整个HTML文档中,某个id值应该是唯一出现的

 (2)但实际应用中类更常用,因为类选择器可以标注多个元素,也可以只标注一个元素,使用起来更加灵活

  通常用于需要精准定位、特定操作某个唯一元素的情况(比如页面中的logo区域、侧边栏的固定菜单等)

1.4 通配符选择器

语法格式:- *{}

不用标签名、不用任何属性,也就是会选中页面中的所有元素

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
       *{
        color:red;
       }
    </style>
</head>
<body>
    <h1>标题元素</h1>
    <p>段落元素</p>
    <span>span元素</span>
</body>
</html>

解析代码:

通过*{ color:red; }的样式规则,页面里的所有元素都被选中(14 15 16行)

ps:

  通常用来做页面初始化

  利用它统一设置页面中所有元素的一些基础样式,让页面具有一个相对整齐、规范的样式基础

Q:下列情况用基本选择器能选中“小猪佩奇”呢?

    <h1 class="rich">土豪张三</h1>
    <h1 class="beauty">明星李四</h1>
    <p class="rich">小狗旺财</p>
    <p class="beauty">小猪佩奇</p>

若要解决这一问题,那就是既要选中元素名p、又要选中class属性,这显然仅仅依靠基本选择器是无法完成的,这时候便需要借助下列的复合选择器了。

二、复合选择器

2.1 交集选择器(并列选择器)

交集选择器的语法形式是紧紧贴在一起(例如:p.beauty{}

需要同时满足多个条件(例如:既要满足标签(p),又要具备指定属性(class属性为beauty))就能选中某一个相应的元素

Q思路:

 (1)选中元素名p

 (2)并且选中class属性

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
       p.beauty{
        color:red;
       }
    </style>
</head>
<body>
    <h1 class="rich">土豪张三</h1>
    <h1 class="beauty">明星李四</h1>
    <p class="rich">小狗旺财</p>
    <p class="beauty">小猪佩奇</p>
</body>
</html>

解析代码:

我们定义了 p.beauty 这个交集选择器,只有 <p> 标签且 class 属性为 beauty 的那个元素(即 “小猪佩奇” 所在的 <p> 标签)会应用这个样式

ps:

  可以在某些难以区分种类的元素当中去做交集的处理

 用于在复杂的页面结构中,精准选中同时满足多个条件的元素

2.2 并集选择器

并集选择器的语法形式是通过使用,来分隔不同的选择器(不一定只有两个)(例如: h1,span{},为方便查看,也可以逗号后换行)

只需要满足其中一个就会被选中

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
       h1,
       span{
        color:green;
       }
    </style>
</head>
<body>
    <p>段落元素1</p>
    <p>段落元素2</p>
    <span>span元素</span>
    <div>div元素1</div>
    <div class="div">div元素2</div>
    <h1 class="rich">土豪张三</h1>
    <h1 class="beauty">明星李四</h1>
    <p class="rich">小狗旺财</p>
    <p class="beauty">小猪佩奇</p>
</body>
</html>

解析代码:

h1,span{ color:green; }的样式规则,页面里所有的<h1>标签和<span>标签中的文字都会被设置成绿色,即使它们的标签名不同

ps:

  在网页设计中常用

   比如,要对多处不同的元素设置相同的样式,就可以使用并集选择器将这些需要应用相同样式的元素选择出来,然后统一设置样式。

2.3 兄弟选择器

2.3.1紧邻的一个兄弟

语法形式是通过 +来查找元素(例如:#h1+p{}

 (1)通过两种选择器(可以相同),用+来找

 (2)紧邻!!!如果中间有别的元素就无法找到对应的元素了(如下所示)

 (3)一个!!!每次只会选中符合条件的第一个兄弟元素,即便后面还有同样符合条件的元素也不会被选中(例如:第一个代码有两个p但是只有一个会变红)

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
       #h1+p{
        color:red;
       }
    </style>
</head>
<body>
    <h1 id="h1">标题元素</h1>
    <p>段落元素</p>
    <p>段落元素</p>
</body>
</html>

解析代码:

#h1+p{ color:red; } 这个样式规则会使得 <h1> 元素(其 idh1)后面紧邻的那个 <p> 元素的文字颜色变为红色,而第二个 <p> 元素则不会变色,因为它不是紧邻在 <h1> 元素后面的唯一兄弟元素。

ps:

  常用于在标题后紧跟的段落、列表项后紧跟的说明文字等场景下,对相邻元素的间距、颜色等样式进行控制。

2.3.2紧邻的所有兄弟

语法形式是通过~进行选择(例如:#h1~p{}

它的选择规则是,先找到选择器A(例如:这里的#h1)后面的所有兄弟元素,然后再从中筛选出符合选择器B(例如:这里的<p>标签)的元素

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
       #h1~p{
        color:red;
       }
    </style>
</head>
<body>
    <h1 id="h1">标题元素</h1>
    <h1 id="h2">标题元素</h1>
    <p>段落元素</p>
    <p>段落元素</p>
    <span>span元素</span>
    <div>div元素1</div>
    <div class="div">div元素2</div>
    <h1 class="rich">土豪张三</h1>
    <h1 class="beauty">明星李四</h1>
    <p class="rich">小狗旺财</p>
    <p class="beauty">小猪佩奇</p>
</body>
</html>

解析代码:

#h1~p{ color:red; }样式规则会让 idh1<h1>元素后面所有的<p>兄弟元素的文字颜色都变成红色

ps:

 (1)兄弟!并列的可以,有嵌套关系层次的不行

 (2)选择器A~选择器B,先找A后面的所有兄弟,在筛选是B的

  在处理多个相邻且具有相同样式需求的元素时非常有用,如一组并列的按钮、多个相邻的文章摘要段落等

2.4 属性选择器

属性选择器有多种不同的匹配方式来选中元素,语法形式如下:

  • [属性名=""]
  • ^以什么开头 $以什么结尾
  • *包含某一个字母
  • ~属性值 含有某一个字段

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
       [class^="d"]{
        color:blue;
       }
       [class$="y"]{
        color:red;
       }
       [class*="i"]{
        color:green;
       }
       [class~="num1"]{
        color:yellow;
       }
    </style>
</head>
<body>
    <h1 id="h1">标题元素</h1>
    <p>段落元素</p>
    <span>span元素</span>
    <div>div元素1</div>
    <div class="div">div元素2</div>
    <h1 class="rich">土豪张三</h1>
    <h1 class="beauty">明星李四</h1>
    <p class="rich">小狗旺财</p>
    <p class="beauty">小猪佩奇</p>
    <ul>
        <li class="index num1">列表</li>
        <li class="indexn um1">列表</li>
        <li class="index">列表</li>
        <li class="index">列表</li>
    </ul>
    
</body>
</html>

解析代码:

  • $是以什么结尾的匹配方式,比如 [class$="y"],则会选中class属性值以 “y” 结尾的元素,满足该条件的元素会按照设定的样式显示。
  • *是包含某一个字母的匹配方式,像 [class*="i"]就会选中class属性值中包含 “i” 这个字母的元素,使其应用对应的样式规则。
  • ~属性值是含有某一个字段的匹配方式,例如 [class~="num1"],表示在多个单词组成的 class 属性值中,含有 “num1” 这个完整字段的元素会被选中,不过像 <li class="indexn um1">列表</li> 在代码中就不会被选中,因为它的 class 属性值里 “num1” 并不是一个完整的字段。

ps:

用于根据元素的自定义属性或 HTML 原生属性来精准地为元素添加样式

  比如根据链接的协议类型(HTTP 或 HTTPS)设置不同颜色、根据图片文件类型设置不同的透明度等。

2.5 后代选择器

2.5.1直接后代(子)

直接后代选择器语法形式是使用 >来选择元素 (例如:.div>p{})

(1)先找到指定的父代元素(例如: classdiv 的元素)

(2)再去选择紧跟在这个父代元素后面的直接子代元素(也就是 > 后面指定的元素(例如:<p>标签))

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
      .div>p{
        color:red;
      }
    </style>
</head>
<body>
    <div class="div">
        <h1>div子代h1</h1>
        <p>div子代p1</p>
        <p>div子代p1</p>
        <div>
            <span>div中的div中的span</span>
            <p>div中的div中的p</p>
        </div>
        <div>div中的div</div>
    </div>
    
</body>
</html>

解析代码:

.div>p{ color:red; } ,只会选中 classdiv 的这个父元素下面的直接 <p> 子代元素(16 17行),而嵌套在子 <div> 里面的 <p> 元素则不会应用该样式,因为它们不是直接子代元素。

ps:

在构建页面布局时,对于控制容器元素下一级子元素的样式很有用

 比如导航栏下的直接菜单项、文章容器下的直接段落等

2.5.2所有后代(子 孙)

所有后代选择器语法形式是通过使用空格(例如:.div p{}

它和直接后代选择器的区别在于,直接后代选择器只作用于元素的第一代后代(子),而所有后代选择器会作用于指定元素下的所有子后代元素(儿 孙等)

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
      .div p{
        color:red;
      }
    </style>
</head>
<body>
    <div class="div">
        <h1>div子代h1</h1>
        <p>div子代p1</p>
        <p>div子代p2</p>
        <div>
            <span>div中的div中的span</span>
            <p>div中的div中的p</p>
        </div>
        <div>div中的div</div>
    </div>
    
</body>
</html>

解析代码:

.div p{ color:red; } ,会选中 classdiv 的元素下的所有 <p> 后代元素(16 17 20行)

ps:

  在处理具有深度嵌套结构的文档时,方便对某一祖先元素下的所有特定类型后代元素进行统一的样式调整

  如在一个大型的内容区域中对所有文本段落进行样式设置

2.6 伪类选择器

(1)不是类,但是很像类

(2)选中:可以通过id选择器、类选择器等选中(例如:标签)

(3)通常选中的不是元素,是元素的某种状态,某种描述(例如: 选中div的悬停状态)

2.6.1 动态伪类

动态伪类选择器能够根据元素的不同状态来进行样式设置,常见的动态伪类选择器有以下四种:

  1. :link没有被访问过
  2. :visited访问过的
  3. :hover鼠标悬停的状态
  4. :active被激活的状态 ( 鼠标按住元素但未松开时的状态 )

(1):link :visited只有a元素才有,因为只有a链接才是一个写请求的地方,点击a链接、访问、发送请求

(2):hover :active 所有元素都有的(比如 div等元素也能使用)

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style> 
        a:link{
            color:green;
        }
        a:visited{
            color:blue;
        }
        a:hover{
            color:red;
        }
        a:active{
            color:yellow;
        }
    </style>
</head>
<body>
   <a href="https://www.ecut.edu.cn/" target="_blank">我是一个a链接</a>
</body>
</html>

效果:

(1)刚开始是绿色(:link生效)

(2)鼠标悬停使红色(:hover生效)

(3)按住不动是黄色(:active生效)

(4)松手后(相当于完成了一次访问)是蓝色(:visited生效)

ps:

 (1)注意上述的顺序(LVHA)!!!乱了可能会出错

  例如:如果把active放在最前面,就不会出现黄色

       a:active{
          color:yellow;
      }       

 (2)顺序导致了优先级的问题,如果不同的样式元素作用在同一个元素上,冲突了,则后来者居上,后面的会把前面的覆盖

  增强用户交互体验,让页面元素在不同状态下呈现不同的视觉效果

2.6.2 结构伪类

结构伪类在开发中并不常用,这里就不细讲了,以下列举了部分语法形式

  1. first-child(全部父元素中的第一个)
  2. last-child(全部父元素中的最后一个)
  3. nth-child(n)(全部父元素中的指定第n个)
  • (1)n从0开始,理论上可以到正无穷
  • (2)0或者超过元素个数的都无法选中
  • (3)元素从第一个开始
  • (4)如果直接写n 那就表示全部元素选中
  • (5)此外还可以写公式(比如:2n(even),表示偶数元素;2n+1(odd),表示奇数元素;前五个:-n+5 倒叙算出来的)
  1. first-of-type
  2. last-of-type
  3. nth-of-type(n)
  4. nth-last-child(n)
  5. nth-last-of-type(n)
  6. only-child
  7. only-of-type
  8. root
  9. empty

UI伪类

  1. checked(选中被点击的单选按钮,复选框)
  2. disabled(选中被禁用的元素(例如:文本框))
  3. eneabled(选中可以使用的元素)

ps:

  选中某一些元素的描述,嵌套关系(例如:有一个div,div中可能有好多个p或者是ul里面好多个li)

  帮助创建具有结构化布局和视觉层次的页面,使页面元素的排列更有规律和美感

2.7 伪元素选择器

  • 语法通过两个冒号 ::
  1.  befoere
  2.  after
  3.  first-letter
  4.  first-line

例如:span::before{content:"$"; }

(1)像是元素,但不是元素(理解为某些元素的某些位置)

(2)不是我们写的元素,但是可以显示出来

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
      span::before{
        content:"$";
      }
      span.book::before{
        content:"《";
      }
      span.book::after{
        content:"》";
      }
      p::first-letter{
        font-size:20px;
        color:blue;
      }
      p::first-line{
        color:red;
      }
    </style>
</head>
<body>
    <span>999.99</span>
    <br>
    <span class="book">论语</span>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Et, beatae odit. Ab, ducimus. Commodi rerum quas magnam ipsam. Ea recusandae, similique quisquam molestias incidunt porro distinctio eos. Necessitatibus, quibusdam ipsa.</p>
</body>
</html>

效果:

(1)这里的 $ 和《》在浏览器中是无法选中的

(2)first-letter:选中第一个(例如:L变成20px,蓝色)

(3)first-line:选中第一行(例如:第一行变成红色)

ps:

  可以这样理解,但是不能这样写,因为没法写成标签的形式,所以可以把《》放到样式里

        <before></before>
        论语
        <after></after>

(1)通常在做一些文章类展示(尤其是文章排版)的时候会用到

(2)但是不一定只有伪元素或者说复合选择器来做(例如:用单个元素把L套起来,再选中那个元素)

样式层叠(权重问题)

  随着网页复杂度的不断提升,样式冲突问题时有发生。这就引出了 CSS 样式权重这一关键概念,它决定了在众多样式规则相互竞争时,究竟哪一个样式最终会被应用到网页元素上。即同一元素,如果出现了同一个样式,作用了好多次,冲突了谁说了算

一、CSS样式来源概述

1.1行内样式(很少见)

行内样式是 HTML 中直接在标签内部 通过style属性来定义元素样式的一种方式(例如 <h2 style="color:red;">东华理工大学</h2>)(下面2.1.1中有代码演示,这里就不过多展示了)

  • 优点:作用在当前元素,不用通过选择器来找
  • 缺点:没有做到样式和结构相分离,而且当需要定义多组样式时写起来很麻烦

ps:

(1)用于快速调试样式。

当开发者需要对某个特定元素进行样式修改,并且只想查看该元素在当前状态下应用特定样式后的效果时,行内样式是最佳选择

(2)需要临时性地覆盖元素已经应用的外部或内部样式。

例如,在一个具有统一主题样式的网站中,某个特定的元素(如一个促销横幅)需要在特定时期(如限时活动期间)突出显示,与其他常规元素有所区别

1.2内部样式

内部样式是在 HTML 文档的<head>标签内部定义的样式(例如 <style>选择器{}</style>)(下面2.1.1中有代码演示,这里就不过多展示了)

  • 优点:对于简单的HTML文档,可以快速定义
  • 缺点:复用性差,如果多个 HTML 文档需要相同的样式,需要在每个文档的<head>部分重复定义样式规则,不利于样式的复用。

ps:

(1)主要用于定义特定页面独有的样式

当一个网页有自己独特的布局和设计要求,与网站的其他页面不完全相同,并且这些样式只在该页面内使用时,内部样式是很好的选择。

(2)对于页面内具有特定功能或视觉效果的元素组,内部样式可以很好地进行局部管理,

有文章标题、作者信息、正文内容等不同的元素部分。设置标题的字体大小和颜色、作者信息的字体样式、正文内容的行间距等

1.3外部样式(最常见)

外部样式是将样式规则定义在一个独立的.CSS文件中,然后通过 HTML 文档中的<link>标签(用于链接 CSS 文件)或者@import规则(在 CSS 中导入其他 CSS 文件)将外部样式文件引入到 HTML 文档中。(例如:<link rel="stylesheet" href="./index.css">)(下面2.1.2中有代码,这里就不过多展示了)

  • 优点:复用性高,结构与样式分离,代码更加清晰,便于分工协作
  • 缺点:如果外部CSS文件体积较大,可能会导致HTML文档加载时间变长;可能会将简单网页复杂化

ps:

(1)实现网站全站样式统一

通过将通用的样式规则(如字体设置、颜色主题、布局模板等)定义在一个或多个外部样式表中,然后在网站的各个页面中引用这些样式表,可以确保整个网站具有一致的视觉风格

(2)外部样式表可以实现样式的模块化,便于在不同页面中复用样式代码。

例如,一个网站可能有多个页面都包含导航栏,这些导航栏的样式(如背景颜色、字体样式、菜单布局等)可以在外部样式表中定义为一个独立的模块。当需要创建新的页面或者修改导航栏样式时,只需要在外部样式表中对这个模块进行修改,所有引用该样式表的页面中的导航栏样式都会随之更新。

二、样式权重计算

在网页开发中,当存在多种样式来源且样式规则发生冲突时,遵循特定的权重计算规则来确定最终应用的样式

2.1基本选择器权重计算

2.1.1 行内样式、内部样式与外部样式的优先级关系

(1)行内 > 内部 = 外部

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        h2{
            color:blue;
        }
    </style>
</head>
<body>
    <h2 style="color:red;">东华理工大学</h2>
</body>
</html>

上述代码运行结果 是红色,内部样式是通过选择器选中的,而行内样式没有选择器就能作用在当前元素上,行内样式之所以优先级高,是因为它直接作用于特定元素,具有更强的针对性和即时性

2.1.2 “后来者居上”原则

(2)“后来者居上”原则:后面的会覆盖前面作用的结果。

  • 在内部样式与外部样式优先级相同的情况下,会遵循 “后来者居上” 的规则

示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Document</title>
     <style>
         h2{
             color:blue;
         }
     </style>
     <link rel="stylesheet" href="./index.css">
 </head>
 <body>
     <h2>东华理工大学</h2>
 </body>
 </html>

对应的index.css文件内容为:

h2{
   color:green;
}

上述代码运行结果是green,由于优先级 内部样式与外部样式地位一样,故遵守后来者居上的原则,link元素写在了style元素后面,即link元素是后引用的,所以会执行green

ps:

这一原则的存在保证了在相同优先级的样式设置中,最后引入或定义的样式能够生效,使得开发者可以灵活地更新和调整样式。

在同一个样式表(以外部样式表为例)情况的前提下,通过不同的选择器选中同一个元素发生冲突时,听谁的?

2.1.3 基本选择器类型优先级顺序

(3)(行内)>ID选择器 > 类选择器 > 元素选择器 > 通配符选择器

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <h2 id="h2" class="test">东华理工大学</h2>
</body>
</html>

对应的index.css文件内容为:

#h2{
    color:purple;
}
.test{
    color:orange;
}
h2{
    color:green;
}
*{
    color:blue;
}

运行结果是purple,可以从上至下依次删除不同的选择器进行验证

可以从选择器的特殊性进行记忆

  • ID选择器能够精准地定位到具有特定ID的唯一元素,范围最为精确;
  • 类选择器是将具有相同类名的元素归为一类进行样式设置,范围相对较广;
  • 元素选择器则针对特定类型的所有元素,
  • 通配符选择器几乎没有任何特征限制,会选中所有元素,其特殊性最低。
2.1.4 !important修饰符
!important的作用与语法
  • !important修饰符具有最高的优先级(是放在属性值后面的,而不是选择器)(例如:p { color: green!important; })

!important > 行内

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <h2 id="h2" class="test" style="color:black;">东华理工大学</h2>
</body>
</html>

index.css文件内容为:

#h2{
    color:purple;
}
.test{
    color:orange;
}
h2{
    color:green !important;
}
*{
    color:blue;
}

上述代码运行结果显示的是绿色

多个!important作用规则

如果有多个!important,则先看选择器的优先级,再是后来者居上原则(举例如下)

示例:

 h2{
     color:green !important;
 }
 *{
     color:blue !important;
 }

上述代码运行结果是green(元素选择器优先级高于通配符选择器)

h2{
    color:green !important;
}
h2{
    color:blue !important;
}

上述代码运行结果是blue(后来者居上原则)

2.1.5 权重计算总结

!important修饰符 > 行内 > ID 选择器 > 类选择器 > 元素选择器 > 通配符选择器

  1. 看!important修饰符
  2. 比较样式表(行内>内部>外部)
  3. 比较选择器(ID选择器>类选择器>元素选择器>通配符选择器),这里需要注意的是:行内>ID
  4. 后来者居上原则

2.2复合选择器权重计算

(a,b,c)

  • a:ID选择器的个数的和 (找#
  • b:类 伪类 属性选择器的个数的和 (找 . : []
  • c:元素 伪元素选择器的个数的和 (找 tagName ::

(1)先后比较a,b,c;若已经出现不等的就不再往后比(比如两个的a不相等,后面就不需要再比b和c了)。谁大,谁权重就高

(2)如果两种选中方式的a,b,c三个都分别相等,那就是后来者居上 示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <div class="container">
        <p>
            <span class="name">东华理工</span>
            <span>大学</span>
        </p>
</body>
</html>
.container span.name{
    /* .container 通过类选择器选中外面的div 找它的后代元素span  */
    /* 用交集选择器(span.name)选中第一个span  */
    color:blue;
}
div p span:nth-child(1){
    /* 先找到外层div div空格p 找后代再空格span:nth-child(1)找第一个 */
    color:orange;
}

代码解析两种选中方式选的都是12行,表达方式不同,第一种是(0,2,1),第二种是(0,1,3) a1=a2;b1>b2,所以第一种的权重值更大,即运行结果是blue(即使调换顺序,也是blue)

后来者居上示例:

div p span:nth-child(1){
    /* 先找到外层div div空格p 找后代再空格span:nth-child(1)找第一个 */
    color:orange;
}
div p span:first-child{
    /* .container 通过类选择器选中外面的div 找它的后代元素span  */
    /* 用交集选择器(span.name)选中第一个span  */
    color:blue;
}

这里的两种方式都是(0,1,3),故遵循后来者居上原则(即blue),如果调换顺序,会改变颜色

上述2.1.5的总结用这个方法也能进行理解 !important修饰符 > 行内 > ID 选择器(1,0,0) > 类选择器(0,1,0) > 元素选择器(0,0,1) > 通配符选择器(0,0,0)