器→工具, 术→技巧, 研发, 编程语言

CSS基础知识:选择器(Selectors)

钱魏Way · · 124 次浏览

在CSS中,选择器(Selectors)是一种模式,用于选择需要添加样式的元素。选择器主要是用来确定html的树形结构中的DOM元素节点。选择器是链接文档中的元素和CSS样式的桥梁,通过选择器可以为指定的元素应用样式。CSS样式规则由两部分构成:选择器和声明

选择器的分类

选择器可以被分为以下类别:

  • 简单选择器(Simple selectors):通过元素类型、class 或 id 匹配一个或多个元素。
  • 属性选择器(Attribute selectors):通过属性/属性值 匹配一个或多个元素。
  • 伪类(Pseudo-classes):匹配处于确定状态的一个或多个元素,比如被鼠标指针悬停的元素,或当前被选中或未选中的复选框,或元素是 DOM 树中一父节点的第一个子节点。
  • 伪元素(Pseudo-elements):匹配处于相关的确定位置的一个或多个元素,例如每个段落的第一个字,或者某个元素之前生成的内容。
  • 组合器(Combinators):这里不仅仅是选择器本身,还有以有效的方式组合两个或更多的选择器用于非常特定的选择的方法。例如,你可以只选择 divs 的直系子节点的段落,或者直接跟在 headings 后面的段落。
  • 多用选择器(Multiple selectors):这些也不是单独的选择器;这个思路是将以逗号分隔开的多个选择器放在一个 CSS 规则下面, 以将一组声明应用于由这些选择器选择的所有元素。

简单选择器

类型选择器(又名:元素选择器)

此选择器只是一个选择器名和指定的HTML元素名的不区分大小写的匹配。这是选择所有指定类型的最简单方式。

类选择器(Class selectors)

类选择器由一个点“.”以及类后面的类名组成。类名是在HTML class文档元素属性中没有空格的任何值。由你自己选择一个名字。同样值得一提的是,文档中的多个元素可以具有相同的类名,而单个元素可以有多个类名(以空格分开多个类名的形式书写)。

ID 选择器

