2.4 伪类选择器
伪类选择器包括伪类和伪对象选择器,伪类选择器以冒号(:)作为前缀标识符。冒号前可以添加选择符,限定伪类应用的范围,冒号后为伪类和伪对象名,冒号前后没有空格,如图2.22所示。
图2.22 伪类选择器结构
提示:CSS伪类选择器有以下两种用法。
☑ 单纯式
E:pseudo-class { property:value}
其中E为元素,pseudo-class为伪类名称,property是CSS的属性,value为CSS的属性值。例如:
a:link {color:red;}
☑ 混用式
E.class:pseudo-class{property:value}
其中.class表示类选择符。把类选择符与伪类选择符组成一个混合式的选择器,能够设计更复杂的样式,以精准匹配元素。例如:
a.selected:hover {color: blue;}
2.4.1 动态伪类
视频讲解
动态伪类是一类行为类样式,只有当用户与页面进行交互时才有效,包括以下两种形式。
☑ 锚点伪类,如: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步,为边框定义阴影效果,代码如下。
a.button:before,a.button:after { border-radius: 3px;} a.button:before { border-radius: 0 0 3px 3px; box-shadow: 0 1px 1px 0px #bfbfbf; }
第7步,定义鼠标经过和访问过按钮伪类状态类样式,设计渐变背景色特效,代码如下。
第8步,利用:active伪类选择器定义对象激活下的样式效果。
2.4.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.24所示。在列表框中为每个列表项定义相同的背景图像。
图2.24 设计排行榜栏目样式
设计的列表结构如下。
设计的列表样式如下。
下面结合这个栏目示例,具体分析结构伪类选择器的用法。
1. :first-child
【示例2】如果设计第一个列表项前的图标为1,且字体加粗显示,则使用:first-child匹配,代码如下。
#wrap li:first-child { background-position:2px 10px; font-weight:bold; }
2. :last-child
【示例3】如果单独给最后一个列表项定义样式,就可以使用:last-child来匹配。
#wrap li:last-child {background-position:2px -277px;}
显示效果如图2.25所示。
3. :nth-child()
:nth-child()可以选择一个或多个特定的子元素。该函数有多种用法。
: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);/*表示隔几选一*/
在nth-child()函数中,参数length为一个整数,n表示一个从0开始的自然数。
:nth-child()可以定义值,值可以是整数,也可以是表达式,用来选择特定的子元素。
【示例4】下面6个样式分别匹配列表中第2~7个列表项,并分别定义它们的背景图像Y轴坐标位置,显示效果如图2.26所示。
#wrap li:nth-child(2) { background-position: 2px -31px; } #wrap li:nth-child(3) { background-position: 2px -72px; } #wrap li:nth-child(4) { background-position: 2px -113px; } #wrap li:nth-child(5) { background-position: 2px -154px; } #wrap li:nth-child(6) { background-position: 2px -195px; } #wrap li:nth-child(7) { background-position: 2px -236px; }
图2.25 设计最后一个列表项样式
图2.26 第2~7个列表项样式
注意,这种函数参数用法不能引用负值,也就是说,li:nth-child(-3)是不正确的使用方法。
☑ :nth-child(n)
在:nth-child(n)中,n是一个简单的表达式,其取值从0开始计算,到什么时候结束不确定,需结合文档结构而定,如果在实际应用中直接这样使用,将会选中所有子元素。
【示例5】在上面示例中,如果在li中使用:nth-child(n),那么将选中所有的li元素。
#wrap li:nth-child(n) {text-decoration:underline;}
上述样式类似于:
#wrap li {text-decoration:underline;}
其实,nth-child(n)是这样计算的:
n=0表示没有选择元素;
n=1表示选择第1个li;
n=2表示选择第2个li。
依此类推,这样就选中了所有的li。
☑ :nth-child(2n)
【示例6】:nth-child(2n)是:nth-child(n)的一种变体,使用它可以选择n的2倍,当然其中2可以换成需要的数字,分别表示不同的倍数。
#wrap li:nth-child(2n) {font-weight:bold;}
等价于:
#wrap li:nth-child(even) {font-weight:bold;}
预览效果如图2.27所示。
来看一下其实现过程:
当n=0,则2n=0,表示没有选中任何元素;
当n=1,则2n=2,表示选择了第2个li;
当n=2,则2n=4,表示选择了第4个li。
依此类推。
如果是2n,这样与使用even命名class定义样式所起到的效果是一样的。
☑ :nth-child(2n-1)
【示例7】: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,表示选择第2个li。
依此类推。
其实这种奇数效果,还可以使用:nth-child(2n+1)和:nth-child(odd)来实现。
☑ :nth-child(n+5)
【示例8】: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。
依此类推。
读者可以使用这种方法选择需要开始选择的元素位置,也就是说换了数字,起始位置就变了。
☑ :nth-child(-n+5)
【示例9】: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,表示没有选择任何元素。
☑ :nth-child(5n+1)
:nth-child(5n+1)选择器是实现隔几选一的效果。
【示例10】如果是隔三选一,则定义的样式如下。
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.28所示。
图2.27 设计偶数行列表项样式
图2.28 设计隔三选一行列表项样式
4. :nth-last-child()
【示例11】: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)所起的作用是一样的。例如:
li:nth-last-child(2n) {font-weight:bold;} li:nth-last-child(even) {font-weight:bold;}
等价于:
li:nth-child(2n+1) {font-weight:bold;} li:nth-child(2n-1) {font-weight:bold;} li:nth-child(odd) {font-weight:bold;}
:nth-last-child(2n-1)选择器刚好与上面的相反,从后面计算选择的是奇数,而从前面计算选择的就是偶数位了。例如:
li:nth-last-child(2n+1) {font-weight:bold;} li:nth-last-child(2n-1) {font-weight:bold;} li:nth-last-child(odd) {font-weight:bold;}
等价于:
li:nth-child(2n) {font-weight:bold;} li:nth-child(even) {font-weight:bold;}
总之,:nth-last-child()和nth-child()的使用方法是一样的,区别是:nth-child()从元素的第一个开始计算,而:nth-last-child()是从元素的最后一个开始计算,它们的计算方法都是一样的。
5. :nth-of-type()
:nth-of-type()类似于:nth-child(),不同的是,:nth-of-type()只计算选择器中指定的那个元素。这个选择器在定位元素中包含很多不同类型的子元素时是很有用处的。
【示例12】在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表示的是一个元素是它的父元素的唯一一个子元素。
【示例13】在文档中设计如下HTML结构。
如果需要在div.post只有一个p元素的时候,改变这个p的样式,那么就可以使用:only-child选择器来实现。
.post p {font-weight:bold;} .post p:only-child {background: red;}
当div.post只有一个子元素p时,那么它的背景色将会显示为红色。
:only-of-type表示一个元素包含很多个子元素,而其中只有一个子元素是唯一的,那么使用这种选择方法就可以选择这个唯一的子元素。例如:
如果只想选择上面结构块中的p元素,就可以这样写:
.post p:only-of-type{background-color:red;}
9. :empty
:empty是用来选择没有任何内容的元素,这里没有内容指的是一点内容都没有,包括空格。
【示例14】这里有3个段落,其中一个段落什么都没有,完全是空的。
如果想设计这个p不显示,那就可这样来写:
.post p:empty {display: none;}
2.4.3 否定伪类
视频讲解
:not()表示否定选择器,即排除或者过滤掉特定元素。
【示例】本示例是设计一个分层表格样式,主要借助否定伪类选择器和结构伪类选择器,配合CSS背景图像技术设计树形结构标志;借助伪类选择器设计鼠标经过时的动态背景效果;利用CSS边框和背景色设计标题行的立体显示效果。效果如图2.29所示。
图2.29 设计表格样式
【操作步骤】
第1步,利用表格结构构建一个数据表。
第2步,使用<style>标签在当前文档中内建一个样式表,并初始化表格样式。
table { border-collapse: collapse; font-size: 75%; line-height: 1.4; border: solid 2px #ccc; width: 100%; } th, td { padding: .3em .5em; cursor: pointer; } th { font-weight: normal; text-align: left; padding-left: 15px; }
第3步,使用结构伪类选择器匹配合并单元格所在的行,定义合并单元格所在行加粗显示。
td:only-of-type { font-weight:bold; color:#444;}
第4步,使用否定伪类选择器选择主体区域非最后一个th元素。以背景方式在行前定义结构路径线。
tbody th:not(.end) { background: url(images/dots.gif) 15px 56% no-repeat; padding-left: 26px;}
第5步,使用类选择器选择主体区域非最后一个th元素。以背景方式在行前定义结构封闭路径线。
tbody th.end { background: url(images/dots2.gif) 15px 56% no-repeat; padding-left: 26px;}
第6步,使用thead元素把表头标题独立出来,方便CSS控制,避免定义过多的class属性。th元素有两种显示形式,一种用来定义列标题,另一种用来定义行标题。下面是定义表格标题列样式。
thead th { background: #c6ceda; border-color: #fff #fff #888 #fff; border-style: solid; border-width: 1px 1px 2px 1px; padding-left: .5em;}
第7步,设计隔行换色的背景效果,这里主要应用了:nth-child(2n)选择器,同时使用:hover动态伪类定义鼠标经过时的行背景色动画变化,以提示鼠标当前经过行效果。
tbody tr:nth-child(2n) {background-color: #fef;} tbody tr:hover{ background: #fbf; }
2.4.4 状态伪类
视频讲解
CSS3新增3个UI状态伪类选择器。简单说明如下。
1. :enabled
:enabled伪类表示匹配指定范围内所有可用UI元素。在网页中,UI元素一般是指包含在form元素内的表单元素。例如,在下面表单结构中,input:enabled选择器将匹配文本框,但不匹配该表单中的按钮。
<form> <input type="text" /> disabled <input type="button"/> </form>
2. :disabled
:disabled伪类表示匹配指定范围内所有不可用UI元素。例如,在下面表单结构中,input:disabled选择器将匹配按钮,但不匹配该表单中的文本框。
<form> <input type="text" /> <input type="button" disabled="disabled" /> </form>
3. :checked
:checked伪类表示匹配指定范围内所有可用UI元素。例如,在下面表单结构中,input:checked选择器将匹配片段中的单选按钮,但不匹配该表单中的复选框。
<form> <input type="checkbox" /> <input type="radio" checked="checked" /> </form>
【示例】本示例设计一个简单的登录表单,效果如图2.30所示。在实际应用中,当用户登录完毕,不妨通过脚本把文本框设置为不可用(disabled="disabled")状态,这时可以通过:disabled选择器让文本框显示为灰色,以告诉用户该文本框不可用了,这样就不用设计“不可用”样式类,并把该类添加到HTML结构中。
图2.30 设计登录表单样式
【操作步骤】
第1步,新建一个文档,在文档中构建一个简单的登录表单结构。
<form action="#"> <label for="username">用户名</label> <input type="text" name="username" id="username" /> <input type="text" name="username1" disabled="disabled" value="不可用" /> <label for="password">密码</label> <input type="password" name="password" id="password" /> <input type="password" name="password1" disabled="disabled" value="不可用" /> <input type="submit" value="提交" /> </form>
在这个表单结构中,使用HTML的disabled属性分别定义两个不可用的文本框对象。
第2步,内建一个内部样式表,使用属性选择器定义文本框和密码域的基本样式。
input[type="text"], input[type="password"] { border:1px solid #0f0; width:160px; height:22px; padding-left:20px; margin:6px 0; line-height:20px;}
第3步,利用属性选择器分别为文本框和密码域定义内嵌标识图标。
input[type="text"] { background:url(images/name.gif) no-repeat 2px 2px; } input[type="password"] { background:url(images/password.gif) no-repeat 2px 2px; }
第4步,使用状态伪类选择器定义不可用表单对象显示为灰色,以提示用户该表单对象不可用。
input[type="text"]:disabled { background:#ddd url(images/name1.gif) no-repeat 2px 2px; border:1px solid #bbb;} input[type="password"]:disabled { background:#ddd url(images/password1.gif) no-repeat 2px 2px; border:1px solid #bbb;}
2.4.5 目标伪类
视频讲解
目标伪类选择器类型形式如E:target,它表示选择匹配E的所有元素,且匹配元素被相关URL指向。该选择器是动态选择器,只有当存在URL指向该匹配元素时,样式效果才能够有效。
【示例】本示例设计了当单击页面中的锚点链接,跳转到指定标题位置时,该标题会自动高亮显示,以提醒用户当前跳转的位置,效果如图2.31所示。
图2.31 目标伪类样式应用效果