选择器与选择
2023年8月11日
编辑

如果你写过HTML文件,你会知道,页面中有非常多的元素,像是div、span、p、img、input等等常用的元素,常常都不止一个,尤其是div这种什么情况都能用的元素,经常一个页面中有几十个上甚至上百个都不奇怪。
要利用CSS来美化HTML页面中的元素,我们首先要能确定美化的目标,我们要美化的是这个目标还是那个,是那几个还是那一些,确定好目标后,如何能让我们把各种CSS化妆品作用到目标元素上呢?就需要靠选择器了,英文叫做Selector。
选择器这个名字听起来很高级的样子,它其实很简单,比如我们看到的这个CSS的代码:
我们可以把这个代码分为两大部分,花括号前面的这个就是选择器,花括号里面的就是各种样式的设定(规则),这个花括号就好像一个分界符号,也是一种指示符号 ,表示这个花括号中的样式设定都是作用于符合这个花括号前面这个选择器条件的元素。

是的,所谓的选择器,其实就是🥳一种条件,一种匹配的规则,满足或者说匹配这个条件的元素都会被这个选择器跟着的花括号中的设定影响(美化)。
最常见的几种选择器
最常见的有三类选择器:
元素(标签名称)选择器
类名选择器
ID选择器。
所谓👉元素选择器,就是只有元素的名称,比如我们上面这个CSS代码,这个div就是一个元素选择器,也就是只要是div元素就满足条件,就匹配,就会被这些样式设定影响,不管你页面中是一个两个还是一万个div,都会起作用。
然后是👉类名选择器,也就是和元素的类名称匹配,比如这么写:

这就表示,只要页面中的元素有abc这个class类名的元素,这里的样式都会对它们起作用,所以你要注意,一旦前面有个. 那么哪怕后面也的是div三个字符或者其他和元素名称一样的字符,那也不是元素名称了,而是类名,所以 . 很重要。
还有一个叫👉ID选择器,也就是根据元素的id属性的值来匹配,这个的写法就是前面要加个#:
表示只要是id属性设置为bcd的元素,就会被这里的样式设定影响。
那可能有同学会想,那要是如果我们想要某个div的元素,然后它同时需要是有abc的类名这样的条件,该怎么写?

就这样连着写,注意它们之间是没有空格的,因为一旦有了空格,就是另一种选择器了,叫做后代选择器,这个一会我们再说。
那如果我们想要选择一个同时有两个类名的这样的元素的话,该怎么写呢?
也是这样连着写,这样就表示会去匹配同时拥有这两个类名的元素,像这种前后顺序是没关系的,只匹配有没有,跟顺序无关
属性选择器与关系选择器
再给大家介绍两种选择器,一个叫做属性选择器,一种叫做关系选择器。
👉属性选择器就是通过元素的属性名称或者名称和值结合的方式来选择匹配的元素,比如:
用方括号的写法,把属性名称放在里面,这个就表示任何有这个autoplay属性的元素都会匹配,不管这个属性的值是什么。但是如果你想指定特定的值也是可以的,也就是只有该特定值的设定的属性的元素,才会被匹配到。
这个选择器就是只会对设置了autoplay属性,而且值为true的元素起作用。
属性选择器也可以和前面介绍的几个选择器结合起来使用,比如
这样这个选择器的选择范围又变小了,因为它这里首先必须是div类型的元素了,然后同时满足autoplay属性的设定,同时设定的值必须是true,才能满足匹配。
那所谓👉关系选择器,正确的说是一些选择器的统称,其实就是通过元素之间的关系进行的选择,我们前面提到的后代选择器其实就是其中一种关系选择器。
这类选择器通过html元素之间的结构、层级关系来进行元素选择、匹配。比如典型的父子层级结构,HTML中的元素是可以一层一层嵌套的,甚至可以无穷多的层级。还有像兄弟层级,也就是在同一个层级关系的元素们。关系选择器们其实就是基于这些层级关系的,比较常用的就是像后代选择器和父子选择器(直接后代选择器)。
所谓👉后代选择,它是可以穿透所有内部层级的,比如像这个结构:
假如我用这样一个后代选择器的规则来设定元素的样式,注意后代选择,其实就是选择器中间要有一个空格:

