前言
CSS的选择器,对开发人员来说既熟悉又陌生,熟悉是因为天天在使用,陌生是由于要灵活到位的运用CSS3的选择器,还是一定的难度,特别是CSS3中的:nth选择器。那么从现在开始我们先丢开他们版本的区别,从头一起来看看CSS选择器的运用。
CSS是一种用于屏幕上渲染html,xml等一种语言,CSS主要是在相应的元素中应用样式,来渲染相对应用的元素,那么这样我们选择相应的元素就很重要了,如何选择对应的元素,此时就需要我们所说的选择器。选择器主要是用来确定html的树形结构中的DOM元素节点。我把CSS选择器分开成三部分,第一部分是我们常用的部分,我把他叫做基本选择器和组合选择器;第二部分我把他称作是属性选择器,第三部分我把他称作伪类选择器,这一部分也是最难理解和掌握的部分。我们先来看一个常用的选择器列表图和选择器的分类图
一、基本选择器
1.1、通配符选择器(*)
通配符选择器用来选择所有的元素,也可以选择某个元素下的所有元素。如:
* {
margin:0;
padding:0;
}
上面代码大家在reset样式文件中看到的肯定不少,他所表示的是,所有元素的margin和padding都设置为0,另外一种就是选择某个元素下的所有元素:
.demo * {border:1px solid blue;}
1.2、标签(元素)选择器(E)
标签选择器使用也很简单,它用于指定HTML文档中特定标签元素的样式
ul{
list-style:none;
}
▲ 这里使用元素选择器选择ul
元素并去除列表前面的默认圆点
1.3、类选择器(.class)
类选择器是最常用的一种选择器,使用时需要在HTML文档元素上定义类名,然后与样式中的.className
相匹配,它一次定义后,在HTML文档元素中是可以多次复用的。
CSS
.menu {
margin:0 auto;
}
HTML
<div class="menu"></div>
类选择器还可以结合元素选择器来使用,假设文档中有两个元素都使用了.menu
类名,但是你只想选择div
元素上类名为.menu
的元素
CSS
div.menu {
margin:0 auto;
}
HTML
<div class="menu"></div>
<ul class="menu"></ul>
类选择器支持多类名使用,比如.menu.active
这个选择器只对元素中同时包含了menu
和active
两个类才会起作用
CSS
.menu {
margin:0 auto;
}
.menu.active {
font-weight:bold;
}
HTML
<div class="menu active"></div>
不过多类选择器.className1.className2
在 IE6+以上才支持,关于浏览器对CSS选择器的支持会下面的内容统一整理列出表格。
类选择器还可以结合元素选择器来使用,比如说,你文档中有好多个元素使用了类名“items”,但你只想在p元素这个类名上修改样式,那么你可以这样进行选择并加上相应的样式:
p.items {color: red;}
上面代码只会匹配class 属性包含items的所有p 元素,但其他任何类型的元素都不匹配,包括有“items”这个类名的元素,上面也说过了“p.items”只会对p元素并且是其有一个类名叫“items”。不符合这两个条件的都不会被选择。
1.4、id选择器(#id)
id选择器与上面的类选择器使用很相似,通过在HTML文档中添加ID名称,然后与样式中的#id
相匹配,不过两者的最大的区别在于,ID选择器是一个页面中唯一的值,不可多次使用,而class选择器是可以多次复用的。
CSS
.menu {
margin:0 auto;
}
HTML
<div class="menu"></div>
类选择器还可以结合元素选择器来使用,假设文档中有两个元素都使用了.menu
类名,但是你只想选择div
元素上类名为.menu
的元素
二、组合(层次/关系)选择器
2.1、群组(并集)选择器(selector1,selector2,...,selectorN)
群组选择器是将具有相同样式的元素分组在一起,每个选择器之间使用逗号“,”隔开,如selector1,selector2,...,selectorN。这个逗号告诉浏览器,规则中包含多个不同的选择器,如果不有这个逗号,那么所表达的意就完全不同了,省去逗号就成了后面所说的后代选择器,这一点大家在使用中千万要小心加小心。著作权归作者所有。
CSS
a:active,a:hover {
outline: 0;
}
▲ 这里统一去掉了a
链接在点击和浮动时的虚线焦点框。
2.2、交集选择器(selector1,selectorN)
交集选择器”由两个选择器直接连接构成,其结果是选中各自元素范围的交集。交集选择器只能交2个,其中第1个是标记,第2个是类选择器或者ID选择器,之间不能有空格。
用法参见类选择器中的多类选择器和类选择器元素选择器结合使用的用法
2.3、后代选择器(E F)
后代选择器是最常使用的选择器之一,它也被称作包含选择器,用于匹配所有被E
元素选择器包含的F
元素,这里F
元素不管是E
元素的子元素或者是孙元素或者是更深层次的关系,都将被选中。
CSS
.menu li{
padding:0 ;
}
HTML
<ul id="menu">
<li>
<ul>
<li></li>
</ul>
</li>
</ul>
▲ 这里.menu
下的li
元素和嵌套的ul
元素下的li
的元素都会被选择,进行清楚内边距。
2.4、子选择器(E>F)
子元素选择器只能选择某元素的子元素,这里的F
元素仅仅是E
元素的子元素才可以被选中
CSS
.menu > li{
padding:0 ;
}
HTML
<ul id="menu">
<li>
<ul>
<li></li>
</ul>
</li>
</ul>
▲ 将会对.menu
下的li
子元素选中,但会忽视内部嵌套的li
元素
2.5、相邻兄弟选择器(E>F)
相邻兄弟选择器可以选择紧接在另一元素后的元素,但是他们必须有一个相同的父元素。比如E
元素和F
元素具有一个相同的父元素,而且F
元素在E
元素后面,这样我们就可以使用相邻兄弟元素选择器来选择F
元素。
CSS
h1 + p {
margin-top:5px;
}
HTML
<div>
<h1>标题</h1>
<p>内容</p>
</div>
▲ 将会选择h1
元素后面的兄弟元素p
2.6、通用兄弟选择器(E~F)
通用兄弟元素选择器是CSS3新增加一种选择器,用于选择某元素后面的所有兄弟元素。它和相邻兄弟元素选择器用法相似,但不同于前者只是选择相邻的后一个元素,而通用兄弟元素选择器是选择所有元素。
CSS
h1 ~ p {
margin-top:5px;
}
HTML
<div>
<h1>标题</h1>
<p>内容</p>
<p>内容</p>
<p>内容</p>
</div>
▲ 将会选择h1
元素后面的所有的兄弟元素p
三、属性选择器
选择器 | 含义 |
E[attr] | 匹配所有具有属性attr的元素,div[id]就能取到所有有id属性的div |
E[attr=value] | 匹配属性attr值为value的元素,div[id=test],匹配id=test的div |
E[attr~=value] | 匹配所有属性attr具有多个空格分隔、其中一个值等于value的元素 |
E[attr|=value] | 匹配所有att属性具有多个”-”分隔、其中一个值以value开头的元素,主要用于lang属性,比如“en”、“en-us” |
E[attr^=value] | 匹配属性attr的值以value开头的元素 |
E[attr$=value] | 匹配属性attr的值以value结尾的元素 |
E[attr*=value] | 匹配属性attr的值包含value的元素 |
3.1、E[attr]
E[attr]
属性选择器是CSS3属性选择器最简单的一种,用于选择具有att
属性的E
元素。
CSS
img[alt] {
margin: 10px;
}
HTML
<img src="url" alt="" />
<img src="url" />
▲ 将会选择到第一张图片,因为匹配到了alt属性,你也可以使用多属性的方式选择元素
img[src][alt] {
margin: 10px;
}
3.2、E[attr=value]
E[attr="value"]
是指定了属性值value
,从而缩小了范围可以更为精确的查找到自己想要的元素。
CSS
input[type="text"] {
border: 2px solid #000;
}
HTML
<input type="text" />
<input type="submit" />
▲ 将会选择到type="text"
表单元素。
3.3、E[attr~=value]
如果你要根据属性值中的词列表的某个词来进行选择元素,那么就需要使用这种属性选择器:E[attr~="value"]
,你会发现它和E[attr="value"]
极为的相似,但是两者的区别是,属性选择器中有波浪(~
)时属性值有value
时就相匹配,没有波浪(~
)时属性值要完全是value
时才匹配。
CSS
div[class~="a"] {
border: 2px solid #000;
}
HTML
<div class="a">1</div>
<div class="b">2</div>
<div class="a b">3</div>
▲ 将会选择到第1、3个div
元素,因为匹配到了class
属性,且属性值中有一个值为a
3.4、E[attr^=value]
E[attr^="value"]属性选择器,指的是选择attr
属性值以“value”
开头的所有元素
CSS
div[class^="a"] {
border: 2px solid #000;
}
HTML
<div class="abc">1</div>
<div class="acb">2</div>
<div class="bac">3</div>
▲ 将会选择到第1、2个div
元素,因为匹配到了class
属性,且属性值以a
开头
3.5、E[attr$=value]
E[attr$="value"]
属性选择器刚好与E[attr^="value"]
选择器相反,这里是选择attr
属性值以"value"结尾的所有元素。
CSS
div[class$="c"] {
border: 2px solid #000;
}
HTML
<div class="abc">1</div>
<div class="acb">2</div>
<div class="bac">3</div>
▲ 将会选择到第1、3个div
元素,因为匹配到了class
属性,且属性值以c
结尾
3.6、E[attr*=value]
E[attr*="value"]
属性选择器表示的是选择attr
属性值中包含"value"
字符串的所有元素。
CSS
div[class*="b"] {
border: 2px solid #000;
}
HTML
<div class="abc">1</div>
<div class="acb">2</div>
<div class="bac">3</div>
▲ 将会选择到所有的元素,因为匹配到了class
属性,且属性值都包含了b
3.7、E[attr|="val"]
E[attr|="val"]
是属性选择器中的最后一种,它被称作为特定属性选择器,这个选择器会选择attr
属性值等于value
或以value-
开头的所有元素。
CSS
div[class|="a"] {
border: 2px solid #000;
}
HTML
<div class="a-test">1</div>
<div class="b-test">2</div>
<div class="c-test">3</div>
▲ 将会选择第1个div
元素,因为匹配到了class
属性,且属性值以紧跟着"a-"
的开头
四、伪类选择器
4.1、动态伪类选择器
选择器 | 类型 | 功能描述 |
E:link | 链接伪类选择器 | 选择匹配的E元素,而且匹配元素被定义了超链接并未被访问过。常用于链接描点上 |
E:visited | 链接伪类选择器 | 选择匹配的E元素,而且匹配元素被定义了超链接并已被访问过。常用于链接描点上 |
E:active | 用户行为选择器 | 选择匹配的E元素,且匹配元素被激活。常用于链接描点和按钮上 |
E:hover | 用户行为选择器 | 选择匹配的E元素,且用户鼠标停留在元素E上。IE6及以下浏览器仅支持a:hover |
E:focus | 用户行为选择器 | 选择匹配的E元素,而且匹配元素获取焦点 |
一般动态伪类是在用户操作体验时触发的,最常见的就是超链接,它拥有访问前,鼠标悬停,被点击,已访问4种伪类效果。
.demo a:link {color:gray;}/*链接没有被访问时前景色为灰色*/
.demo a:visited{color:yellow;}/*链接被访问过后前景色为黄色*/
.demo a:hover{color:green;}/*鼠标悬浮在链接上时前景色为绿色*/
.demo a:active{color:blue;}/*鼠标点中激活链接那一下前景色为蓝色*/
不过在使用时的时候,一定要注意书写的顺序,不然在不同的浏览器中会带来一些意想不到的错误。
a:link {}
a:visited {}
a:hover {}
a:active {}
最可靠的记忆顺序就是遵循爱恨原则:l(link)ov(visited)e h(hover)a(active)te, 即用喜欢(love)和讨厌(hate)两个词来概括。
还有一个用户行为的动态伪类:focus
,常用于表单元素(触发onfocus事件发生)时的样式。
input[type="text"]:focus{
border: 2px solid #000;
}
▲ 当用户聚焦到输入框内,会给输入框添加一个边框颜色。
4.2、UI元素(表单)状态伪类选择器
我们把以下3种状态称作表单状态伪类,你会发现这些关键字就是HTML表单元素的属性,checked
用于type="radio"
和type="checkbox"
够选中状态,disabled
用于type="text"
禁用的状态,而enabled
这里表示type="text"
可用的状态。
E:checked
匹配用户界面上处于选中状态的元素EE:enabled
匹配用户界面上处于可用状态的元素EE:disabled
匹配用户界面上处于禁用状态的元素E
CSS
input[type="text"]:enabled {
background: #fff;
}
input[type="text"]:disabled{
background: #eee;
}
input:checked + span {
background: red;
}
HTML
<input type="text" value="可用状态" />
<input type="text" value="可用状态" />
<input type="text" value="禁用状态" disabled="disabled" />
<input type="text" value="禁用状态" disabled="disabled" />
<label><input type="radio" name="radio" /><span>黑色</span></label>
▲ 将会给可用状态的文本框设置为白色(#fff
)背景,禁用状态设置为灰色(#eee
)背景,如果你选中了radio
,它兄弟元素span
的文本会变成红色
4.3、结构伪类选择器
选择器 | 功能描述 |
E:fisrt-child | 作为父元素的第一个子元素的元素E。与E:nth-child(1)等同 |
E:last-child | 作为父元素的最后一个子元素的元素E。与E:nth-last-child(1)等同 |
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-tye | 选择父元素内具有指定类型的最后一个E元素,与E:nth-last-of-type(1)等同 |
E:only-child | 选择父元素只包含一个子元素,且该子元素匹配E元素 |
E:only-of-type | 选择父元素只包含一个同类型子元素,且该子元素匹配E元素 |
E:root | 选择匹配元素E所在文档的根元素。在HTML文档中,根元素始终是html,此时该选择器与html类型选择器匹配的内容相同 |
E:empty | 选择没有子元素的元素,而且该元素也不包含任何文本节点 |
4.3.1、E:first-child 和 E:last-child
E:first-child
是用来选择父元素的第一个子元素E,但是它必须为父元素的第一个子元素,不然会失效,举例说明
CSS
p:first-child {
color:red;
}
HTML
<div>
<h1>标题</h1>
<p>段落</p>
</div>
▲ 你会发现p
元素的字体并没有变为红色,因为p
元素前面还有个h1
,它并不是父元素下的第一个子元素。
<div>
<p>段落</p>
</div>
▲ 这时需要改变结构,效果才会正常。
而E:last-child
与E:first-child
选择器的作用类似,不同的是E:last-child
选择是的元素的最后一个子元素。
CSS
p:last-child {
color:red;
}
HTML
<div>
<h1>标题</h1>
<p>段落</p>
</div>
▲ 将p
元素的字体设置为红色
4.3.2、E:nth-child(n) 和 E:nth-last-child(n)
E:nth-child(n)
用于匹配父元素的第n个子元素E,假设该子元素不是E,则选择符无效。我们可以按这种方式进行选择:
:nth-child(length);/*参数是具体数字*/
:nth-child(n);/*参数是n,n从0开始计算*/
:nth-child(n*length)/*n的倍数选择,n从0开始算*/
:nth-child(n+length);/*选择大于length后面的元素*/
:nth-child(-n+length)/*选择小于length前面的元素*/
:nth-child(n*length+1);/*表示隔几选一*/
//上面length为整数
该选择符允许使用一个乘法因子(n)来作为换算方式,比如说,我需要选择列表中的第2个li元素,那么我们可以直接这样使用:如下:
li:nth-child(2) { background:#fff}
▲ 选择第2个标签
li:nth-child(n) {background: lime;}
/*等效于*/
li {background: lime;}
▲ :nth-child(n),其中n是一个简单的表达式,那么"n"取值是从“0”开始计算的,到什么时候结束我也不知道,如果你在实际应用中直接这样使用的话,将会选中所有子元素,比如说,你在li中使用":nth-child(n)",那么将选中所有的"li",如:
li:nth-child(n+4) { background:#fff}
▲ 选择大于等于4的所有li标签,“n”表示从整数0开始计算
li:nth-child(-n+4) { background:#fff}
▲ 选择小于等于4的所有li标签
li:nth-child(2n) { background:#fff}
/*等效于*/
li:nth-child(even) { background:#fff}
▲ 选择偶数标签,2n也可以是even
li:nth-child(2n-1) { background:#fff}
/*等效于*/
li:nth-child(odd) { background:#fff}
▲ 选择奇数标签,2n-1也可以是odd
li:nth-child(3n+1) { background:#fff}
▲ 自定义选择标签,3n+1表示“隔二取一”
而E:nth-last-child(n)
又要开始反着来了,CSS3选择器有正就有反
li:nth-last-child(3) { background:#fff}
▲ 选择倒数第3个标签
4.3.3、E:first-of-type 和 E:last-of-type
E:first-of-type
的使用方法类似于我们上面讲过的E:first-child
,其实区别很简单::nth-of-type为什么要叫:nth-of-type?因为它是以"type"来区分的。也就是说:ele:nth-of-type(n)是指父元素下第n个ele元素, 而ele:nth-child(n)是指父元素下第n个元素且这个元素为ele,若不是,则选择失败。 这里我们来看两个小例子:
例子一:
<div>
<ul class="demo">
<p>zero</p>
<li>one</li>
<li>two</li>
</ul>
</div>
上面这个例子,.demo li:nth-child(2)选择的是<li>one</li>节点,而.demo li:nth-of-type(2)则选择的是<li>two</li>节点。
例子二:
CSS
p:first-child {
color:red;
}
p:first-of-type {
color:green;
}
HTML
<div>
<h1>标题</h1>
<p>段落</p>
<p>段落</p>
<div></div>
</div>
▲ 你会发现第一个p
元素的字体被设置为红色,第二个p
元素的字体被设置为绿色,这就是E:first-of-type
和E:first-child
不同之处。
4.3.4、E:nth-of-type(n) 和 E:nth-last-of-type(n)
这两个选择器的用法类似于:nth-child(n)
和E:nth-last-child(n)
,关于区别也是选择器只会选择同类型的兄弟元素,举个栗子
p:nth-child(3) {
color:red;
}
<div>
<p>第1个p</p>
<p>第2个p</p>
<span>第1个span</span>
<p>第3个p</p>
<span>第2个span</span>
<p>第4个p</p>
<p>第5个p</p>
</div>
▲ 如果使用:nth-child(3)
你会发现第3个p
元素文本并没有变成红色。就像我们之前说的,如果第n个子元素不是E,则是无效选择符,但n会递增。
p:nth-of-type(3) {
color:red;
}
▲ 但是使用:nth-of-type(3)
后会发现第3个p
元素文本被设置为红色。
4.3.5、E:only-child 和 E:only-of-type
E:only-child用来表示的是元素E是它的父元素的唯一一个子元素,而E:only-of-type是表示一个元素它有很多个子元素,
但是其中子元素E只有一个,说起来有点绕口,来个栗子
HTML
<div>
<p>段落</p>
</div>
<div>
<div>容器</div>
<p>段落</p>
<div>容器</div>
</div>
p:only-child {
color: red;
}
▲ 将会对第1个div
元素下的p
元素文本设置成红色。
p:only-of-type {
color: red;
}
▲ 不仅会第1个div
元素下的p
元素文本设置成红色,也会对第2个div
元素下的p
元素文本设置成红色,因为它是p元素在div
元素下唯一的一个。
4.3.6、E:root
E:root
选择器用匹配E元素所在文档的根元素。在HTML中根元素始终是HTML元素。
:root
{
background:#ff0000;
}
▲ 设置HTML文档的背景色:
4.3.7、E:empty
E:empty
是用来选择没有任何内容的元素,包括text节点,也就是意味着连一个空格都不能有
HTML
<div>
<p> </p>
<p></p>
</div>
CSS
p:empty {
height: 100px;
}
▲ 将会对第2个空元素p
设置一个高度,为什么第一个会失效呢,因为该容器里面有一个空格。
4.4、否定伪类选择器(:not)
E:not(s)
和jq中的:not选择器一模一样,用于匹配不含有s选择符的元素E,比如我们要对ul
元素下的所有li
都加上一个下边框用于内容分割,但是最后一个不需要,如下:
HTML
<ul>
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
<li>列表4</li>
</ul>
CSS
ul li:not(:last-child) {
border-bottom: 1px solid #ddd;
}
▲ 将会对列表中除最后一项外的所有列表项添加一条下边框
4.5、伪元素选择器
选择器 | 含义 |
E:first-line | 匹配E元素内容的第一行 |
E:first-letter | 匹配E元素内容的第一个字母 |
E:before | 在E元素之前插入生成的内容 |
E:after | 在E元素之后插入生成的内容 |
CSS中的伪元素大家以前看过::first-line,:first-letter,:before,:after;那么在CSS3中,他对伪元素进行了一定的调整,在以前的基础上增加了一个“:”也就是现在变成了“::first-letter,::first-line,::before,::after”另外他还增加了一个“::selection”。两个“::”和一个“:”css3中主要用来区分伪类和伪元素,到目前来说,这两种方式都是被接受的,也就是说不管使用哪种写法所起的作用都是一样的,只是一个书写格式不同而以。
4.5.1、E::first-letter 和 E::first-line
p::first-letter {
font-weight:bold;
}
▲ 将会对文本块的第一个字母进行加粗
p::first-line {
font-weight:bold;
}
▲ 将会对段落的第一行文本进行加粗
4.5.2、E::before 和 E::after
E::before
和E::after
是用来给元素的前面和后面差入内容,配合"content"使用,但它必须有值才能生效。
HTML
<div>me</div>
CSS
div:before{
content:'you before';
color:red;
}
div:after{
content:'you after';
color:green;
}
▲ 将会在div
容器中的文本me
加上添加后的内容并设置其颜色