# CSS选择器世界

开局一张图,内容全靠浪 😸😸

# CSS 选择器
- 基本选择器
| 选择器 | 类型 | 功能描述 |
|---|---|---|
| * | 通配选择器 | 选择文档中所有HTML元素 |
| E | 元素选择器 | 选择指定类型的HTML元素 |
| #id | ID选择器 | 选择指定ID属性值为“id”的任意类型元素 |
| .class | 类选择器 | 选择指定class属性值为“class”的任意类型的任意多个元素 |
| selector1,selectorN | 群组选择器 | 将每一个选择器匹配的元素集合并 |
- 层次选择器
| 选择器 | 类型 | 功能描述 |
|---|---|---|
| E F | 后代选择器(包含选择器) | 选择匹配的F元素,且匹配的F元素被包含在匹配的E元素内 |
| E>F | 子选择器 | 选择匹配的F元素,且匹配的F元素所匹配的E元素的子元素 |
| E+F | 相邻兄弟选择器 | 选择匹配的F元素,且匹配的F元素紧位于匹配的E元素的后面 |
| E~F | 通用选择器 | 选择匹配的F元素,且位于匹配的E元素后的所有匹配的F元素 |
- 动态伪类选择器
| 选择器 | 类型 | 功能描述 |
|---|---|---|
| E:link | 链接伪类选择器 | 选择匹配的E元素,而且匹配元素被定义了超链接并未被访问过。常用于链接描点上 |
| E:visited | 链接伪类选择器 | 选择匹配的E元素,而且匹配元素被定义了超链接并已被访问过。常用于链接描点上 |
| E:active | 用户行为选择器 | 选择匹配的E元素,且匹配元素被激活。常用于链接描点和按钮上 |
| E:hover | 用户行为选择器 | 选择匹配的E元素,且用户鼠标停留在元素E上。IE6及以下浏览器仅支持a:hover |
| E:focus | 用户行为选择器 | 选择匹配的E元素,而且匹配元素获取焦点 |
- 目标伪类选择器
| 选择器 | 类型 | 功能描述 |
|---|---|---|
| E:target | 目标伪类选择器 | 选择匹配E的所有元素,且匹配元素被相关URL指向 |
- UI元素状态伪类选择器
| 选择器 | 类型 | 功能描述 |
|---|---|---|
| E:checked | 选中状态伪类选择器 | 匹配选中的复选按钮或者单选按钮表单元素 |
| E:enabled | 启用状态伪类选择器 | 匹配所有启用的表单元素 |
| E:disabled | 不可用状态伪类选择器 | 匹配所有禁用的表单元素 |
- 结构伪类选择器
| 选择器 | 功能描述 |
|---|---|
| E:first-child | 作为父元素的第一个子元素的元素E。与E:nth-child(1)等同 |
| E:last-child | 作为父元素的最后一个子元素的元素E。与E:nth-last-child(1)等同 |
| E:root | 选择匹配元素E所在文档的根元素。在HTML文档中,根元素始终是html,此时该选择器与html类型选择器匹配的内容相同 |
| E F:nth-child(n) | 选择父元素E的第n个子元素F。其中n可以是整数(1,2,3)、关键字(even,odd)、可以是公式(2n+1),而且n值起始值为1,而不是0. |
| E F:nth-last-child(n) | 选择父元素E的倒数第n个子元素F。此选择器与E:nth-child(n)选择器计算顺序刚好相反,但使用方法都是一样的,其中:nth-last-child(1)始终匹配最后一个元素,与last-child等同 |
| E:nth-of-type(n) | 选择父元素内具有指定类型的第n个E元素 |
| E:nth-last-of-type(n) | 选择父元素内具有指定类型的倒数第n个E元素 |
| E:first-of-type | 选择父元素内具有指定类型的第一个E元素,与E:nth-of-type(1)等同 |
| E:last-of-type | 选择父元素内具有指定类型的最后一个E元素,与E:nth-last-of-type(1)等同 |
| E:only-child | 选择父元素只包含一个子元素,且该子元素匹配E元素 |
| E:only-of-type | 选择父元素只包含一个同类型子元素,且该子元素匹配E元素 |
| E:empty | 选择没有子元素的元素,而且该元素也不包含任何文本节点 |
- 否定伪类选择器
| 选择器 | 功能描述 |
|---|---|
| E:not(F) | 匹配所有除元素F外的E元素 |
这个伪类选择器以前经常用不好,老是混淆,举个栗子(摘自张鑫旭博客)
<section>
<div>我是一个普通的div标签</div>
<p>我是第1个p标签</p>
<p>我是第2个p标签</p> <!-- 希望这个变红 -->
</section>
p:nth-child(2) { color: red; }
p:nth-of-type(2) { color: red; }
2
3
4
5
6
7
8
这时候两个选择器所渲染的结果就不一样了。 p:nth-child(2) 悲剧了,其渲染的结果不是第二个p标签文字变红,而是第一个p标签,也就是父标签的第二个子元素。如下效果截图:

