Skip to content

选择器

选择器描述
类型选择器h1 { }
通配选择器* { }
类选择器.box { }
ID 选择器#unique { }
标签属性选择器a[title] { }
伪类选择器p:first-child { }
伪元素选择器p::first-line { }
后代选择器article p
子代选择器article > p
相邻兄弟选择器h1 + p
通用兄弟选择器h1 ~ p

元素、类和 ID 选择器

类型选择器有时也叫做“标签名选择器”或者是”元素选择器“,因为它在文档中选择了一个 HTML 标签元素的缘故。

全局选择器,是由一个星号(*)代指的,它选中了文档中的所有内容(或者是父元素中的所有内容,比如,它紧随在其他元素以及邻代运算符之后的时候)。

类选择器以一个句点(.)开头,会选择文档中应用了这个类的所有元素。

ID 选择器开头为 # 而非句点,不过基本上和类选择器是同种用法。可是在一篇文档中,一个 ID 只会用到一次。它能选中设定了id的元素,你可以在 ID 前面加上类型选择器,只指向元素和 ID 都匹配的类。

标签属性选择器

这些选择器允许基于一个元素自身是否存在(例如href)或者基于各式不同的按属性值的匹配,来选取元素。

选择器示例描述
[attr]a[title]匹配带有一个名为attr的属性的元素,方括号里的值。
[attr=value]a[href=”https://example.com“]匹配带有一个名为attr的属性的元素,其值正为value,引号中的字符串
[attr~=value]p[class~=”special“]匹配带有一个名为attr的属性的元素,其值正为value,或者匹配带有一个attr属性的元素,其值有一个或者更多,至少有一个和value匹配。注意,在一列中的好几个值,是用空格隔开的。
[attr=value]div[lang='zh']匹配带有一个名为attr的属性的元素,其值可正为value,或者开始为value,后面紧随着一个连字符。
  • 使用li[class],我们就能匹配任何有 class 属性的选择器。
  • li[class=”a“]匹配带有一个a类的选择器,不过不会选中一部分值为a而另一部分是另一个用空格隔开的值的类。
  • li[class~=”a“]会匹配一个a类,不过也可以匹配一列用空格分开、包含a类的值。

子字符串匹配选择器

这些选择器让更高级的属性的值的子字符串的匹配变得可行。例如,如果你有box-warningbox-error类,想把开头为“box-”字符串的每个物件都匹配上的话,你可以用[class^=”box-“]来把它们两个都选中。

选择器示例描述
[attr^=value]li[class^=”box-“]匹配带有一个名为attr的属性的元素,其值开头为value子字符串。
[attr$=value]li[class$=”-box“]匹配带有一个名为attr的属性的元素,其值结尾为value子字符串
[attr*=value]li[class*=”box“]匹配带有一个名为attr的属性的元素,其值的字符串中的任何地方,至少出现了一次value子字符串。

下个示例展示了这些选择器的用法:

  • li[class^=”a“]匹配了任何值开头为a的属性。
  • li[class$=”a“]匹配了任何值结尾为a的属性。
  • li[class*=”a“]匹配了任何值的字符串中出现了a的属性。

大小写敏感

如果你想在大小写不敏感的情况下,匹配属性值的话,你可以在闭合括号之前,使用i值。这个标记告诉浏览器,要以大小写不敏感的方式匹配 ASCII 字符。没有了这个标记的话,值会按照文档语言对大小写的处理方式,进行匹配——HTML 中是大小写敏感的。

下面的示例中,第一个选择器将会匹配一个开头为a的值,这样它只匹配了第一项,因为另外两项开头是大写的 A。第二个选择器使用了大小写不敏感的标记,于是匹配了所有项。

css
li[class^="a" i] {
  color: red;
}

伪类和伪元素选择器

伪类是选择器的一种,它用于选择处于特定状态的元素,比如当它们是这一类型的第一个元素时,或者是当鼠标指针悬浮在元素上面的时候。它们表现得会像是你向你的文档的某个部分应用了一个类一样,帮你在你的标记文本中减少多余的类,让你的代码更灵活、更易于维护。

伪类就是开头为冒号的关键字:

css
:pseudo-class-name ;

伪元素以类似方式表现,不过表现得是像你往标记文本中加入全新的 HTML 元素一样,而不是向现有的元素上应用类。伪元素开头为双冒号::

伪类选择器

选择器描述
:active在用户激活(例如点击)元素的时候匹配。
:any-link匹配一个链接的:link:visited状态。
:blank匹配空输入值的<input>元素。
:checked匹配处于选中状态的单选或者复选框。
:current匹配正在展示的元素,或者其上级元素。
:default匹配一组相似的元素中默认的一个或者更多的 UI 元素。
:dir基于其方向性(HTML dir属性或者 CSS direction属性的值)匹配一个元素。
:disabled匹配处于关闭状态的用户界面元素
:empty匹配除了可能存在的空格外,没有子元素的元素。
:enabled匹配处于开启状态的用户界面元素。
:first匹配分页媒体的第一页。
:first-child匹配兄弟元素中的第一个元素。
:first-of-type匹配兄弟元素中第一个某种类型的元素。
:focus当一个元素有焦点的时候匹配。
:focus-visible当元素有焦点,且焦点对用户可见的时候匹配。
:focus-within匹配有焦点的元素,以及子代元素有焦点的元素。
:future匹配当前元素之后的元素。
:hover当用户悬浮到一个元素之上的时候匹配。
:indeterminate匹配未定态值的 UI 元素,通常为 复选框。
:in-range用一个区间匹配元素,当值处于区间之内时匹配。
:invalid匹配诸如<input>的位于不可用状态的元素。
:lang基于语言(HTML lang 属性的值)匹配元素。
:last-child匹配兄弟元素中最末的那个元素。
:last-of-type匹配兄弟元素中最后一个某种类型的元素。
:left在分页媒体中,匹配左手边的页。
:link匹配未曾访问的链接。
:local-link匹配指向和当前文档同一网站页面的链接。
:is()匹配传入的选择器列表中的任何选择器。
:not匹配作为值传入自身的选择器未匹配的物件。
:nth-child匹配一列兄弟元素中的元素——兄弟元素按照an+b形式的式子进行匹配(比如 2n+1 匹配元素 1、3、5、7 等。即所有的奇数个)。
:nth-of-type匹配某种类型的一列兄弟元素(比如,<p>元素)——兄弟元素按照an+b形式的式子进行匹配(比如 2n+1 匹配元素 1、3、5、7 等。即所有的奇数个)。
:nth-last-child匹配一列兄弟元素,从后往前倒数。兄弟元素按照an+b形式的式子进行匹配(比如 2n+1 匹配按照顺序来的最后一个元素,然后往前两个,再往前两个,诸如此类。从后往前数的所有奇数个)。
:nth-last-of-type匹配某种类型的一列兄弟元素(比如,<p>元素),从后往前倒数。兄弟元素按照an+b形式的式子进行匹配(比如 2n+1 匹配按照顺序来的最后一个元素,然后往前两个,再往前两个,诸如此类。从后往前数的所有奇数个)。
:only-child匹配没有兄弟元素的元素。
:only-of-type匹配兄弟元素中某类型仅有的元素。
:optional匹配不是必填的 form 元素。
:out-of-range按区间匹配元素,当值不在区间内的的时候匹配。
:past匹配当前元素之前的元素。
:placeholder-shown匹配显示占位文字的 input 元素。
:playing匹配代表音频、视频或者相似的能“播放”或者“暂停”的资源的,且正在“播放”的元素。
:paused匹配代表音频、视频或者相似的能“播放”或者“暂停”的资源的,且正在“暂停”的元素。
:read-only匹配用户不可更改的元素。
:read-write匹配用户可更改的元素。
:required匹配必填的 form 元素。
:right在分页媒体中,匹配右手边的页。
:root匹配文档的根元素。
:scope匹配任何为参考点元素的的元素。
:valid匹配诸如<input>元素的处于可用状态的元素。
:target匹配当前 URL 目标的元素(例如如果它有一个匹配当前 URL 分段的元素)。
:visited匹配已访问链接。

常见伪类选择器

元素状态

:active、:empty:visited

:focus:focus-visible:focus-within

元素顺序个数

:nth-child():nth-of-type() > :first-child:first-of-type > :last-child:last-of-type > :only-child:only-of-type

其他

:is(), :not(), :where()

伪元素选择器

选择器描述
::after匹配出现在原有元素的实际内容之后的一个可样式化元素。
::before匹配出现在原有元素的实际内容之前的一个可样式化元素。
::first-letter匹配元素的第一个字母。
::first-line匹配包含此伪元素的元素的第一行。
::grammar-error匹配文档中包含了浏览器标记的语法错误的那部分。
::selection匹配文档中被选择的那部分。
::spelling-error匹配文档中包含了浏览器标记的拼写错误的那部分。

关系选择器

后代选择器

后代选择器——典型用单个空格(” “)字符——组合两个选择器,比如,第二个选择器匹配的元素被选择,如果他们有一个祖先(父亲,父亲的父亲,父亲的父亲的父亲,等等)元素匹配第一个选择器。选择器利用后代组合符被称作后代选择器。

body article p

子代关系选择器

子代关系选择器是个大于号(>),只会在选择器选中直接子元素的时候匹配。继承关系上更远的后代则不会匹配。例如,只选中作为<article>的直接子元素的<p>元素:

article > p

邻接兄弟

邻接兄弟选择器(+)用来选中恰好处于另一个在继承关系上同级的元素旁边的物件。例如,选中所有紧随<p>元素之后的<img>元素:

p + img

通用兄弟

如果你想选中一个元素的兄弟元素,即使它们不直接相邻,你还是可以使用通用兄弟关系选择器(~)。要选中所有的<p>元素后任何地方<img>元素,我们会这样做:

p ~ img

优先级与权重

浏览器通过优先级来判断哪些属性值与一个元素最为相关,从而在该元素上应用这些属性值。优先级是基于不同种类[选择器]组成的匹配规则。

优先级是如何计算的?

优先级就是分配给指定的 CSS 声明的一个权重,它由 匹配的选择器中的 每一种选择器类型的 数值 决定。

而当优先级与多个 CSS 声明中任意一个声明的优先级相等的时候,CSS 中最后的那个声明将会被应用到元素上。

当同一个元素有多个声明的时候,优先级才会有意义。因为每一个直接作用于元素的 CSS 规则总是会接管/覆盖(take over)该元素从祖先元素继承而来的规则。

  • 一定要优先考虑使用样式规则的优先级来解决问题而不是  !important
  • 只有在需要覆盖全站或外部 CSS 的特定页面中使用  !important
  • 永远不要在你的插件中使用  !important
  • 永远不要在全站范围的 CSS 代码中使用  !important
  • 与其使用 !important,你可以:
  1. 更好地利用 CSS 级联属性

  2. 使用更具体的规则。在您选择的元素之前,增加一个或多个其他元素,使选择器变得更加具体,并获得更高的优先级。

    html
    <div id="”test“">
      <span>Text</span>
    </div>
    css
    div#test span {
      color: green;
    }
    div span {
      color: blue;
    }
    span {
      color: red;
    }

    无论 c​ss 语句的顺序是什么样的,文本都会是绿色的(green),因为这一条规则是最有针对性、优先级最高的。(同理,无论语句顺序怎样,蓝色 blue 的规则都会覆盖红色 red 的规则)

  3. 对于(2)的一种特殊情况,当您无其他要指定的内容时,请复制简单的选择器以增加特异性。

    css
    #myId#myId span {
      color: yellow;
    }
    .myClass.myClass span {
      color: orange;
    }

