跳到主要内容

选择器与优先级

长念
长念阅读约 8 分钟2 年前发布2 年前编辑

基本选择器

ID 选择器

选择 id 属性与之匹配的元素,同一文档中,每个 ID 属性都应当是唯一的。
语法: #idname

/** 选择 id 为 `doc` 的元素 */
#doc {
color: red;
}
如果 ID 选择器全局不唯一会如何?

首先功能上不会受到影响,类似 class 选择器,所有匹配的 id 都能被选择,样式也会生效; 使用 document.querySelectorAll 也能获取到一个包含所有匹配元素的列表。

类选择器

选择所有 class 属性与之匹配的元素。

语法: .classname

/** 选择所有 class 为 doc 的元素 */
.doc {
color: red;
}

元素选择器

选择所有匹配的元素。

语法: elementname

/** 选择所有的 p 元素 */
p {
color: red;
}

属性选择器

语法: [attr] [attr=value] [attr~=value] [attr|=value] [attr^=value] [attr$=value] [attr*=value]

/** 选择所有指定了 name 属性的元素 */
[name] {
color: red;
}
/** 选择所有指定了 role 属性为 header 的元素 */
[role='header'] {
color: red;
}
/** 选择所有指定了 role 属性为 header 的 p 元素 */
p[role='header'] {
color: red;
}
提示

属性选择器也是可以使用 classid 作为属性关键字的。

通用选择器

语法: * ns|* *|*

ns 指的是命名空间 (namespace),用的相对较少。

/** 选择所有元素 */
* {
box-sizing: border-box;
margin: 0px;
}

分组选择器

选择器列表

使用 , 将不同的选择器组合到一起,选择所有能被列表中的任意一个选择器选中的节点。

语法: A, B

/** 选择所有的 p 和 span 元素 */
p,
span {
color: red;
}
/** 选择所有的类名为 header 和 footer 以及 id 为 nav 的 元素 */
.header,
.footer,
#nav {
color: red;
}

组合器

组合器是将不同的选择器通过特定符号连接,选择特定的元素。

后代组合器

(空格) 连接多个选择器,选择前一个元素的后代节点。

语法: A B

/** 选择 span 标签后代中的 p 标签 */
span p {
color: red;
}

/** 选择类名为 header 标签后代中的 nav 标签后代中的所有 li 标签 */
.header nav li {
color: red;
}

直接子代组合器

> 连接多个选择器,选择前一个元素的直接后代节点

语法: A > B

/** 选择 span 标签直接后代中的 p 标签 */
span > p {
color: red;
}

/** 选择类名为 header 标签后代中的 nav 标签直接后代中的所有 li 标签 */
.header nav > li {
color: red;
}

一般兄弟组合器

~ 连接多个选择器,选择前一个元素的匹配的兄弟节点(只要是与前一个元素同一父节点即可,位置前后都可)。

语法: A ~ B

/** 选择与 span 标签相同父节点的兄弟 p 标签 */
span ~ p {
color: red;
}

/** 选择类名为 header 标签后代中与类名为 active 的 li 标签相同父节点的所有 li 标签 */
.header li.active ~ li {
color: red;
}

紧邻兄弟组合器

+ 连接多个选择器,选择紧跟在前一个元素后面且匹配的一个兄弟节点(如果紧跟其后的兄弟节点不满足匹配条件,则不匹配任何元素)。

语法: A + B

/** 选择紧跟在 span 标签后面的兄弟 p 标签 */
span + p {
color: red;
}

/** 选择类名为 header 标签后代中紧跟在类名为 active 的 li 标签后的 li 标签 */
.header li.active + li {
color: red;
}

列组合器

伪选择器

伪类

: 用于指定所选元素的特殊状态。

/** 访问过的 a 标签 */
a:visited {
color: red;
}
/** 聚焦的文本框 */
input:focus {
color: red;
}

常用伪类选择器

伪类描述其他
:active
匹配被用户激活的状态,即鼠标按下-松开之间的状态
:blank匹配 input textarea 未输入状态
试验功能
:checked匹配处于选中状态的 radio checkbox option
:disabled匹配处于禁用状态(不能被激活、选择、获取焦点)的元素
:empty匹配没有任何子节点的元素(注释、处理指令和 content 不影响子元素是否为空的判定;元素和文本 (包括空格) 都是有效的子元素)
:enabled匹配任何可以被元素,即可以被选择、单击、输入或获取焦点
:first-child匹配一组兄弟节点中的第一个
:first-of-type匹配一组兄弟节点中的该类型的第一个
:fullscreen匹配处于全屏模式下的所有元素
:focus匹配获取焦点的元素
:focus-visible匹配通过键盘获取焦点的元素 (忽略鼠标)
:focus-within匹配自身或者其后代节点 (包括 shadow DOM 中的后代节点) 获取焦点的元素
:has()提供一种选择父级元素/前兄弟元素的方式
:hover鼠标指针悬停在元素上时触发
:in-rangeinput 元素值在 minmax范围之内 (typenumber date time datetime-local range)
:invalid匹配未通过验证的 form fieldset input 或其他表单元素
:is()接受一个选择器列表,选择与选择器列表匹配的所有元素优先级由列表中优先级最高的决定
:last-child匹配一组兄弟节点中的最后一个
:last-of-type匹配一组兄弟节点中的该类型的最后一个
:link匹配具有 href 的尚未访问的 a area 元素
:not()匹配不符合一组选择器的元素,由于它的作用是防止特定的元素被选中,它也被称为反选伪类。伪类有许多怪异、技巧和意料之外的结果
:nth-child()先找到所有当前元素的兄弟元素,然后按照位置先后顺序从 1 开始排序伪类有许多怪异、技巧和意料之外的结果

伪元素

:: 伪选择器用于表示无法用 HTML 语义表达的实体

/** before 伪元素添加 * 号 */
.header::before {
content: '*';
}

/** p 元素内容首字母 */
p::first-letter {
color: red;
}

权重

选择器权重
行内样式 inline style1000
ID 选择器100
类选择器 class、属性选择器 attibutes、伪类选择器 pseudo-class10
元素选择器 element、伪元素选择器 pseudo-element1
关键字 !important最高

权重规则

  • 匹配规则中的各个选择器权重累计相加
  • 相同权重的选择器,最后出现的规则将覆盖之前的
  • !important 优先级最高,切忌滥用
/* 1 */
p {
}
/* 2 */
p span {
}
/* 10 */
.header {
}
/* 100 */
#nav {
}
/* 11 */
p.colorful {
}
/* 111 */
#nav li.active {
}
提示

权重计算是累加计算的,但是并不限制选择器是否重复,也就是同一个选择器是可以重复叠加计算权重的。

/* 11 */
li.active {
}
/* 31 */
li.active.active.active {
}

级联层

@layer 级联层,最后的层中的样式优先级更高。

/* p 标签为绿色 */
@layer style1 {
p {
color: red !important;
}
}

@layer style2 {
p {
color: green;
}
}