CSS 选择器

432 阅读12分钟

前言

CSS中选择器种类不多,但是有些很容易搞混,比如逗号(并集选择器,如div,.one,[title="one"])、空格(后代选择器)、附加到类或ID选择器上的元素名称(交集选择器,如div.box)是不一样的,它们写法上很相近,但含义大不一样。

要彻底搞懂CSS选择器,且看下文!

选择器的种类(8种)

1.全局选择器

也叫做通用选择器,选中了文档中的所有内容,或者是父元素中的所有内容,比如,它紧随在其他元素以及邻代运算符之后的时候。

*{
    margin: 0;
    padding: 0;
 }
 div *{ color: red; }

2.类型选择器

也叫做元素选择器或者标签选择器,用于选中html文档中某一类标签。

div{ color: red; }
span{ font-size: 12px; }

3.类选择器

以一个句点(.)开头,会选择文档中应用了这个类的所有元素。可以通过附加类的欲选元素的类型选择器,限定该类选择器只对该元素有效(交集选择器)。

.box{
    width: 100px;
    height: 100px;
    border: 1px solid black;
}

4.ID选择器

以一个井号(#)开头,选中设定了id的元素,一个 ID 只会用到一次。和类选择器一样,也可以在 ID 前面加上类型选择器,只指向元素和 ID 都匹配的类(交集选择器)。

#content{ color: black; }

5.属性选择器

选中带有特定属性的元素,CSS中有7种属性选择器匹配方式。

  • [attr]:选中拥有attr属性的元素
/* [attr]-选中拥有title属性(即使为空)的a元素 */
a[title]{ color: red; } 
  • [attr=value]:选中attr属性值恰好等于value的元素
/* [attr=value]-选中拥有属性href且值为'https://example.com'的a元素 */
a[href='https://example.com']{ color: yellow; } 
  • [attr~=value]:选中attr属性值包含单词value的元素(单词之间必须用空格隔开)
/* [attr~=value]-选中类名带有special的p元素 */
p[class~='special']{ color: red; } 
  • [attr|=value]:选中attr属性值恰好等于value或以单词value开头后面紧跟连字符-的元素
/* [attr|=value]-选中lang属性值为en或以en开头后面紧跟连字符-(指中间短横线,下划线无效)的div元素 */
div[lang|='en']{ color: green; } 
  • [attr^=value]:选中attr属性值以value开头的元素
/* [attr^=value]-选中class属性值以box-开头的div元素 */
div[class^='box-']{ color: blueviolet; } 
  • [attr$=value]:选中attr属性值以单词val结尾的元素
/* [attr$=value]-选中class属性值以-box结尾的div元素 */
div[class$='-box']{ color: aquamarine; } 
  • [attr*=value]:选中attr属性值包含单词value的元素
/* [attr*=value]-选中class属性值包含box的div元素 */
div[class*='box']{ color: blue; } 

6.伪类选择器

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

  • :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或其它form元素
  • :target:匹配当前 URL 目标的元素
  • :visited:匹配已访问链接
  • :autofill:浏览器自动填充表单中的 <input> 元素的值时匹配该 input 元素,如果用户编辑了该字段,则该类将不再匹配
  • :buffering:用于在元素正在加载内容时显示一个加载动画或占位符,该伪类会应用到该元素上,并在元素的内容加载完成后自动移除
  • :defined:表示任何已定义的元素,包括任何浏览器内置的标准元素以及已成功定义的自定义元素
  • :fullscreen:匹配当前处于全屏模式的所有元素
  • :host:选择内部使用了该 CSS 的影子DOM的影子宿主
  • :modal:表示一个元素,该元素处于排除与它之外的元素的所有交互的状态,直到它被解除
  • :muted:匹配被静音的 audiovideo 元素
  • :picture-in-picture:匹配当前处于画中画模式的元素
  • :popover-open:表示处于显示状态的弹出窗口元素(即带有弹出窗口属性的元素)
  • :seeking:匹配可播放的元素正在寻找媒体资源中的播放位置时
  • :stalled:匹配视频、音频或其他媒体资源加载过程中发生了错误或者被中断时
  • :target-within:用于选择当前 URL 中的目标元素的父级元素。它只能与锚点链接a元素一起使用,并且只有在点击锚点链接时才会生效
  • :user-invalid:匹配用户交互后未通过自定义表单验证的表单元素
  • :user-valid:表示通过自定义表单验证的表单元素,用户交互仅匹配一次
  • :volume-locked:匹配媒体元素(如音频或视频)的音量被锁定的元素
  • :has():它指定一个元素,该元素至少有一个与作为参数传递的相对选择器匹配的元素
  • :where():接受选择器列表作为它的参数,匹配所有能被该选择器列表中任何一条规则选中的元素
  • :host():选择包含使用这段 CSS 的 影子DOM的影子宿主
  • :host-context():选择内部使用了该 CSS 的影子DOM的影子宿主

7.伪元素选择器

伪元素以类似伪类的方式表现,不过表现得是像你往标记文本中加入全新的 HTML 元素一样,而不是向现有的元素上应用类。伪元素开头为双冒号::,一些早期的伪元素曾使用单冒号的语法,现代的浏览器为了保持后向兼容,支持早期的带有单双冒号语法的伪元素。

  • ::after:匹配出现在原有元素的实际内容之后的一个可样式化元素
  • ::before:匹配出现在原有元素的实际内容之前的一个可样式化元素
  • ::first-letter:匹配元素的第一个字母
  • ::first-line:匹配包含此伪元素的元素的第一行
  • ::grammar-error:匹配文档中包含了浏览器标记的语法错误的那部分
  • ::selection:匹配文档中被选择的那部分
  • ::spelling-error:匹配文档中包含了浏览器标记的拼写错误的那部分
  • ::backdrop:匹配任何处于全屏模式的元素下的即刻渲染的盒子
  • ::cue:匹配所选元素中的WebVTT提示
  • ::cue-region:匹配选定元素中的WebVTT线索
  • ::file-selector-button:匹配type="file"的<input>的按钮
  • ::marker:匹配列表的标记框,它作用在任何设置了 display: list-item 的元素或伪元素上,例如 <li><summary> 元素
  • ::placeholder:匹配一个表单元素的占位文本
  • ::target-text:匹配浏览器在支持文本片段技术时所滚动到的文字
  • ::view-transition:匹配已滚动到的文本
  • ::view-transition-group:表示单个视图转换组
  • ::view-transition-image-pair:表示视图转换的"旧"和"新"视图状态(转换之前和之后)的容器
  • ::view-transition-new:表示视图转换的"新"视图状态 - 转换后新视图的实时表示
  • ::view-transition-old:表示视图转换的"旧"视图状态 - 转换之前旧视图的静态屏幕截图
  • ::highlight():当用户选中文本时,浏览器会在选中的文本上添加一个默认的高亮效果,此 伪元素可以对这个高亮效果进行自定义样式的设置
  • ::part():表示在阴影树中任何匹配 part 属性的元素
  • ::slotted():用于选定那些被放在 HTML 模板中的元素

8.关系选择器

这类选择器在其他选择器之间和其他选择器与文档内容的位置之间建立了一种有用的关系,关系选择器有5种。

  • 后代选择器(空格):选择指定元素下的子元素,包括直接和间接子元素
.father .son{ color: palegreen; }
  • 子代选择器(>):选择指定元素下的直接子元素,不包括间接子元素
.father>.son{ color: palegreen; }
  • 兄弟选择器(+、~):+选择某元素后面紧挨的兄弟元素,~选择某元素后面的兄弟元素,不需要紧挨
.first+div{color: blueviolet;}
.first~div{color: blueviolet;}
  • 交集选择器(附加到类或ID选择器上的元素组合):选择同时符合多个条件的元素
p.content{ color: red; }   
p#content{ color: black; }
  • 并集选择器(逗号):针对不同的选择条件,全部选中
div,p,span{ color: aquamarine; }

选择器的使用

最后的目的是为了更好的使用它们,下面列出了一些实践经验,供大家参考:

  1. 大多数情况下,给一个元素加个类而不是使用 ID,会更好。因为ID 所指特定,会优先于大多数其他选择器,所以很难处理它们。
  2. 绝大部分场景,使用类型、类、ID选择器已经可以满足要求,少部分场景使用属性选择器,极少部分场景用伪类和伪元素更方便。
  3. 尽量使用ID选择器和类选择器,避免使用标签选择器,因为标签选择器会影响性能。
  4. 本质上,伪类与伪元素是为了弥补常规CSS选择器的不足,以便获取到更多信息,有一些应用场景使用伪类和伪元素特别方便。
  5. 使用子选择器和后代选择器时,要注意选择器的层级不要太深,不要超过3级。
  6. 避免使用通配符选择器,因为它会匹配页面上的所有元素,影响性能。

选择器的权重

大家请看 《CSS 属性计算过程》

总结

笔者在整理了CSS选择器之后,感觉自己还远远没有掌握它们,特别是对于伪类与伪元素这块知之甚少。

经过反思过后,我觉得原因是因为以上都是基于理论的,即使做了知识体系,大脑也很快把这块知识忘掉了

学习不只是一堆知识的堆积,更是对知识的理解与联结,这就需要结合实践。

笔者认为,实践是最快的一种学习方式,要想彻底掌握以上内容,还需敲上几百几千几万行代码,在工作应用场景下经常使用才行!

希望对大家有用,有关CSS其它理论和实践知识,请看这里《CSS》