CSS 选择器和优先级权重计算这么简单,你还没掌握?一篇文章让你轻松通关面试!(下)

引言

许多小伙伴即将面临找工作,正在为面试忙碌准备,但在日常开发中,常因依赖框架而逐渐忽略了一些基础知识,比如------CSS 选择器以及其优先级权重,你还记得吗? 如果你也遇到过样式冲突而找不到原因,或者面试时被问到选择器优先级的计算而手忙脚乱,那么这篇文章正是为你而写!

接下来,我们将从基础规则讲起,带你逐步了解CSS选择器的概念、掌握 CSS 选择器的优先级权重计算,轻松应对日常开发和技术面试!

本篇文章将主要讲述CSS选择器的优先级权重计算 。由于篇幅限制,如果是想看关于CSS选择器 内容的小伙伴,请移步我的另外一篇文章: CSS 选择器和优先级权重计算这么简单,你还没掌握?一篇文章让你轻松通关面试!(上)

正文

CSS选择器的优先级权重计算

什么是权重问题?

权重问题 ,也被称为样式层叠问题,是指当同一个元素上应用了多次相同的样式时,发生冲突时应该以哪个样式为准。也就是"谁说了算"的问题。

在深入了解权重问题之前,我们先回顾一下样式表之间的优先级

在CSS中,样式表有以下三种常见的定义方式:

  1. 行内样式

    通过直接使用 style 属性定义样式,例如<spanstyle="xxx">

    • 优点:不需要依赖选择器,样式直接作用在当前元素上。
    • 缺点:没有实现样式与结构的分离,维护和修改都很麻烦,因此不推荐使用。
  2. 内部样式

    在HTML文件中,通过 <style> 标签写样式,例如:

    html 复制代码
    <style>
        p { color: red; }
    </style>
    • 优点:相对集中,适用于小型项目或临时调试。
    • 缺点:当样式较多时,文件会变得难以管理。
  3. 外部样式

    将样式定义在单独的CSS文件中,然后通过 <link> 标签引用,例如:<link rel="stylesheet" href="styles.css">

    • 优点:实现样式与结构的完全分离,便于管理和复用。
    • 缺点:需要额外的文件。

当上述三种样式表中的同一属性同时作用于同一元素时,必然会发生冲突。那么这时的优先级规则为:行内样式 > 内部样式 = 外部样式

拓展

看完这三种样式表的优先级后,你会不会觉得行内样式应该就是优先级最高的了?其实还有优先级比它更高的规则,只不过人家不是选择器,也不是样式表,而是放在属性值后面的一个写法 ------它就是important

写法 :在你希望强调的属性后加上 !important

css 复制代码
.test {
    color: red !important;
}

注意 :通过这种方式,你可以确保该属性无论在哪里都会优先应用。但是由于!important 具有极高的优先级,所以过度依赖它就会导致代码变得难以维护。

那么如果在同一类型的样式表 中,通过不同选择器选中了同一个元素,再出现冲突应该听谁的?这就是我们今天要研究的权重问题


基本选择器权重

html 复制代码
<!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="./style.css">
</head>
<body>
    <h2>超级无敌霹雳螺旋丸!</h2>
</body>
</html>
css 复制代码
h1 {
    color: blue;
    font-size: 12px;
}

* {
    color: aqua;
}

在这段代码中,h1{}*{} 的样式显然发生了冲突。然而,最终生效的样式却是 h1{} 的样式。为什么会这样呢?

我们可以调换样式的位置,再次运行,发现无论顺序如何变化,h1{} 的样式始终优先应用。这表明,标签选择器通配符选择器 之间是有优先级关系的,也就是说它们的权重不同:

标签选择器 > 通配符选择器

进一步验证其他的基本选择器,我们可以就得出基本选择器的优先级顺序:

id 选择器 > 类选择器 > 标签选择器 > 通配符选择器


复合选择器权重

规则讲解

复合选择器的权重通常通过abc 方法来计算。这种方法就是分别计算出你想要比较的选择器在a、b、c三个位置上的权重值,然后按顺序 进行比较。只要某一位置的权重不同,就停止比较,谁的值更大,谁的权重就更高,最终得出谁的优先级更高。

(如果三个值都一样,那么采用后来者居上的原则:顺序在后面的优先级更高)

具体计算方式如下:

  • a :计算选择器中id选择器的个数。
  • b :计算选择器中类选择器伪类选择器属性选择器的个数。
  • b :计算选择器中元素选择器伪元素选择器的个数。