什么的情况下可以使用  !important

A) 覆盖内联样式

你的网站上有一个设定了全站样式的 CSS 文件,同时你(或是你同事)写了一些很差的内联样式。

全局的 CSS 文件会在全局范围内设置网站的外观,而直接在各个元素上定义的内联样式可能会覆盖您的全局 CSS 文件。内联样式和 !important 都被认为是非常不好的做法,但是有时你可以在 CSS 文件里用 !important 去覆盖内联样式。

在这种情况下,你就可以在你全局的 CSS 文件中写一些  !important  的样式来覆盖掉那些直接写在元素上的行内样式。

<div class=”foo“ style=”color: red;“>What color am I?</div>
.foo[style*=”color: red“] {
  color: firebrick !important;
}

许多 JavaScript 框架和库都添加了内联样式。有时候可以用!important与优先级高的选择器一起使用,以重写覆盖这些内联样式。

B) 覆盖优先级高的选择器

#someElement p {
  color: blue;
}

p.awesome {
  color: red;
}

在外层有  #someElement  的情况下,你怎样能使  awesome的段落变成红色呢?这种情况下,如果不使用  !important,第一条规则永远比第二条的优先级更高

怎样覆盖  !important

A) 很简单,只需再添加一条 带  !important  的 CSS 规则,再给这个给选择器更高的优先级(添加一个标签,ID 或类);或是添加一样选择器,把它的位置放在原有声明的后面(总之,最后定义一条规则比胜)。