p:nth-of-type(2)的表现显得很坚挺,其把希望渲染的第二个p标签染红了,如下截图:

对于p:nth-child(2)表示这个元素要是p标签,且是第二个子元素,是两个必须满足的条件。于是,就是第一个p标签颜色为红色(正好符合:p标签,第二个子元素)。如果在div标签后面再插入个span标签,如下:
<section>
<div>我是一个普通的div标签</div>
<span>我是一个普通的span标签</span>
<p>我是第1个p标签</p>
<p>我是第2个p标签</p> <!-- 希望这个变红 -->
</section>
2
3
4
5
6
那么p:nth-child(2)将不会选择任何元素。
而 p:nth-of-type(2)表示父标签下的第二个p元素,显然,无论在div标签后面再插入个span标签,还是h1标签,都是第二个p标签中的文字变红。

# 选择器的权重和优先级
- CSS 三大特性
- 继承性
- 优先级
- 层叠性
优先级的等级:
- 0级(0):通配选择器(*)、选择符(+、>、~、空格、||):not()
- 1级(1):元素、关系、伪元素
- 2级(10):类选择器、属性选择器、伪类
- 3级(100):ID选择器
- 4级(1000):style内联选择器
- 5级(10000):!important

优先级的计算规则:
- 权重顺序 !important > 行内样式 > id选择器 > 类选择器 > 标签选择器 > 通配符 > 继承 > 浏览器默认
选择器权重:
- !important 优先级最高
- 元素属性 优先级高
- 相同权重 后写的生效
# 选择器的命名
驼峰命名法
第一个字母要小写,后面的词的第一个字母就要用大写,例如: studentInfo、navMenuRedButton
帕斯卡命名法
这种命名法同样也是大小写字母混编而成,和骆驼命名法很像,但和骆驼命名法有一点区别,就是所有单词的首字母都要大写,当然也包括第一个单词;例如: StudentInfo、NavMenuRedButton
匈牙利命名法
在名称前面加上一个或多个小写字母作为前缀,来让名称更加好认,更容易理解,例如: head_navigation
页面模块的常用命名
| 头:header | 导航:nav | 菜单:menu | 友情链接:friendlink |
|---|---|---|---|
| 页面外围包裹:wrapper | 子导航:subnav | 子菜单:submenu | 下载:download |
| 页面主体:main | 广告:banner | 侧栏:sidebar | 小技巧:tips |
| 内容:content | 标志:logo | 栏目:column | 滚动:scroll |
| 页脚:footer | 搜索:search | 热点:hot | 上一个:prev |
| 版权:copyright | 登录条:loginbar | 新闻:news | 下一个:next |
BEM命名法
BEM的意思就是块(block)、元素(element)、修饰符(modifier),是由Yandex团队提出的一种前端命名方法论。这种巧妙的命名方法让你的CSS类对其他开发者来说更加透明而且更有意义。BEM命名约定更加严格,而且包含更多的信息,它们用于一个团队开发一个耗时的大项目。
- BEM:块(block)、元素(element)、修饰符(modifier)
- block 代表了更高级别的抽象或组件。
- block__element 代表.block的后代,用于形成一个完整的.block的整体。
- block--modifier代表.block的不同状态或不同版本,用于修饰。
air-table{} /* 块 */
air-table__footer{} /* 元素 */
air-table--full{} /* 修饰符 */
2
3
<template>
<!--wrapper主要用于sass嵌套,以免父(子)组件里的css冲突-->
<div class="air-table(组件名)-wrapper">
<el-table class="air-table"></el-table>
<div class="air-table__footer air-table__footer--full">
<button class="air-table__footer--prev">上</button>
<button class="air-table__footer--next">下</button>
</div>
</div>
</template>
<style lang="scss" scoped>
.air-table(组件名)-wrapper {
.air-table {}
.air-table__footer {
.air-table__footer—prev {}
.air-table__footer—bext {}
&.air-table__footer--full {}
}
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 选择器中的正则表达式
正则表达式字符含义:
- 字符
^表示字符串开始位置匹配;- 字符
$表示字符串结束位置匹配;- 字符
*表示字符串任意位置匹配;- 字符
i表示字符串匹配不区分大小写;- 字符
g表示字符串全局匹配;
CSS属性选择器版本:
- CSS2.1属性选择器:
- 直接匹配: [attr]、[attr="val"]、[attr~="val"]、[attr|="val"]
- CSS3属性选择器:
- 正则匹配:[attr^='val'], [attr$='val'], [attr*='val']
- CSS4属性选择器:
- 忽略大小写匹配: [attr='val' i]
属性选择器
| 选择器 | 功能描述 |
|---|---|
| [attribute] | 用于选取带有指定属性的元素。 |
| [attribute=value] | 用于选取带有指定属性和值的元素。 |
| [attribute~=value] | 用于选取属性值中包含指定词汇的元素。 |
| [attribute | =value] |
| [attribute^=value] | 选择匹配元素E,且E元素定义了属性attr,其属性值以val开头的任何字符串。 |
| [attribute$=value] | 选择匹配元素E,且E元素定义了属性attr,其属性值以val结束的任何字符串。 |
| [attribute*=value] | 选择匹配元素E,且E元素定义了属性attr,其属性值任意位置包含了val。 |
CSS属性选择器分解:
[attr] :
- 只要元素有attr这个属性就可以
<div attr="val"></div> ok
<div attr="text val"></div> ok
<div attr="value"></div> ok
<div attr="val-ue"></div> ok
2
3
4
[attr="val"] :
- 元素的属性名是"attr", 值必须是'val'
<div attr="val"></div> ok
<div attr="text val"></div> no
<div attr="value"></div> no
<div attr="val-ue"></div> no
2
3
4
[attr~="val"] :
- "attr"值需含有单词"val"
<div attr="val"></div> ok
<div attr="text val"></div> ok
<div attr="value"></div> no
<div attr="val-ue"></div> no
2
3
4
[attr|="bar"] :
- "attr" 属性值开头必须是bar的单词,或者开头是bar-
<div attr="bar"></div> ok
<div attr="bar-val"></div> ok
<div attr="barval"></div> no
<div attr="bar val"></div> no
2
3
4
[attr^='val'] :
- 属性值开头三个字符需要是val
<div attr="val"></div> ok
<div attr="text val"></div> no
<div attr="value"></div> ok
<div attr="val-ue"></div> ok
2
3
4
[attr$='val'] :
- 属性值最后三个字符需要是val
<div attr="val"></div> ok
<div attr="text val"></div> ok
<div attr="value"></div> no
<div attr="val-ue"></div> no
2
3
4
[attr*='val'] :
- 属性值任意位置包含val这三个字符就可以
<div attr="val"></div> ok
<div attr="text val"></div> ok
<div attr="value"></div> ok
<div attr="val-ue"></div> ok
2
3
4
[attr*='val' i]:
- 就和正则表达式中的作i用一样,忽略大小写
- 目前Chrome, FireFox, Safari已支持
i正则,但是,IE惊喜过后又打回了原形,包括到IE14都还没支持不区分大小写;
<div attr="VAL"></div> ok
<div attr="Text val"></div> ok
<div attr="Value"></div> ok
<div attr="Val-ue"></div> ok
2
3
4

# AMCSS开发模式简介
它是Attribute Modules for CSS的缩写,表示借助HTML属性来进行CSS相关开发;
AMCSS的官网:
- AMCSS有专门的介绍网站:http://amcss.github.io/
- 优点: 每个属性有效地声明一个单独的命名空间,用于封装样式信息,从而产生更易于阅读和维护的HTML和CSS;
传统类名和AMCSS写法对比:
- 传统写法:
<div class="button button-large button-blue">Button</div>
- AMCSS写法:
<div button="large blue">Button</div>
<div am-button="large blue">Button</div>(避免属性名称冲突)
2
/* 目前主流类名选择器:通过多个类名进行控制 */
.button {...}
.button-large {...}
.button-blue {...}
/* AMCSS则是基于属性控制 */
[am-button] {...}
[am-button~="large"] {...}
[am-button~="blue"] {...}
2
3
4
5
6
7
8
9
- Flexbox Grid
<div class="row reverse">
<div class="column-12--hand column-8--lap">
<div class="box">Responsive</div>
</div>
</div>
<div am-Grid-Row="reverse">
<div am-Grid-Col="12 lap:8">
<div am-Demo="box">Responsive</div>
</div>
</div>
2
3
4
5
6
7
8
9
10
11
# 伪类和伪元素
- 伪类:
- 用于当已有元素处于的某个状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的。比如说,当用户悬停在指定的元素时,我们可以通过:hover来描述这个元素的状态。虽然它和普通的css类相似,可以为已有的元素添加样式,但是它只有处于dom树无法描述的状态下才能为元素添加样式,所以将其称为伪类。
- 伪类存在的意义是为了通过选择器,格式化DOM树以外的信息以及不能被常规CSS选择器获取到的信息。
- 伪元素:
- 用于创建一些不在文档树中的元素,并为其添加样式。比如说,我们可以通过:before来在一个元素前增加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。
- 伪元素可以创建一些文档语言无法创建的虚拟元素。比如:文档语言没有一种机制可以描述元素内容的第一个字母或第一行,但伪元素可以做到(::first-letter、::first-line)。同时,伪元素还可以创建源文档不存在的内容,比如使用 ::before 或 ::after
- 区别:
伪类的操作对象是文档树中已有的元素,而伪元素则创建了一个文档数外的元素。因此,伪类与伪元素的区别在于:有没有创建一个文档树之外的元素> - 伪类本质上是为了弥补常规CSS选择器的不足,以便获取到更多信息;
- 伪元素本质上是创建了一个有内容的虚拟容器
- CSS3中伪类和伪元素的语法不同
- 在CSS3中,已经明确规定了伪类用一个冒号来表示,而伪元素则用两个冒号来表示
- 可以同时使用多个伪类,而只能同时使用一个伪元素
- 伪元素选择器
| 选择器 | 功能描述 |
|---|---|
| first-letter/:first-letter | 设置对象内的第一个字符的样式 |
| first-line/:first-line | 设置对象内的第一行的样式 |
| before/:before | 设置在对象前(依据对象树的逻辑结构)发生的内容。用来和content属性一起使用,并且必须定义content属性 |
| after/:after | 设置在对象后(依据对象树的逻辑结构)发生的内容。用来和content属性一起使用,并且必须定义content属性 |
| :selection | 设置对象被选择时的样式,::selection只能定义被选择时的background-color及color。 |

