dudo博客

4月
21

英文原文http://www.456bereastreet.com/archive/200601/css_3_selectors_explained/
中文翻译http://www.dudo.org/article.asp?id=197

[注]本文写于2006年1月,当时IE7、IE8和Firefox3还未发行,文中所有说的浏览器支持均未包括这三个版本的浏览器。在IE8和Firefox3中,文中的大部分选择符已经被支持[dudo注]

在2005年的9月和10月,我先后发表了几篇关于CSS2.1中选择符的介绍文章。大体看来那几篇文章中介绍过的大部分选择符都已经可以在像Mozilla/Firefox,Safari和Opera等现代浏览器中使用了。我们现在要做的就是等待Internet Explorer尽快赶上来,那我们就可以尽情地使用CSS2.1中的选择符了。好在Internet Explorer在其第7个版本中已经在尽力追赶了,至少在某些扩展方面。
如果我们再向前看一点,在CSS3中还有功能更加强大的选择符等待我们去发掘和使用。CSS3中的很多选择符已经在现代浏览器中得到很好的应用(IE8.0中也已经部分地支持了CSS3,dudo注),但是这些基本功能上的支持还远远不能满足开发者使用的要求。但是在某些情况下使用他们可以带来很好的超前体验,因此我认为了解一下CSS 3新增选择符是如何使用还是有益处的。
本文中对选择符描述主要是参考了《2005年12月15日W3C制定的选择符草稿》。草稿中讲到的新的选择符可能会在CSS的第3个版本中出现,但是也可能会出现在其他语言中。如果你是几个月前甚至是几年前读过这篇草稿,那么现在你应该再去看一下是不是已经出现了最新版本了。
这里我不打算去解释CSS选择符工作的基本原理。如果你想重要复习一下的话,最好从《细说CSS2.1中的选择符》开始。
首先,快速浏览一下CSS3中新增的选择符:

CSS3选择符语法概览:

选择符类型______________表达式__________________描述
子串匹配的属性选择符_____E[att^="val"]___________匹配具有att属性、且值以val开头的E元素
子串匹配的属性选择符_____E[att$="val"]___________匹配具有att属性、且值以val结尾的E元素
子串匹配的属性选择符_____E[att*="val"]___________匹配具有att属性、且值中含有val的E元素
结构性伪类_____________E:root_________________匹配文档的根元素。在HTML中,根元素永远是HTML
结构性伪类______________E:nth-child(n)__________匹配父元素中的第n个子元素E
结构性伪类______________E:nth-last-child(n)_______匹配父元素中的倒数第n个结构子元素E
结构性伪类______________E:nth-of-type(n)________匹配同类型中的第n个同级兄弟元素E
结构性伪类______________E:nth-last-of-type(n)_____匹配同类型中的倒数第n个同级兄弟元素E
结构性伪类______________E:last-child_____________匹配父元素中最后一个E元素
结构性伪类______________E:first-of-type__________匹配同级兄弟元素中的第一个E元素
结构性伪类______________E:only-child____________匹配属于父元素中唯一子元素的E
结构性伪类______________E:only-of-type__________匹配属于同类型中唯一兄弟元素的E
结构性伪类______________E:empty______________匹配没有任何子元素(包括text节点)的元素E
目标伪类________________E:target______________匹配相关URL指向的E元素
UI元素状态伪类__________E:enabled______________匹配所有用户界面(form表单)中处于可用状态的E元素
UI元素状态伪类__________E:disabled______________匹配所有用户界面(form表单)中处于不可用状态的E元素
UI元素状态伪类__________E:checked_______________匹配所有用户界面(form表单)中处于选中状态的元素E
UI元素状态伪类__________E::selection____________匹配E元素中被用户选中或处于高亮状态的部分
否定伪类________________E:not(s)________________匹配所有不匹配简单选择符s的元素E
通用兄弟元素选择器______E ~ F___________________匹配E元素之后的F元素

如果对上面的描述还不是很清楚的,请不要担心。本文下面的部分将会对他们进行更加详细的讲解,并且提供例子来演示他们是怎么使用的。