一些拥有更高优先级的例子:

css
table td {
  height: 50px !important;
}
.myTable td {
  height: 50px !important;
}
#myTable td {
  height: 50px !important;
}

B) 或者使用相同的选择器,但是置于已有的样式之后:

td { height: 50px !important; }

C) 或干脆改写原来的规则,以避免使用  !important

[id=”someElement“] p {
  color: blue;
}

p.awesome {
  color: red;
}

将 id 作为属性选择器的一部分而不是 id 选择器,将使其具有与类相同的特异性。上面的两个选择器现在具有相同的权重。在优先级相同情况下,后面定义的 CSS 样式会被应用。

:not  否定伪类在优先级计算中不会被看作是伪类。事实上,在计算选择器数量时还是会把其中的选择器当做普通选择器进行计数。

伪类:where()实验性总是将其特异性替换为零。

  • 优先级是基于选择器的形式进行计算的。在下面的例子中,尽管选择器 *[id=”foo“] 选择了一个 ID,但是它还是作为一个属性选择器来计算自身的优先级。

  • 无视 Dom 树中的距离,

  • 为目标元素直接添加样式,永远比继承样式的优先级高,无视优先级的遗传规则。

选择器权重值和优先级

!important > 内联 > #id > .class/属性选择器/:伪类 > 标签/::伪元素 > * > 继承

对于选择器的优先级:

  • 标签选择器、伪元素选择器:1;
  • 类选择器、伪类选择器、属性选择器:10;
  • id 选择器:100;
  • 内联样式:1000;

注意事项:

  • !important 声明的样式的优先级最高;
  • 如果优先级相同,则最后出现的样式生效;
  • 继承得到的样式的优先级最低;
  • 通用选择器(*)、子选择器(>)和相邻同胞选择器(+)并不在这四个等级中,所以它们的权值都为 0 ;
  • 样式表的来源不同时,优先级顺序为:内联样式 > 内部样式 > 外部样式 > 浏览器用户自定义样式 > 浏览器默认样式.

Released under the MIT License.