2.1. 标签选择器
2.1.1 通用选择 *
通用选择器 * 大家应该都比较熟悉了,最常用的就是 *{margin:0; box-sizing:border-box;}。mragin:0咱们在上一节已经说过,box-sizing:border-box将在后面的盒子模型那块再详细描述。
例如,我们在检测bootstrap3的样式时,也可以看到它用到了 * 选择器:
2.1.2 单标签
单标签选择器是最基础的css知识了,在上一节的浏览器默认样式中,到处都用了单标签选择。这里不再赘述,css基础薄弱的朋友,可以先去补补课。
2.1.3 多标签
多标签选择器一般和html上下文有关,它有以下集中分类
- 选择一个祖先的所有子孙节点,例如 div p{…}
- 选择一个父元素的所有直属节点,例如 div > p{…}
- 选择某一个元素紧挨着的兄弟节点,例如 li + li{…}
- 选择某一个元素的所有同胞节点,例如 span ~ a{…}
- 以上各种情况的组合应用(不要组合过于复杂,编码讲求可读性第一)
给大家列举一个比较典型的应用,如下图
上图中的效果应该比较常见,在各个菜单之间加下划线。我之前的实现是:每个li都加一个border-bottom,在把最后一个li的border-bottom去掉。
其实完全没必要这样麻烦,下面一个样式设置即可解决:
有点意思吧?
2.2. 属性选择器
2.2.1 特殊1:id选择器
基础知识,不再赘述。
按照许多css教程上讲的,id选择器和属性选择器是不同的两个类别,为什么要把id选择器放在属性选择器下面的呢?因为css选择器是根据html节点的特性来设置的,id也是一个属性,只是它是一个比较特殊的属性,每个html节点的id不能重复。
由于特殊,而且比较常用,所以就单独给id选择器一个“#”,本质上就是一个属性选择器。下面两行代码的执行效果完全相同:
2.2.2 特殊2:class选择器
基础知识,不再赘述。
class也是一个特殊的属性,之所以把它放在属性选择器下,和上文将的id一样。
2.2.3 属性选择器
属性选择器有两种情况:
- 只通过属性名选择:img[title]{… }
- 通过属性名和属性值选择:input[type=’text’]{…}
这两个也是比较基础的,再次也就不再详细展开了,不了解的朋友可以去看看基础教程补补课。
3. 伪类和伪元素
上文提到了若干种选择器类型,伪类和伪元素可针对任何一种选择器使用。
3.1. 伪类
伪类分为UI伪类和结构化伪类。
3.1.1 UI伪类
UI伪类都比较简单常用,我下面简单写几句代码,就不再详细说了。
3.1.2 结构化伪类(IE低版本不行)
先问大家一个问题:如何实现一个表格间隔显示背景颜色,如图:
最简单的方式莫过于使用结构化伪类,一句样式设置即可实现。
结构化伪类有如下书写选项,至于什么意思,从字面意思即可理解:
3.2. 伪元素
记住,伪元素是一个非常重要的概念!其中,:before和:after 非常常用。
首先,咱们先看看:before和:after是怎么回事儿。
上图中,我们可以看到,可以为元素前后添加内容。这里的“内容”还可以写成unicode编码的方式,如下图:
另外,除了可以添加内容外,你还可以自定义执行内容的样式,如下图:
以上大体了解了两者的基本用法,下面给家介绍两个典型的应用场景:
第一,大家都知道fontAwesome吧,web最流行的icon字体库。这些小图标的应用就是通过伪元素来实现的,如下图:
(不知道fontAwesome也没关系,我们在讲到css字体时,会详细介绍)
第二,清除浮动的样式大家都知道吧?这就是一个很典型的伪元素应用场景:
(在讲到css浮动时,会专门讲解clearfix)
4. 选择器的扩展
选择器本来是css的一种规则,用于为css选择html节点的。但是聪明的人类还是通过选择器创造出了其他领域非常伟大的作品。
- jQuery
jQuery被推广流行的根本原因就是它的“Query”——基于css选择器的“Query”。现在的浏览器都支持querySelectAll()方法了,其实这就是W3C“抄袭”的jQuery的设计。
相信各位web前端人员对jquery都比较熟悉了,这里点一下即可。
- zen-Coding
jquery可以通过一段css选择器表达式从既有的html结构中选择符合表达式的dom组,但是zen-coding反其道而行之——可以根据css选择器表达式创造出html节点。不得不佩服这帮人的创造力。
如果你还没用过zen-coding,无论你以后用不用,建议你也一定要去体验一下!
5. 引言
上一节《css知多少(5)——选择器》最后提到,选择器类型过多将导致一些问题,是什么问题呢?咱们直接举例子说明。
上图中,css中的两个选择器都是针对<span>的,而且两个设置的颜色不一样,这里的<span>到底听从谁的命令?
上面还是比较简单的,下面在来一个复杂的:
上图中的<li>该显示成什么颜色呢?
6. 特指度
要解决以上问题,我们需要引入一个概念——特指度(specificity)。特指度表示一个css选择器表达式的重要程度,可以通过一个公式来计算出一个数值,数越大,越重要。
这个计算叫做“I-C-E”计算公式,
- I——Id;
- C——Class;
- E——Element;
即,针对一个css选择器表达式,遇到一个id就往特指度数值中加100,遇到一个class就往特指度数值中加10,遇到一个element就往特指度数值中加1。
下面举几个css表达式的特指度计算结果,大家也自己算一算,是不是对:
CSS选择器表达式 | 特指度计算结果 |
p | 1 |
p.large | 11 |
P#large | 101 |
div p#large | 102 |
div p#large ul.list | 113 |
div p#large ul.list li | 114 |
还有一个重点要注意:!important优先级最高,高于上面一切。* 选择器最低,低于一切。
好了,你现在可以返回文章一开始提出的两个问题,根据特指度计算公式计算,哪个的计算结果大,浏览器就会以哪个为优先。
7. 简版规则
如果你嫌上面的计算过于复杂,有一个简版规则。它只有三个规则,这三个规则能覆盖大多数情况,而且比较好记。
规则一,包含ID的选择器胜过包含Class的选择器,包含Class的选择器胜过包含元素的选择器;例如下图,第一个特指度更高:
规则二,不同选择器的特指度比较时,不区分加载的顺序(相同选择器在层叠时,后加载的覆盖前加载的),例如下图,虽然后加载,但是特指度低:
规则三,设置的样式高于继承的样式,不用考虑特指度。例如:
其实,大部分情况下,你通过这个简版的规则,即可判断选择器的优先级。
8. 总结
本节的内容是一个重点,我在许多的面试题中看到过考css优先级的问题。css优先级并不麻烦,只要你掌握了合适的方法来学习,一晚上就入门个差不多,祝君好运。