有些小伙伴可能会问:这不是在讲复合选择器的权重计算吗?怎么abc的位置里除了伪类选择器伪元素选择器,其他的都是基本选择器?

其实,这是因为复合选择器本质上是由多个基本选择器组合 而成的。除了伪类选择器和伪元素选择器外,复合选择器的权重来自于这些基本选择器的组合。正是这种组合使得复合选择器的权重比单一选择器要高。因此,在计算复合选择器的权重时,我们可以将其拆解成多个基本选择器,然后按照上述规则进行计算。

Tips

当你一眼看过去,看到各种选择器,可能会觉得有些混乱,不知道该从哪里开始。其实,计算选择器权重时,我们并不需要那么复杂,可以通过以下几个简单的规则来帮助你快速判断:

  • a :由于id选择器 的唯一特征是 #,因此只需要计算选择器中 # 的个数即可。

  • b :同理,类选择器伪类选择器属性选择器 都有明显的标志:.(类选择器)、:(伪类选择器)和 [](属性选择器)。只需要计算这些符号的个数即可。不过,要记住,伪元素选择器 的标志是 ::(双冒号),需要和单冒号区分开来哦。

  • c :最后,元素选择器伪元素选择器 也很简单。只需计算元素名称(例如 divspanh1 等)和 ::(伪元素选择器)的个数。

案例分析

光靠说规则,大家可能还不能够具体地认识到如何计算权重,下面我们来通过具体的例子解释一下:

css 复制代码
.container span.name {
    color: blue;
}
div p span:nth-child(1) {
    color: orange;
}

在这个例子中,第一个选择器是 .container span.name,第二个选择器是 div p span:nth-child(1)。要比较它们的权重,就使用abc的方法,先依次计算两个选择器的abc的值,再按照顺序比较。

计算:

  1. 计算a的值:找id选择器的个数。由于两个选择器都没有使用id选择器,所以a的值都为0。

  2. 计算b的值:找类选择器、伪类选择器和属性选择器的个数。

    • 第一个选择器 .container span.name 包含两个类选择器(.container.name),因此b位置的权重为2。
    • 第二个选择器 div p span:nth-child(1) 只有一个伪类选择器 nth-child(1),所以b位置的权重为1。

其实进行到这一步,答案已经能够出来了:第一个选择器的优先级更高,不需要再进行下一步计算。但为了熟悉计算权重的方法,我们把c的值一并算出来。

  1. 计算c的值:找元素选择器和伪元素选择器的个数。

    • 第一个选择器 .container span.name 包含两个元素选择器(spanspan),所以c位置的权重为2。
    • 第二个选择器 div p span:nth-child(1) 包含三个元素选择器(divpspan),所以c位置的权重为3。

比较:

  1. 比较a的值:两个选择器的a的值都为0,权重相同。
  2. 比较b的值:第一个选择器的b的值为2,第二个选择器的b的值为1,b的值已经出现不同,比较停止。第一个选择器的权重大。

结论:

.container span.name 的权重比 div p span:nth-child(1) 高。

结语

到这里,文章内容就全部结束了!希望通过这篇文章,能帮助大家更加清晰地掌握 CSS 选择器及其优先级权重的计算方法,无论是在日常开发中解决样式冲突,还是在技术面试中自信应答,都能更加游刃有余。

如果你在阅读过程中发现任何问题或有其他的想法,欢迎交流探讨!也祝正在准备面试的小伙伴们都能拿到自己心仪的 offer,加油!🎉

相关推荐
GISer_Jing1 小时前
2025前端面试热门题目——计算机网络篇
前端·计算机网络·面试
m0_748245521 小时前
吉利前端、AI面试
前端·面试·职场和发展
TodoCoder3 小时前
【编程思想】CopyOnWrite是如何解决高并发场景中的读写瓶颈?
java·后端·面试
liyinuo20177 小时前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范
代码中の快捷键8 小时前
java开发面试有2年经验
java·开发语言·面试
bufanjun00111 小时前
JUC并发工具---ThreadLocal
java·jvm·面试·并发·并发基础
Zhu_S W1 天前
Java web的发展历史
面试·职场和发展
power-辰南1 天前
大厂 Java 架构师面试题全解析
java·前端·面试
重生之Java开发工程师1 天前
ArrayList与LinkedList、Vector的区别
java·数据结构·算法·面试