ID选择器由哈希/磅符号 (#)组成,后面是给定元素的ID名称。 任何元素都可以使用id属性设置唯一的ID名称。 由你自己选择的ID是什么。 这是选择单个元素的最有效的方式。

通用选择器(Universal selector)

通用选择(*)是最终的王牌。它允许选择在一个页面中的所有元素。由于给每个元素应用同样的规则几乎没有什么实际价值,更常见的做法是与其他选择器结合使用。

组合器(Combinators)

在CSS中,组合器允许您将多个选择器组合在一起,这允许您在其他元素中选择元素,或者与其他元素相邻。四种可用的类型是:

  • 后代选择器:允许您选择嵌套在另一个元素中的某个元素(不一定是直接的后代;例如,它可以是一个孙子)。
  • 子选择器:允许您选择一个元素,该元素是另一个元素的直接子元素。
  • 相邻兄弟选择器:允许您选择一个元素,它是另一个元素的直接兄弟元素(也就是说,在它的旁边,在层次结构的同一层)。
  • 通用兄弟选择器:允许您选择其他元素的兄弟元素(例如,在层次结构中的相同级别,但不一定就在它的旁边)。
Combinators Select
A,B 匹配满足A(和/或)B的任意元素.
A B 匹配任意元素,满足条件:B是A的后代结点(B是A的子节点,或者A的子节点的子节点)
A > B 匹配任意元素,满足条件:B是A的直接子节点
A + B 匹配任意元素,满足条件:B是A的下一个兄弟节点(AB有相同的父结点,并且B紧跟在A的后面)
A ~ B 匹配任意元素,满足条件:B是A之后的兄弟节点中的任意一个(AB有相同的父节点,B在A之后,但不一定是紧挨着A)

注:相邻兄弟选择器和通用兄弟选择器只会“向后”选择,DOM结构靠前的兄弟元素不在选择范围内。

属性选择器

属性选择器是一种特殊类型的选择器,它根据元素的 属性和属性值来匹配元素。它们的通用语法由方括号([]) 组成,其中包含属性名称,后跟可选条件以匹配属性的值。 属性选择器可以根据其匹配属性值的方式分为两类: 存在和值属性选择器 和 子串值属性选择器。

存在和值(Presence and value)属性选择器

这些属性选择器尝试匹配精确的属性值:

  • [attr]:该选择器选择包含 attr 属性的所有元素,不论 attr 的值为何。
  • [attr=val]:该选择器仅选择 attr 属性被赋值为 val 的所有元素。
  • [attr~=val]:该选择器仅选择 attr 属性的值(以空格间隔出多个值)中有包含 val 值的所有元素,比如位于被空格分隔的多个类(class)中的一个类。

子串值(Substring value)属性选择器

这种情况的属性选择器也被称为“伪正则选择器”,因为它们提供类似 regular expression 的灵活匹配方式(但请注意,这些选择器并不是真正的正则表达式):

  • [attr|=val] : 选择attr属性的值以val(包括val)或val-开头的元素(-用来处理语言编码)。
  • [attr^=val] : 选择attr属性的值以val开头(包括val)的元素。
  • [attr$=val] : 选择attr属性的值以val结尾(包括val)的元素。
  • [attr*=val] : 选择attr属性的值中包含字符串val的元素。

伪类和伪元素

伪类(Pseudo-class)

一个 CSS 伪类(pseudo-class) 是一个以冒号(:)作为前缀的关键字,当你希望样式在特定状态下才被呈现到指定的元素时,你可以往元素的选择器后面加上对应的伪类(pseudo-class)。你可能希望某个元素在处于某种状态下呈现另一种样式,例如当鼠标悬停在元素上面时,或者当一个 checkbox 被禁用或被勾选时,又或者当一个元素是它在 DOM 树中父元素的第一个孩子元素时。

:active
:any
:checked
:default
:dir()
:disabled
:empty
:enabled
:first
:first-child
:first-of-type
:fullscreen
:focus
:hover
:indeterminate
:in-range
:invalid
:lang()
:last-child
:last-of-type
:left
:link
:not()
:nth-child()
:nth-last-child()
:nth-last-of-type()
:nth-of-type()
:only-child
:only-of-type
:optional
:out-of-range
:read-only
:read-write
:required
:right
:root
:scope
:target
:valid
:visited

伪元素

伪元素(Pseudo-element)跟伪类很像,但它们又有不同的地方。它们都是关键字,但这次伪元素前缀是两个冒号 (::),同样是添加到选择器后面达到指定某个元素的某个部分。

::after
::before
::first-letter
::first-line
::selection
::backdrop

常见CSS选择器如下(”CSS” 列指示该属性是在哪个 CSS 版本中定义的):

选择器 例子 例子描述 CSS
.class .intro 选择 class=”intro” 的所有元素。 1
#id #firstname 选择 id=”firstname” 的所有元素。 1
* * 选择所有元素。 2
element p 选择所有 <p> 元素。 1
element,element div,p 选择所有 <div> 元素和所有 <p> 元素。 1
element element div p 选择 <div> 元素内部的所有 <p> 元素。 1
element>element div>p 选择父元素为 <div> 元素的所有 <p> 元素。 2
element+element div+p 选择紧接在 <div> 元素之后的所有 <p> 元素。 2
[attribute] [target] 选择带有 target 属性所有元素。 2
[attribute=value] [target=_blank] 选择 target=”_blank” 的所有元素。 2
[attribute~=value] [title~=flower] 选择 title 属性包含单词 “flower” 的所有元素。 2
[attribute|=value] [lang|=en] 选择 lang 属性值以 “en” 开头的所有元素。 2
:link a:link 选择所有未被访问的链接。 1
:visited a:visited 选择所有已被访问的链接。 1
:active a:active 选择活动链接。 1
:hover a:hover 选择鼠标指针位于其上的链接。 1
:focus input:focus 选择获得焦点的 input 元素。 2
:first-letter p:first-letter 选择每个 <p> 元素的首字母。 1
:first-line p:first-line 选择每个 <p> 元素的首行。 1
:first-child p:first-child 选择属于父元素的第一个子元素的每个 <p> 元素。 2
:before p:before 在每个 <p> 元素的内容之前插入内容。 2
:after p:after 在每个 <p> 元素的内容之后插入内容。 2
:lang(language) p:lang(it) 选择带有以 “it” 开头的 lang 属性值的每个 <p> 元素。 2
element1~element2 p~ul 选择前面有 <p> 元素的每个 <ul> 元素。 3
[attribute^=value] a[src^=”https”] 选择其 src 属性值以 “https” 开头的每个 <a> 元素。 3
[attribute$=value] a[src$=”.pdf”] 选择其 src 属性以 “.pdf” 结尾的所有 <a> 元素。 3
[attribute*=value] a[src*=”abc”] 选择其 src 属性中包含 “abc” 子串的每个 <a> 元素。 3
:first-of-type p:first-of-type 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。 3
:last-of-type p:last-of-type 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。 3
:only-of-type p:only-of-type 选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。 3
:only-child p:only-child 选择属于其父元素的唯一子元素的每个 <p> 元素。 3
:nth-child(n) p:nth-child(2) 选择属于其父元素的第二个子元素的每个 <p> 元素。 3
:nth-last-child(n) p:nth-last-child(2) 同上,从最后一个子元素开始计数。 3
:nth-of-type(n) p:nth-of-type(2) 选择属于其父元素第二个 <p> 元素的每个 <p> 元素。 3
:nth-last-of-type(n) p:nth-last-of-type(2) 同上,但是从最后一个子元素开始计数。 3
:last-child p:last-child 选择属于其父元素最后一个子元素每个 <p> 元素。 3
:root :root 选择文档的根元素。 3
:empty p:empty 选择没有子元素的每个 <p> 元素(包括文本节点)。 3
:target #news:target 选择当前活动的 #news 元素。 3
:enabled input:enabled 选择每个启用的 <input> 元素。 3
:disabled input:disabled 选择每个禁用的 <input> 元素 3
:checked input:checked 选择每个被选中的 <input> 元素。 3
:not(selector) :not(p) 选择非 <p> 元素的每个元素。 3
::selection ::selection 选择被用户选取的元素部分。 3

画成思维导图如下:

CSS选择器的权重与优先级

当我们写CSS的时候我们必须注意有些选择器在级联(cascade)上会高于其它选择器,我们写在最后面的选择器将不一定会覆盖前面我们写在同一个元素的样式。

解析顺序

CSS匹配不是从左到右进行查找,而是从右到左进行查找。如果从左到右的顺序,那么每条选择器都需要遍历整个DOM树,性能很受影响。所谓高效的CSS就是让浏览器在查找style匹配的元素的时候尽量进行少的查找, 所以选择器最好写的简洁一点。

选择器权重

权重,也就是选择器的优先级,每条选择器的规则都有其权重,权重大的会覆盖掉权重小的,很多CSS出现问题的场景,都是某处定义了一个更高权重的规则,导致此处规则不生效。

根据样式所在位置,对元素的影响也有关系:内联样式(标签内style形式) > style标签 > link标签。另外一点需要注意的是!improtant,凡是属性值后加上了!important,那么它的值不会被其他值替换。

权重的计算

如何计算指定选择器的优先级?以下为一个简单的计算方案:

样式分为四个等级:

  • 第一等:代表内联样式,如: style=”xxx”,权值为1000。
  • 第二等:代表ID选择器,如:#content,权值为100。
  • 第三等:代表类,伪类和属性选择器,如.content,:hover,[attribute],权值为10。
  • 第四等:代表元素选择器和伪元素选择器,如div,p,权值为1。

权值越高,越优先显示,示例(注意:通用选择器(*),子选择器(>)和相邻同胞选择器(+)并不在这四个等级中,所以他们的权值都为0。):

参考地址:

发表评论

邮箱地址不会被公开。 必填项已用*标注