页面中匹配的元素是这两个:
因此这个规则,其实就是可以简单的解释为,只要是div内部的span元素,都符合这个匹配规则,哪怕一万层,它也没问题,也是符合的。
而👉父子选择器,就是不会有层级穿透的效果,它就是只匹配下面一层,也就是直接的子元素那一层。同样的html结构,假如我这里用的是父子选择器,比如这样:
注意父子选择器,符号就是一个右尖括号,尖括号左右两边的空格不是必须的,但是为了可读性更好,一般都会加上空格。
使用父子选择器的页面中匹配的元素是这一个:
但是假如,div下直接的span子元素有多个,那么这个些都是符合匹配的规则的,都会起作用
还有其他一些选择器,具体的可以看看 MDN上的文档教程,其中对于初学者不太好理解的可能就是👻伪类和伪元素选择器。
我这里就讲一个最常用的👉伪类选择器,叫做hover鼠标悬浮选择器,比如我写一个这样的选择器:

注意看这个hover选择器前面是有个冒号的,这是伪类选择器的写法特点,这个选择器的作用,是会匹配元素的被鼠标悬浮时的这样一个状态,那么这里这个选择器的意思其实就是当div元素被鼠标悬浮时,使用花括号中的设定。
也就是只要是div,我的鼠标放在上面,那么这个元素就会应用这里的这些样式效果,而一旦鼠标移开,不符合hover这个悬浮的条件,那么这些样式的效果就会消失。
而不同的伪类选择器📝起作用的状态或者说作用的情况是不会一样的,要根据具体的伪类选择器来进行使用。然后,像伪元素的选择器中before和after这两个伪元素选择器是需要大家好好了解下的。这两类选择器的应用场景还是挺多的,大家要有一定的了解,知道基本的使用逻辑。
如果你在学习过程中,发现各种选择器太多了,感觉头晕眼花的,其实不用担心,因为我们真正开发过程中,其实并不会用很多各种不同的选择器。🎏最常用的一般都是最简单的选择器,比如元素选择器,类名选择器,以及父子选择器,然后会用一些伪类伪元素选择器。
层叠、优先级与继承
这是CSS三个非常重要的特性,首先是👉层叠,这个词是不是看起来很眼熟,是的,就是CSS的全名的翻译-层叠样式表。那所谓层叠,其实就是指写在后面的样式会覆盖前面的样式,当然,这个覆盖是指作用于同一个元素的同一个属性名的设定。
下面这个就是两个规则,都是设置同一个元素的背景颜色的值,但是写在后面的通过类名设置的设定起作用了:
但是有时候,你可能会看到,反而是写在前面的一些规则起作用了,所以层叠这个事,其实并不是前后顺序唯一决定的,还有一个非常重要的特性,叫做👉优先级-Specificity,这个优先级是针对选择器的,不同的选择器有不同的优先级,如果是同一个优先级的选择器,它们内部的对于各种属性的设定,才会遵从后面覆盖前面的这样的规则,但是如果是写在前面的反而有更高的优先级,后面对于同样属性的设定并不会覆盖前面的设定。
关于优先级更详细的讲解,你可以参看这个MDN的教程,我这里只想和大家说几个重要的点:
更精确选择元素的选择器,一般优先级就会更高,比如类名选择器就是元素选择器优先级更高
直接写在html元素上的样式,也就是通过style属性设置的样式,具有最高优先级
不用太在意优先级这个事,了解就好,点到为止,优先级在开发过程中的意义,可能就是当你发现你的样式设定不起作用的时候,能知道大概率是选择器的优先级或者说是层叠的问题
优先级会有一个数值指标,但是这个东西,不需要深入研究,真正的开发也不会去算这个东西,了解就好,你在开发过程中其实会发现,很少会碰到因为优先级导致的问题
还有一个特性就是👉继承,也就是某些设定子元素是会根据html元素结构从父元素上继承,比如常见的字体颜色color属性,关于这个大家也需要去了解一下,MDN上的这篇内容讲的已经比较清晰了。但是其实关于继承,也不用担心,这个特性其实在真正开发中感知并不明显,也很少会主动设置继承的相关属性,如果碰到了继承了不想继承的一些设置,就用CSS对元素进行额外的设定就好了,所以最重要的是要了解这个概念。