子串匹配的属性选择符

这一组的选择符都新加的,他允许开发者对属性中的子字符串来进行匹配。

假设HTML文档中包含下面的代码结构:

通过使用子串匹配的属性选择符就可以找到文档中这些结构性的特定组合。

下面的规则将为id以“nav”开头的div元素设定背景颜色:

div[id^="nav"] { background:#ff0; }

上例中选择符会匹配div#nav-primary和div#nav-secondary。

要找到id以primary结尾的div元素,可以使用下面的规则:

div[id$="primary"] { background:#ff0; }

这时选择符将匹配div#nav-primary和div#content-primary。

下面的规则将会匹配到id中含有content子字符串的的div中:

div[id*="content"] { background:#ff0; }

受影响的元素有:div#content-primary、div#content-secondary和div#tertiary-content。

子串匹配的属性选择符已经在最新版本的Mozilla、Firefox、Flock、Camino、Safari、OmniWeb以及Opera中可以使用,但是如果IE中还不支持的话,我们最好还是先不要使用他们(作者在写这篇文章时IE还在开发中,如今IE7、IE8都支持这些选择符,dudo注)。

目标伪类

含有识别标识的url(一个#后面紧跟锚点名称或者元素的id)指向的是文档中的特定元素。链向其他目标元素的这些元素就可以使用:target伪类来修饰它。如果当前的URL中没有任何的片断识别标识,:target伪类将不会匹配任何元素。

还是以上面提到的代码结构为例,如果URL中包含content-primary标识时,现在的规则将会在他外围增加一个边框:

div#content-primary:target { outline:1px solid #300; }

URL是类似这样的形式的:
http://www.example.com/index.html#content-primary。
基于Mozilla和Safari的浏览器已经支持:target伪类。

UI元素状态伪类

:ENABLED伪类和:DISABLED伪类
在浏览器允许改变表单控件外观的前提下,:enabled伪类和:disable伪类允许开发者指定用户界面中可用和不可用元素(表单元素)的显示样式。下面的规则将会根据单行输入框是否可用设定不同的背景颜色:

input[type="text"]:enabled { background:#ffc; }
input[type="text"]:disabled { background:#ddd; }

:CHECKED伪类
:checked伪类允许开发者为处于选中状态的checkbox和radio设定样式。当然这也要在浏览器允许改变表单控件外观的条件下。下面的CSS规则将会使选中的radio和checkbox元素显示一个绿色边框:

input:checked { border:1px solid #090; }

UI元素状态伪类目前可以在Opera和基于Mozilla的浏览器中使用。

要注意的是,许多浏览器对于开发者对表单控件样式的改变有着严格的限制。更多关于这方便的内容可以我的两篇文章:《样式化表单控件》《样式化更多表单控件》

结构性伪类

结构性伪类允许开发者根据文档树中表明的结构来指定元素,而这些使用简单选择符或者是混合选择符都无法做到。结构性伪类功能十分强大,但是不幸的是现代浏览器仅提供了有限的支持。

:ROOT伪类
:root伪类指向的是文档的根元素。在HTML中,文档的根元素始终是HTML,也就是说现在的两条规则其实是一样的(大体上说来:root要比html更专业点)。

:root { background:#ff0; }
html { background:#ff0; }

:NTH-CHILD()伪类

:nth-child()伪类指向的元素在文档树中有一定数量的兄弟元素存在。其中括号内的参数,可以是一个数字,也可以一个关键字或者一个公式。
数字b指是的第b个子元素。下面的规则将会应用到父元素下所有p元素中的第三个中:

p:nth-child(3) { color:#f00; }

关键字odd(奇数)和even(偶数)可以用来匹配序号为奇数或者是偶数的子元素。第一个元素的序号为1,因为下面的规则将会匹配第1、3、5…了子元素p:

p:nth-child(odd) { color:#f00; }

下面的规则则匹配第2、4、6…个字元素p:

p:nth-child(even) { color:#f00; }

表达式an+b可以用来创建更加复杂的循环模式。在表达式中,a代表步长,n是一个从0开始的计数器,b代表偏移量。其中,所有的数值都必须是整数(这里,n是从0开始的,和js等中的循环不同的是,至于到多少结束取决于元素的个数决定,如文档中有20个元素,3n(n=1,2…)就会分别选择第3、6、9、…18个元素,n此时为6 ,dudo注)。为了更好理解如何使用表达式我们先看几个代码实例:

下面的规则将会匹配序号数为3的倍数的所有p元素。在第一行中,b等于0,因此可以忽略不写(见第二行):

p:nth-child(3n+0) { color:#f00; }
p:nth-child(3n) { color:#f00; }

偏移量可以用来指定样式的循环是从哪个元素开始应用的。如果有一个20行的表格,我们希望从第10行以后的奇数行开始使用不同的背景颜色,就可以使用下面这条规则:

tr:nth-child(2n+11) { background:#ff0; }

由于n是从为开始的,因此第一个受影响的tr元素的序号是11(2*0+11=11,dudo注)。接下来就是第13行(2*1+11=13)再接下来就第15行(2*2+11=15),以此类推。

更详细介绍请参照CSS 3选择符中的《nth-child()伪类》

那么,对于这样有用的一个选择符又有哪些浏览器支持它呢?很糟糕,据我所知,没有一个浏览器支持这个选择符甚至没有浏览器支持nth类的选择符。如果有的话请帮我指正(Firefox3和IE8目前是否支持?dudo)

:nth-of-type()

:nth-of-type()伪类和nth-child()伪类找使用方法十分相似,只不过他匹配的是规则中指明类型的元素。下面的规则将会匹配每个属于父元素中第三个子元素的p元素(属于第3个子元素的p在一个该当中可能会有很多,只不过他们位于不同的父元素下,dudo注):

p:nth-of-type(3) { background:#ff0; }

当你想确定是否已经指向了第三个p元素,这种方法会很有用。开始你可能觉得这和使用nth-child效果是一样的,但是nth-child(3)会把所有的子元素都计算进来,因此结果可能就会不一样,除非p所有的所有兄弟元素也都是p元素。

:nth-of-type伪类目前还没有浏览器支持。

:nth-last-of-type伪类
:nth-last-of-type伪类指向的元素在其后还有若干同类型的元素。和:nth-last-child伪类一样,它是从最后一个子元素向回数的。下面的规则将会匹配到倒数第二个兄弟元素p中(注意:是兄弟、同级别的节点):

p:nth-last-of-type(2) { background:#ff0; }

:nth-last-of-type()目前还没有浏览器支持。

:last-child伪类

:last伪类指向的是父元素中最后一个子元素。它和:nth-last-child(1)效果是一样的。下面的规则匹配所有属于父元素中最后一个子元素的p:

p:last-child { background:#ff0; }

:last-childe伪类可以在基于Mozilla的浏览器中使用。Opera不支持:last-childe伪类,在Safri中存在bug(上面的规则会匹配到所有的p元素)。令人稀奇是的它可以在OmniWeb(测试版本5.1.1)中正常使用,尽管这个浏览器是基于Safari的。这可能是因为Apple WebKit最新版本的回归,因为OmniWeb使用的WebKit通常要比Safari版本稍微低一点。

:first-of-type伪类
:first-of-type伪类指向同类型元素中的第一个元素。它和:nth-of-type(1)是一样的。

p:first-of-type { background:#ff0; }

:first-of-type伪类目前还没有浏览器支持。

:last-of-type伪类
:last-of-type伪类指向同类型元素中的最后一个元素。它和nth-last-of-type(1)是一样的。

p:last-of-type { background:#ff0; }

:last-of-type伪类目前还没有浏览器支持。

:only-child伪类
:only-childe伪类指向的是那些父元素中再没有其他任何子元素的元素。它和:first-child:last-child或者:nth-child(1):nth-last-child(1)是一样的(后者不够专业、简明)。

p:only-child { backgound:#ff0; }

:only-childe伪类目前可以在基于Mozilla的浏览器中使用。在Safari似乎被解释成了:first-child(上面的规则会被匹配到文档中所有第一个子元素p中)。

:only-of-type伪类
:only-of-type伪类指向的是那些父元素中再也没有与之类型相同的子元素。这和:first-of-type:last-of-type或者:nth-of-type(1):nth-last-of-type(1)相同(后者专业性不够)。

p:only-of-type { background:#ff0; }

:only-of-type伪类目前还没有浏览器支持。

:empty伪类
:empty伪类指向没有任何子元素的元素。其中包括text节点,因此下面的示例只有第一行是空元素。

text

下面的规则只匹配第一行的p元素:

p:empty { background:#ff0 }

:empty伪类目前被基于Mozilla的浏览器支持。Safari会错误地把样式应用到所有指定的元素中去。

否定伪类
否定伪类写成:not(s),参数s为简单选择符。它指向的是除简单选择所指向的元素以外的所有元素。例如,下面的CSS将会指向所有不是p的元素:

:not(p) { border:1px solid #ccc; }

否定伪类目前只有基于Mozilla的浏览器支持。

::selection伪类
::selection伪类匹配指定元素中处于选中或者高亮状态的部分。其中一个应用就是用它来控制选中文本的样式。
下面的规则会使选中的文本颜色变为红色:

::select { color:#f00; }

::selection伪类目前可能基于Safari的浏览器支持。但是在使用上会出现不可预料的情况,因此Safari还需要一点改进。基于Mozilla的浏览器要使用-moz-prefix: ::-mozi-selection来实现。这种prefix可能最终会被去掉。

通用兄弟元素选择器
通用兄弟元素选择器通过两个简单选择符通过波浪号(~)分隔组成。它匹配第二个简单选择符中所匹配的元素,而且与第一个简单选择符中匹配的元素要出现在他的前面。这两个元素必须具有同一个父元素,但是第二个元素不一定必须紧跟在第一个元素之后。这条CSS规则将会匹配所有p元素之后ul元素:

p ~ ul { background:#ff0; }

通用兄弟元素选择器目前有Opera和基于Mozilla的浏览器支持。

亟需更好的浏览器支持
部分CSS 3选择符已经被广泛支持。但是,大部分非常有用的选择符在现代浏览器中或者未被支持或者使用受到限制。这就使得本文中介绍的很多选择符在今天的Web或多或少失去了用武之地。但是不必害怕去尝试它,你仍然可以在支持他们的带来超前体验的高级浏览器中使用他们。

[附件]CSS3选择符在现在浏览器(Firefox 2、Firefox 3、InternetExplorer 7、Internet Explorer 8、Oper9.27)中的支持程度(dudo验证,请指正!)

_________________IE 7________IE8________FF2_________FF3______Opera9.27
E[foo^="bar"]______Y__________Y__________Y__________Y__________Y
E[foo$="bar"] ______Y__________Y__________Y__________Y__________Y
E[foo*="bar"] ______Y__________Y__________Y__________Y__________Y
E:root____________ N__________N__________Y__________Y__________Y
E:nth-child()_______ N__________N__________N__________N__________N
E:nth-last-child()____ N__________N__________N__________N__________N
E:nth-of-type()_____ N__________N__________N__________N__________N
E:nth-last-of-type()__ N__________N__________N__________N__________N
E:last-child_________ N__________N__________Y__________Y__________N
E:first-of-type______ N__________N__________N__________N__________N
E:only-child________ N__________N__________Y__________Y__________Y
E:only-of-type______N__________N__________N__________N__________N
E:empty__________ N__________N__________Y__________Y__________N
E:target___________N__________N__________Y__________Y__________N
E:enabled_________ N__________N__________Y__________Y__________Y
E:disabled_________ N__________N__________Y__________Y__________Y
E:checked_________N__________N__________N__________N__________Y
::selection_________N__________N__________N__________N__________N
not()_____________N__________N__________Y__________Y__________Y
E ~ F_____________Y__________Y__________Y__________Y__________Y



随便说两句
名字:
Email:
网站:
内容:

无觅相关文章插件,快速提升流量