2.5 伪类选择器
伪类选择器是一种特殊的类选择器,它的用处就是可以对不同状态或行为下的元素定义样式,这些状态或行为是无法通过静态的选择器匹配的,具有动态特性。
2.5.1 伪选择器概述
伪选择器包括伪类选择器和伪对象选择器,伪选择器能够根据元素或对象的特征、状态、行为进行匹配。
伪选择器以冒号(:)作为前缀标识符。冒号前可以添加限定选择符,限定伪类应用的范围,冒号后为伪类和伪对象名,冒号前后没有空格。
CSS伪类选择器有两种用法。
1. 单纯式
E:pseudo-class {property:value}
其中E为元素,pseudo-class为伪类名称,property为CSS的属性,value为CSS的属性值。例如:
a:link {color:red;}
2. 混用式
E.class:pseudo-class{property:value}
其中.class表示类选择符。把类选择符与伪类选择符组成一个混合式的选择器,能够设计更复杂的样式,以精准匹配元素。例如:
a.selected:hover {color: blue;}
CSS3支持的伪类选择器具体说明如表2.4所示,CSS3支持的伪对象选择器具体说明如表2.5所示。
由于CSS3伪选择器众多,下面仅针对CSS3中新增的伪类选择器进行说明,其他选择器请读者参考CSS3参考手册详细了解。
2.5.2 结构伪类
结构伪类是根据文档结构的相互关系来匹配特定的元素,从而减少文档元素的class属性和ID属性的无序设置,使得文档更加简洁。
结构伪类形式多样,但用法固定,以便设计各种特殊样式效果。结构伪类主要包括下面几种。
:first-child:第一个子元素。
:last-child:最后一个子元素。
:nth-child():按正序匹配特定子元素。
:nth-last-child():按倒序匹配特定子元素。
:nth-of-type():在同类型中匹配特定子元素。
:nth-last-of-type():按倒序在同类型中匹配特定子元素。
:first-of-type:第一个同类型子元素。
:last-of-type:最后一个同类型子元素。
:only-child:唯一子元素。
:only-of-type:同类型的唯一子元素。
:empty:空元素。
【示例1】下面示例设计排行榜栏目列表样式,设计效果如图2.15所示。在列表框中为每个列表项定义相同的背景图像。
图2.15 排行榜栏目样式
设计列表结构如下:
设计的列表样式请参考本节示例源代码。下面以示例1为基础分析结构伪类选择器的用法。
1. :first-child
【示例2】设计第一个列表项前的图标为1,且字体加粗显示。
使用:first-child匹配,代码如下:
2. : last-child
【示例3】单独给最后一个列表项定义样式。
使用:last-child来匹配,代码如下:
#wrap li:last-child {background-position:2px -277px;}
显示效果如图2.16所示。
图2.16 设计最后一个列表项样式
3. :nth-child()
:nth-child()可以选择一个或多个特定的子元素。该函数有多种用法:
在nth-child()函数中,参数length和n均为整数。
:nth-child()可以定义值,值可以是整数,也可以是表达式,用来选择特定的子元素。
【示例4】下面6个样式分别匹配列表中第2~7个列表项,并分别定义它们的背景图像Y轴坐标位置,显示效果如图2.17所示。
图2.17 设计每个列表项样式
注意::nth-child()函数的参数不能引用负值,如li:nth-child(-3)是不正确的使用方法。
(1):nth-child(n)
在:nth-child(n)中,n是一个简单的表达式,其取值从0开始计算,到什么时候结束是不确定的,须结合文档结构而定,如果在实际应用中直接这样使用,将会选中所有子元素。
在示例4中,如果在li中使用:nth-child(n),那么将选中所有的li元素:
#wrap li:nth-child(n) {text-decoration:underline;}
这个样式类似于:
#wrap li {text-decoration:underline;}
其实,nth-child()是这样计算的:
n=0表示没有选择元素。
n=1表示选择第1个li。
n=2表示选择第2个li。
依此类推,这样下来就选中了所有的li。
(2):nth-child(2n)
:nth-child(2n)是:nth-child(n)的一种变体,使用它可以选择n的倍数(其中2可以换成需要的数字,分别表示不同的倍数)。
#wrap li:nth-child(2n) {font-weight:bold;}
等价于:
#wrap li:nth-child(even) {font-weight:bold;}
预览效果如图2.18所示。
图2.18 设计偶数行列表项样式
其实现过程如下:
当n=0,则2n=0,表示没有选中任何元素。
当n=1,则2n=2,表示选择第2个li。
当n=2,则2n=4,表示选择第4个li。
依此类推。
如果是2n,则与使用even命名class定义样式所起到的效果是一样的。
(3):nth-child(2n-1)
:nth-child(2n-1)选择器是在:nth-child(2n)基础上演变来的,既然:nth-child(2n)表示选择偶数,那么在它的基础上减去1就变成选择奇数。
#wrap li:nth-child(2n-1) {font-weight:bold;}
等价于:
#wrap li:nth-child(odd) {font-weight:bold;}
其实现过程如下:
当n=0,则2n-1=-1,表示没有选中任何元素。
当n=1,则2n-1=1,表示选择第1个li。
当n=2,则2n-1=3,表示选择第3个li。
依此类推。
奇数效果还可以使用:nth-child(2n+1)和:nth-child(odd)来实现。
(4):nth-child(n+5)
:nth-child(n+5)选择器是从第5个子元素开始选择。
li:nth-child(n+5) {font-weight:bold;}
其实现过程如下:
当n=0,则n+5=5,表示选择第5个li。
当n=1,则n+5=6,表示选择第6个li。
依此类推。
可以使用这种方法设置需要开始选择的元素位置,也就是说更改数字,可更改起始位置。
(5):nth-child(-n+5)
:nth-child(-n+5)选择器刚好和:nth-child(n+5)选择器相反,它选择第5个元素前面的子元素。
li:nth-child(-n+5) {font-weight:bold;}
其实现过程如下:
当n=0,则-n+5=5,表示选择第5个li。
当n=1,则-n+5=4,表示选择第4个li。
当n=2,则-n+5=3,表示选择第3个li。
当n=3,则-n+5=2,表示选择第2个li。
当n=4,则-n+5=1,表示选择第1个li。
当n=5,则-n+5=0,表示没有选择任何元素。
(6):nth-child(5n+1)
:nth-child(5n+1)选择器是实现隔几选一的效果。如果是隔三选一,则定义的样式如下:
li:nth-child(3n+1) {font-weight:bold;}
其实现过程如下:
当n=0,则3n+1=1,表示选择第1个li。
当n=1,则3n+1=4,表示选择第4个li。
当n=2,则3n+1=7,表示选择第7个li。
设计效果如图2.19所示。
图2.19 设计隔三选一行列表项样式
4. :nth- last-child()
:nth-last-child()选择器与:nth-child()相似,但作用与:nth-child不一样,:nth-last-child()是从最后一个元素开始计算,来选择特定元素。
li:nth-last-child(4) {font-weight:bold;}
上面代码表示选择倒数第4个列表项。
其中:nth-last-child(1)和:last-child所起作用是一样的,都表示选择最后一个元素。
另外,:nth-last-child()与:nth-child()用法相同,可以使用表达式来选择特定元素,下面来看几个特殊的表达式所起的作用。
:nth-last-child(2n)表示从元素后面计算,选择的是偶数个数,而从前面来说就是选择元素的奇数个数,与:nth-child(2n+1)、:nth-child(2n-1)、:nth-child(odd)所起的作用是一样的。如:
等价于:
:nth-last-child(2n-1)选择器刚好与:nth-last-child(2n)相反,它从后面计算选择的是奇数,而从前面计算选择的就是偶数位了,如:
等价于:
总之,:nth-last-child()和nth-child()使用方法是一样的,只不过:nth-child()是从元素的第一个开始计算,而:nth-last-child()是从元素的最后一个开始计算,它们的计算方法都是一样的。
5. :nth-of-type()
:nth-of-type()类似于:nth-child(),不同的是它只计算选择器中指定的那个元素。:nth-of-type()选择器用来定位元素中包含好多不同类型的子元素时很有用处。
【示例5】在div#wrap中有很多p、li、img等元素,但现在只需要选择p元素,并让它每隔一个p元素就有不同的样式,那就可以简单地写成:
div#wrap p:nth-of-type(even) {font-weight:bold;}
其实,这种用法与:nth-child()是一样的,也可以使用:nth-child()的表达式来实现,唯一不同的是:nth-of-type指定了元素的类型。
6. :nth-last-of-type()
:nth-last-of-type()与:nth-last-child()用法相同,但它指定了子元素的类型。除此之外,语法形式和用法基本相同。
7. :first-of-type和:last-of-type
:first-of-type和:last-of-type选择器类似于:first-child和:last-child,不同之处就是它们指定了元素的类型。
8. :only-child和:only-of-type
:only-child表示一个元素是它的父元素的唯一子元素。
【示例6】在文档中设计如下HTML结构。
如果需要使div.post只有一个p元素时,改变p的样式,可以使用:only-child选择器来实现。
此时若div.post只有一个子元素p,那么它的背景色将会显示为红色。
:only-of-type表示一个元素包含很多个子元素,而其中只有一个子元素是唯一的,那么使用这种选择方法就可以选中这个唯一的子元素。例如:
如果只想选择上面结构块中的p元素,就可以这样写:
.post p:only-of-type{background-color:red;}
9. :empty
:empty用来选择没有任何内容的元素,这里没有内容指的是一点内容都没有,包括空格。
【示例7】以下有3个段落,其中一个段落什么都没有,完全是空的:
如果想设计这个p不显示,那就可以这样来写:
.post p:empty {display: none;}
2.5.3 否定伪类
:not()表示否定选择器,即过滤掉not()函数匹配的特定元素。
【示例】下面示例为页面中所有段落文本设置字体大小为24px,然后使用:not(.author)排除第一段文本,设置其他段落文本的字体大小为14px,显示效果如图2.20所示。
图2.20 否定伪类的应用
2.5.4 状态伪类
CSS3包含3个UI状态伪类选择器,简单说明如下。
: enabled:匹配指定范围内所有可用UI元素。
:disabled:匹配指定范围内所有不可用UI元素。
:checked:匹配指定范围内所有可用UI元素。
【示例】下面示例设计一个简单的登录表单,效果如图2.21所示。在实际应用中,当用户登录完毕,不妨通过脚本把文本框设置为不可用(disabled="disabled")状态,这时可以通过:disabled选择器让文本框显示为灰色,以告诉用户该文本框已不可用,这样就不用设计“不可用”样式类,并把该类添加到HTML结构中。
图2.21 设计登录表单样式
【操作步骤】
第1步,新建一个文档,在文档中构建一个简单的登录表单结构。
在这个表单结构中,使用HTML的disabled属性分别定义两个不可用的文本框对象。
第2步,内建一个内部样式表,使用属性选择器定义文本框和密码域的基本样式。
第3步,利用属性选择器,分别为文本框和密码域定义内嵌标识图标。
第4步,使用状态伪类选择器,定义不可用表单对象显示为灰色,以提示用户该表单对象不可用。
2.5.5 目标伪类
目标伪类选择器类型形式如E:target,它表示选择匹配E的所有元素,且匹配元素被相关URL指向。该选择器是动态选择器,只有当存在URL指向该匹配元素时,样式效果才有效。
【示例】下面示例设计当单击页面中的锚点链接,跳转到指定标题位置时,该标题会自动高亮显示,以提醒用户当前跳转的位置,效果如图2.22所示。
图2.22 目标伪类样式应用效果
2.5.6 动态伪类
动态伪类是一类行为类样式,只有当用户与页面进行交互时有效。包括以下两种形式。
锚点伪类,如:link、:visited。
行为伪类,如:hover、:active和:focus。
【示例】下面示例使用动态伪类选择器设计一组3D动态效果的按钮样式,效果如图2.23所示。
图2.23 设计3D按钮样式
【操作步骤】
第1步,设计一个HTML文档结构。创建一个新的HTML文档,并添加一个列表,在列表项中包含基本的锚链接。不需要任何额外的<div>或者<span>标签,也不用添加id和class属性,一切效果都通过CSS进行控制。结构代码如下:
为了演示不同色彩风格的按钮样式,可以定义主题样式类,通过给每一个按钮应用不同的主题样式,可以充分发挥CSS的优势和便捷之处。
第2步,新建内部样式表,定义基本的按钮类样式。
第3步,为按钮类样式增加行为样式,让按钮实现动态效果。这里主要使用了:hover伪类选择器。例如,为灰色系按钮设计鼠标经过时的动态样式效果,主要包括字体颜色和背景色的变化,以及边框线的变换,以模拟立体效果。
第4步,定义双边框样式。通过预览会发现现在的按钮边框显得比较单薄,需要为按钮定义粗边框的底部效果,同时还需要增加一点点行间距,因此这里使用了:before和:after伪类样式。
第5步,为了彰显按钮的金属特质,不妨借助CSS3的特效定义圆角效果。
a.button {border-radius: 3px;}
第6步,为边框定义阴影效果。
第7步,定义鼠标经过和访问过按钮伪类状态类样式,设计渐变背景色特效。
第8步,利用:active伪类选择器定义对象激活状态的样式效果。