前言
最近,在和前端小伙伴聊天中发现,有些同学对css有一种望而却步的赶脚。究其原因,就是因为它的各种属性繁杂多样,属性的用法千奇百怪。大家想做系统学习也找不到对应的方法,只是「机械式」的进行记忆。而没有在脑海中形成对应的「画面」。
想必大家在平时业务开发中,对某个css属性进行查询时,总是打开google然后输入对应的属性,一般都是返回MDN中相关介绍。但是,它们这种介绍都是从原理角度来分析,无法给人一种直观的感受。
所以,既要想系统性的学习并且有一个直观印象,最好的方式就是用图例的方式来「可视化」记忆和总结。
而今天,我们来系统的介绍一下CSS选择器。这块没啥原理可讲,我们只是需要记忆即可,所以这篇文章算是给我或者大家的一篇备忘录。以便以后能够快速查询。
0. 啥是CSS选择器
CSS选择器是用于选择 HTML 元素并为其应用样式的一种机制。
- 选择器允许我们根据元素的类型、属性、位置以及其他特征来选择要样式化的元素,从而实现对网页样式的精确控制。
以下是一些常见的 CSS 选择器及其用途:
- 「元素选择器(Element Selector)」:选择指定类型的 HTML 元素。例如,p 选择所有段落元素。
- 「类选择器(Class Selector)」:选择具有指定类名的元素。以点号(.)开头,后跟类名。例如,.button 选择所有类名为 button 的元素。
- 「ID 选择器(ID Selector)」:选择具有指定 ID 的元素。以井号(#)开头,后跟 ID 名称。例如,#header 选择 ID 为 header 的元素。
- 「后代选择器(Descendant Selector)」:选择指定元素的后代元素。使用空格分隔两个选择器,其中
第一个选择器表示父元素
第二个选择器表示后代元素
例如,div p 选择所有 <div> 元素内部的所有段落 <p> 元素。
- 「相邻兄弟选择器(Adjacent Sibling Selector)」:选择紧接在另一个元素后面的元素。使用加号(+)符号连接两个选择器,其中
第一个选择器表示第一个元素
第二个选择器表示其紧邻的兄弟元素
例如,h2 + p 选择所有紧接在 <h2> 元素后面的 <p> 元素。
- 「通用选择器(Universal Selector)」:选择页面中的「所有元素」。使用星号(*)表示。例如,* 选择页面中的所有元素。
除了这些基本的选择器外,CSS 还提供了许多其他类型的选择器,如伪类选择器(例如 :hover、:active)、伪元素选择器(例如 ::before、::after)、属性选择器(例如 [type="text"])等,可以根据具体的需求选择合适的选择器来对页面元素进行样式化。
1. 通用选择器 - *
CSS的通用选择器是一个星号(*),它匹配文档中的「任何元素」。使用通用选择器,我们可以选择页面上的「所有元素」,并为它们应用相同的样式。
例如,如果我们想为页面上的所有元素设置相同的字体样式,我们可以使用通用选择器来实现。
但要注意,过度使用通用选择器可能会导致「性能问题」,因为它会匹配页面上的所有元素,包括嵌套元素,这可能会增加浏览器的渲染负担。因此,建议在必要时谨慎使用通用选择器。
图片
2. 元素选择器 - element
元素选择器是 CSS 中最简单的选择器之一,它通过指定 HTML 元素的名称来选择元素。例如,要选择所有段落元素 <p>,我们可以使用以下选择器:
p {
/* CSS 样式 */
}
这将选择页面中的所有段落元素,并应用所指定的 CSS 样式。
图片
3. 类名选择器 - .class
类选择器用于选择具有特定类名的 HTML 元素。类选择器以点号(.)开头,后跟类名。例如,如果我们有一个类名为 button 的按钮元素,我们可以使用类选择器来选择它:
.button {
/* CSS 样式 */
}
这将选择页面中所有具有类名 button 的元素,并应用所指定的 CSS 样式。类选择器使我们可以为页面中的「多个元素定义相同的样式」,而不必重复定义。此外,一个元素可以同时具有多个类,这样就可以轻松地将多个样式应用于同一个元素。
图片
4. ID 选择器 - #id
ID 选择器是 CSS 中用于选择具有特定 ID 属性的 HTML 元素的选择器。ID 选择器以井号(#)开头,后跟 ID 名称。
例如,如果我们有一个 ID 为 my-id 的标题元素,我们可以使用 ID 选择器来选择它:
#my-id {
/* CSS 样式 */
}
这将选择页面中具有 ID 名称为 my-id 的元素,并应用所指定的 CSS 样式。「与类选择器不同,ID 选择器应该是唯一的」,因为 HTML 页面中每个元素的 ID 必须是唯一的。ID 选择器通常用于「为特定元素应用唯一的样式」。
图片
5. 多选择器 - .class.class-2
.class.class-2表示连接两个或更多类或ID来选择具有所有指定类/ID的元素:
图片
这段CSS代码的意思是选择具有 .my-class 和 .special 两个类的元素,并设置对应的背景色。
6. 逗号组合 - .class, .class-2
使用逗号分隔多个选择器声明。这样可以轻松地「将相同的样式应用于多个选择器声明」:
图片
7. 后代选择器 - .class .class-2
后代选择器用于「选择特定元素的后代元素」。后代选择器使用「空格分隔两个选择器」,其中
- 第一个选择器表示父元素
- 第二个选择器表示后代元素
例如,如果我们想选择所有 <div> 元素内部的所有段落 <p>,我们可以使用后代选择器:
div p {
/* CSS 样式 */
}
这将选择所有在 <div> 元素内部的 <p> 元素,并应用所指定的 CSS 样式。后代选择器允许我们更精确地定位特定元素,而不受页面结构的限制。
图片
8. 相邻兄弟选择器 - .class + .class-2
相邻兄弟选择器它用于选择「紧接」在另一个元素后面的元素。相邻兄弟选择器使用加号(+)符号来连接两个选择器,其中
- 第一个选择器表示第一个元素
- 第二个选择器表示紧跟在其后的兄弟元素
例如,如果我们想选择所有紧跟在 <h2> 元素后面的段落 <p> 元素,我们可以使用相邻兄弟选择器:
h2 + p {
/* CSS 样式 */
}
这将选择紧接在 <h2> 元素后面的 <p> 元素,并应用所指定的 CSS 样式。相邻兄弟选择器允许我们「根据元素之间的特定关系来选择元素」,从而使得样式的应用更加精确和有针对性。
图片
9. 子选择器 - .class > .class-2
子选择器用于选择特定元素的「直接子元素」。子选择器使用大于号(>)符号来连接两个选择器,其中
- 第一个选择器表示父元素
- 第二个选择器表示其直接子元素
例如,如果我们想选择所有 <ul> 元素下的直接子元素 <li>,我们可以使用子选择器:
ul > li {
/* CSS 样式 */
}
这将选择所有直接位于 <ul> 元素内部的 <li> 元素,并应用所指定的 CSS 样式。
子选择器「只会选择指定元素的直接子元素,而不会选择嵌套在更深层次的子元素」。这使得子选择器非常有用,因为它可以帮助我们更精确地定位特定层次结构的元素,并应用相应的样式。
图片
10. 兄弟选择器 - .class ~ .class-2
兄弟选择器用于「选择与指定元素具有相同父元素且位于其后面的所有兄弟元素」。一般兄弟选择器使用波浪号(~)符号来连接两个选择器,其中
- 第一个选择器表示基准元素
- 第二个选择器表示它的兄弟元素
例如,如果我们想选择所有与 <h2> 元素具有相同父元素且位于其后面的 <p> 元素,我们可以使用一般兄弟选择器:
h2 ~ p {
/* CSS 样式 */
}
这将选择所有与 <h2> 元素具有相同父元素且位于其后面的 <p> 元素,并应用所指定的 CSS 样式。
兄弟选择器允许我们选择与指定元素具有相同父元素且位于其后面的所有兄弟元素,而不仅仅是直接的兄弟元素。
图片
11. 脑残猫头鹰选择器 - * + *
脑残猫头鹰选择器用来描述一种特定的 CSS 模式。它涉及选择多个元素并为它们应用共享样式,从而在网页的各个组件或部分中创建一致的视觉设计。
术语脑残指的是通用选择器(*)与相邻兄弟选择器(+)结合使用的情况。猫头鹰可能指的是 CSS 选择器的形态类似于猫头鹰的头部和眼睛。
以下是“脑残猫头鹰”选择器模式的示例:
* + * {
margin-top: 1.5em;
}
这个 CSS 规则选择了在另一个元素之后出现的任何元素(除了容器中的第一个元素),并在顶部应用了一定的边距,有效地使元素均匀地间隔开来。这种模式特别适用于在为「容器内的元素添加间距,但第一个元素没有前置兄弟元素」。当然,我们也可以使用 :not(:first-child)来达到相同的效果。
图片
12. 属性选择器
属性选择器它允许我们根据元素的属性及其属性值来选择元素,并为其应用样式。属性选择器使用方括号([])表示,内部包含属性名和可选的属性值。
存在性属性选择器
选择具有指定属性的元素,不论其属性值是什么。
[data-text] {
/* CSS 样式 */
}
选择所有具有 data-text 属性的元素,并为其应用样式。这个选择器「不关心属性的值是什么,只要有这个属性就会被选中」
图片
值属性选择器
选择具有指定属性和特定值的元素。
[data-text="hello"] {
/* CSS 样式 */
}
选择所有 data-text 属性的值为 hello 的元素,并为其应用样式。
只有属性值为 hello 的元素才会被选中。
部分值属性选择器
选择具有指定属性,并且属性值包含特定值的元素。
[title*="saur"] {
/* CSS 样式 */
}
选择所有 title 属性值中包含 saur子字符串的元素,并为其应用样式。
只要属性值包含 saur,无论是在开头、中间还是结尾,都会被选中。
图片
起始值属性选择器
选择具有指定属性,且属性值以特定值开头的元素。
a[href^="https://"] {
/* CSS 样式 */
}
选择所有 href 属性值以 https:// 开头的 <a> 元素,并为其应用样式。
只有链接以 https:// 开头的 <a> 元素才会被选中。
图片
结束值属性选择器
选择具有指定属性,且属性值以特定值结尾的元素。
[src$=".png"] {
/* CSS 样式 */
}
选择所有 src 属性值以 .png 结尾的元素,并为其应用样式。
只有图片路径以 .png 结尾的元素才会被选中。
图片
包含值属性选择器
选择具有指定属性,且属性值包含特定值的元素,且值之间以空格分隔。
[class~="active"] {
/* CSS 样式 */
}
选择所有具有包含 active 的类名的元素,并为其应用样式。
这个选择器将选中所有具有 active 类的元素,无论它们的类名是 active 还是 some-active-class 等。
图片
13. link伪类选择器
以下四个伪类用于选择各种状态下的link等元素。这四个伪类通常与链接一起使用,但是 :active 对于button也很有用,而 :hover 可以用于所有类型的元素:
- :link
选择未访问的link。它允许我们为用户尚未点击的超链接设置样式。
- :visited
选择用户已经访问过的link。这个伪类允许我们为以前点击过的超链接应用样式。
- :hover
当用户的指针(例如鼠标光标)悬停在元素(通常是链接)上时,选择这些元素。
- :active
选择在它们被激活时的元素(通常是链接或按钮),例如当用户点击它们时。
14. input相关
在前端项目中,input有很大的用处。我们来看MDN关于input的介绍。
所以,和input相关的选择器也很多。
元素聚焦 - :focus
元素选中 - :checked
:checked 伪类选择器用于选择当前被选中/勾选的单选按钮、复选框或选择元素中的选项。
input[type='checkbox'] {
all: unset;
-webkit-appearance: none;
appearance: none;
margin: 0;
}
input[type='checkbox']:checked + label {
background: mediumseagreen;
}
input[type='checkbox']:focus + label {
box-shadow: 0 0 0 2px yellow;
}
在上面的示例中,我使用 appearance: none 来移除复选框输入框的默认样式
元素禁用 - :disabled
:disabled 伪类匹配「禁用」的表单元素,例如button或input
元素可用 - :enabled
:enabled 伪类匹配可以交互并接收输入的表单元素
元素验证 - :valid
:valid 伪类用于定位具有内容符合其属性规定要求(如 pattern、type 等)的输入元素:
元素验证- :invalid
:invalid 伪类用于定位内容不符合要求的输入元素:
元素必填 - :required
:required 伪类用于定位具有 required 属性的输入元素,表明在提交表单之前必须填写它们:
元素可选 - :optional
:optional 伪类用于定位没有 required 属性的输入元素,表示它们不是必填项:
15. 第N个孩子
第一个孩子 - :first-child
:first-child 伪类用于定位其「父元素内的第一个子元素」:
最后一个孩子 - last-child
:last-child 伪类用于定位其父元素内的最后一个子元素:
第N个孩子 - :nth-child
:nth-child 伪类根据元素在其父元素中的位置进行选择,允许进行各种各样的选择。
:nth-child 还可以让我们按模式选择元素:
- :nth-child(odd) 或 :nth-child(2n+1) 选择「每个奇数位置」的子元素
- :nth-child(even) 或 :nth-child(2n) 选择「每个偶数位置」的子元素
公式中的 n 就像一个计数器,让我们可以在重复循环中选择元素。
第N个孩子(倒数) - :nth-last-child
:nth-last-child 伪类类似于 :nth-child,但它是从「最后一个子元素开始向后计数」的
元素的唯一子元素 - :only-child
如果某个元素是其父元素的「唯一子元素」,则 :only-child 伪类将其作为目标元素:
16. 指定类型的第N个孩子
类型的第一个元素 - :first-of-type
:first-of-type 伪类的目标是其父级中「该类型的第一个元素」:
类型的最后一个元素 - :last-of-type
:last-of-type 伪类的目标是其父级中「该类型的最后一个元素」
类型的第N个元素 - :nth-of-type
:nth-of-type 伪类根据元素的类型和兄弟元素中的位置来匹配元素
类型的第N个元素(向后计数) - :nth-last-of-type
:nth-last-of-type 伪类根据元素的类型和兄弟元素中的位置来匹配元素,但从末尾开始计数
其类型的唯一元素 - :only-of-type
:only-of-type 伪类的目标元素是其兄弟元素中该类型的唯一元素:
17. 伪类选择器
目标元素选择器- .target
:target 伪类选择具有与 URL 片段匹配的 ID 属性的元素(例如:https://example.com/#fragment)。:target 经常用于为直接链接到的页面部分设置样式,通常「与页面内链接一起使用」。
否定伪类 - .not()
:not()函数伪类允许我们定位与指定选择器或条件不匹配的元素。它本质上是一个「过滤器」:
父选择器 - :has()
:has()函数伪类允许在元素包含某个元素或另一个选择器时对其进行样式设置:
其他伪类
- :root:选择文档中最高级别的父元素,通常是 HTML 文档中的 <html> 元素。用于定义 CSS 变量,这些变量将对页面内所有元素可用。
- :is():匹配可以是多个选择器之一的元素,使得长选择器列表更简洁易读。例如,:is(h1, h2, h3) 可以匹配这三个标题元素中的任何一个。
- :where():类似于 :is(),但允许根据条件选择元素,而不影响选择器的特异性。
- :default:匹配设置为其默认选择状态的 UI 元素(例如单选按钮或复选框)。
- :empty:选择没有子元素的元素(包括文本节点)。
- :fullscreen:选择当前以全屏模式显示的元素。
- :in-range:匹配值在指定范围内的表单元素(使用 min 和 max 属性)。
- :out-of-range:匹配值在指定范围之外的表单元素。
- :indeterminate:选择状态不确定的表单元素,例如既不选中也不取消选中的复选框(通常在树形视图结构中看到)。
- :read-only:匹配由于 readonly 属性而无法由用户编辑的表单元素。
- :read-write:选择用户可以编辑的表单元素,意味着它们不是只读的。
- :lang():根据其语言属性匹配元素。例如,:lang(en) 选择用英语定义的元素。
18. 伪元素
第一个子伪元素 - ::before
::before 伪元素用于在元素内容之前插入内容。它可用于添加装饰内容、图标或其他不需要在实际 DOM 中的元素:
最后一个子伪元素 - ::after
::after 伪元素与 ::before 类似,用于在元素内容之后插入内容:
首字母伪元素- ::first-letter
::first-letter 伪元素用于设置块级元素的「第一个字母的样式」,允许使用首字下沉等设计元素:
首行伪元素 - ::first-line
::first-line 伪元素用于设置块级元素第一行的样式。这允许印刷效果可以根据包含元素的大小和字体大小动态调整:
文本输入占位符 - ::placeholder
::placeholder 伪元素用于设置表单字段(如 <input> 和 <textarea>)的占位符文本的样式:
样式突出显示框 - ::selection
::selection 伪元素用于设置元素中已突出显示或由用户选择的部分的样式。例如,当用户单击并拖动以选择文本时,::selection伪元素可用于修改该选择的背景颜色、文本颜色和其他样式:
列表标记伪元素 - ::marker
::marker 伪元素用于设置列表项中标记框的样式,列表项通常包含项目符号(对于无序列表)或数字/字母(对于有序列表)。
在引入 ::marker 伪元素之前,自定义这些标记通常需要解决方法,但这个伪元素给了我们更多的控制权: