详解 CSS 选择器及优先级的权重计算
2024-08-03 13:53 阅读(295)

引言

CSS 是前端学习中最基础的部分,CSS选择器用于选择HTML元素并为其应用样式,想必关于 CSS 一些常见的选择器大家都不陌生,但是如果是一些使用的比较少的如 伪元素选择器、属性选择器、群组选择器等等,可能并不熟悉,且对这些选择器之间的优先级也不是很清楚。因此,我们将通过这篇文章把 CSS 里的选择器和优先级都掌握。

基础选择器

ID 选择器

这也是最常见的选择器了,这些最熟悉的选择器将快速带过,ID选择器使用元素的id属性来选择特定的HTML元素。一个页面中的每个ID都是唯一的,使用#符号加上ID名来定义ID选择器。使用方法如下:

#header {
    background-color: lightblue;
}
<div id="header">Header</div>

类选择器

类选择器使用元素的class属性来选择HTML元素。类可以在多个元素中重复使用。使用.符号加上类名来定义类选择器。

.content {
    color: green;
}
<div class="content">Content</div>
<div class="content">More Content</div>

标签选择器

标签选择器直接使用HTML标签名来选择元素,作用于页面中所有该标签的元素。

p {
    font-size: 14px;
    color: red;
}
<p>Paragraph 1</p>
<p>Paragraph 2</p>

复合选择器

从这里开始,可能对后面的选择器陌生了。复合选择器是将多个简单选择器结合在一起,以便精确地选择元素。常见的复合选择器包括后代选择器、子选择器、相邻兄弟选择器等。


后代选择器

后代选择器选择某元素内部的所有指定后代元素,用空格分隔父元素和子元素。

#main p {
    color: blue;
}
<div id="main">
    <p>Paragraph inside main</p>
</div>
<div>
    <p>Paragraph outside main</p>
</div>

可以看到只有在 id 为 main 的div中的段落标签生效了。


子选择器

子选择器仅选择某元素的直接子元素,用>符号表示。

.parent > .child {
    border: 1px solid black;
}
<div class="parent">
    <div class="child">Child</div>
    <div class="grandchild">
        <div class="child">Grandchild</div>
    </div>
</div>

只有子代才会被选中,孙代不会被选中,这也是子选择器与后代选择器不同之处,后代选择器则会将子孙都选中。


相邻兄弟选择器

相邻兄弟选择器选择紧接在特定元素后的兄弟元素,用+符号表示。

 .one+.two {
            color: pink;
        }

        .one+.three {
            color: blue;
        }
<div class="one">One</div>
    <div class="two">Two</div>
    <div class="three">Three</div>

我们可以看到这里粉色生效了,但是蓝色没有,说明相邻兄弟选择器只能选中 紧接 和 后面 的兄弟元素。


群组选择器

群组选择器用于将多个选择器组合在一起,用逗号分隔,以便对多个元素应用相同的样式。


h1, p {
    font-family: Arial, sans-serif;
}
<h1>Title</h1>
<p>Paragraph</p>

对这两个元素都生效了。


伪类选择器

伪类选择器用于选择元素的特定状态或部分,如鼠标悬停或第一个子元素等。

a:hover {
    text-decoration: none;
    background-color: red;
}
<a href="#">Link</a>

可以看到当我们将鼠标悬停在链接上,链接会改变状态为去除下划线和修改背景色。


伪元素选择器

伪元素选择器用于选择元素的某部分,并生成内容,如首字母或插入内容等。

.intro::first-letter {
    font-size: 2em;
    color: red;
}
<p class="intro">Introduction text</p>

此种选择器能较方便的修改显示的字符串等标签,此外还可以通过 .intro::before 或 .intro::after 去给首部或尾部插入内容。


属性选择器

属性选择器根据元素的属性及属性值来选择元素。

.box[data-index="1"] {
    background-color: yellow;
}
 <div class="box" data-index="1">Box 1</div>
<div class="box" data-index="2">Box 2</div>

这类选择器类似数组通过索引去取值,我们通过在标签定义的 data-index="1" 去选中的 Box 1。

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

CSS 优先级规则分为五个级别,从高到低分别为:


!important 最高权重

内联样式 (在标签中的style 属性)

ID 选择器

类选择器、伪类选择器、属性选择器

标签(元素)选择器、伪元素选择器


每种选择器根据其类型分配一个权重。权重计算方法如下:


ID 选择器:100

类选择器、属性选择器、伪类选择器:10

标签选择器、伪元素选择器:1


后代选择器、子选择器、和兄弟选择器这一类选择器通常被认为优先级相等,因为它们的权重计算方法相同:每一个选择器(后代、子、兄弟)在选择器链中增加的权重都是相同的。而根据不同的权重计算是 CSS 优先级规则中的一个核心概念。

比较示例

<div id="main" class="container">
    <p class="text">Paragraph inside main.</p>
</div>

结果显示是这样的

到这里可能有点懵了,接下来我详细解释一下:

.container p 的权重是 10 + 1 = 11。 .container > p 的权重是 10 + 1 = 11。 .text 的权重是 10。

在这个例子中,.container p 和 .container > p 的权重都是 11,它们的优先级相等,因此选择器顺序将决定哪个样式生效。如果都定义了颜色样式,.container > p 将覆盖 .container p,因为它在后面定义。

如果我们添加一个ID选择器组成后代选择器:

#main .text {
    color: red;
}

那么- #main .text 的权重是 100 + 10 = 110。


显然,#main .text 的优先级最高,应用的颜色将是紫色。

后代选择器、子选择器、相邻兄弟选择器的权重都是通过简单选择器的组合计算出来的。每种选择器增加的权重都是一样的,因为它们本质上是将多个基础选择器(类选择器、元素选择器)结合在一起。这些选择器组合在一起并不增加额外的权重,只是通过这些组合提供了更精确的选择逻辑。因此,它们的优先级相等。

而其他的选择器之间的优先级也可以通过权重计算方法去计算,在此便不一一举例了。

总结

本文详细介绍了 CSS 选择器的各种类型,包括 ID 选择器、类选择器、标签选择器、后代选择器、子选择器、相邻兄弟选择器、通用兄弟选择器等。通过实例代码,展示了每种选择器的使用方法和作用范围。同时,深入解析了 CSS 选择器的优先级计算规则,重点说明了复合选择器的权重计算方式。具体实例说明了在不同选择器的组合中,如何通过权重比较确定最终应用的样式。