在上面的这个例子中,第一个黄色的li元素将会是第四个。如果也想从第一个开始匹配,你可以使用一个简单的表达式:
ul li:nth-child(3n) {
color: yellow;
}
这样的话,第一个黄色的li元素将会是第三个子元素,然后是它后面的每隔第三个。现在想象一下如果你只想匹配列表中的前四个子元素:
ul li:nth-child(-n+4) {
color: green;
}
:nth-child的值同样也可以被定义为“even” 或“odd”,和“2n” (第偶数个) 或“2n+1” (第奇数个)的效果是一样的。
:nth-last-child
:nth-last-child伪类基本上和:nth-child伪类的作用相同,但是它从最后一个元素开始算。
使用上面的一个例子来看看:
ul li:nth-child(-n+4) {
color: green;
}
不是匹配最前面的四个li元素,该选择器匹配最后面的四个元素。
你同样可以使用“even” 或“odd”只,同样与nth-child不同的是,这是从最后面的元素开始算的:
ul li:nth-last-child(odd) {
color: grey;
}
:nth-of-type
:nth-of-type伪类和:nth-child也很像,不同的是它只计算选择器中指定的那个元素。
这对定位元素中包含大量不同的元素的情况会很有用。比如,我们想控制一个文本块中的每隔一个段落,但是我们又想要无视其它元素比如图片和引用块:
p:nth-of-type(even) {
color: blue;
}
你也可以使用一些值,就像在:nth-child中使用的一样。
:nth-last-of-type
你能猜到它吧?!:nth-last-of-type 伪类可以像前面提到的:nth-last-child一样使用,但是这次,它将之匹配你在选择器中指定的元素类型:
ul li:nth-last-of-type(-n+4) {
color: green;
}
我们可以更加的聪明一些,在一个大的块级选择器中结合多种这样的伪类。比如我们想让文章中的所有的图片左浮动,除了第一个和最后一个(我们可以假设他们是满宽的,无须浮动):
.post img:nth-of-type(n+2):nth-last-of-type(n+2) {
float: left;
}
所以在这个选择器的第一部分,我们从第二个图片开始定位每一个图片。在第二部分中,我们定位所有的图片,除了最后一个。因为这两个选择器并非互斥的,我们可以同时使用它们,这样就可以一下子排除第一个和最后一个元素!
:last-child
:last-child伪类的作用类似于:first-child 伪类,但是会定位父级元素的最后一个子元素。
让我们假设你不想让你的日志的div的最后一个段落也有一个底部边距:
.post > p:last-child {
margin-bottom: 0;
}
该选择器将定位class为”post”的元素的最后一个直接子级段落。
:first-of-type 和:last-of-type
:first-of-type 伪类用于定位一个父级元素下的第一个同类子元素。
比如,你可以定位某个特定的div的第一个子级段落(p),并让其第一行字母大写:
.post > p:first-of-type:first-line {
font-variant: small-caps;
}
在这个选择器中,你可以确定你是在只定位class为”post”的元素的直接子级p元素,而且还是匹配第一个子级p元素。
:last-of-type伪类与此类似,只是匹配最后一个子元素。
nly-child
nly-child伪类表示一个元素是它的父级元素的唯一一个子元素。
比如说,你有一些盒子(“news”),里面有一些文字段落,当你有多于一个段落的时候,你想让文字比只有一个段落的时候小一些:
div.news > p {
font-size: 1.2em;
}
div.news > p:only-child {
font-size: 1.5em;
}
第一个选择器中,我们定义”news”div的所有子级p元素的字体大小。在第二个中,我们覆盖之前的字体大小,如果该p元素是“news” div的唯一子元素的时候,它的字体大小会比较大一些。
nly-of-type
nly-of-type伪类表示一个元素是它的父级元素的唯一一个相同类型的子元素。
这有用什么用?假设你有一些日志,每一篇都有个class为”post”的div,他们中的一些有多于一张图片,但是有些可能就只有一张图片。你想让后者中的图片水平居中,而在其它的有多于一张图片的日志中,就将它左浮动。这个需求用这个选择器就很容易实现:
.post > img {
float: left;
}
.post > img:only-of-type {
float: none;
margin: auto;
}
:empty
:empty伪类表示一个元素里面没有任何内容。
这个选择器可以用很多种用途。比如,你在你的“sidebar”中有若干个盒子,但是不想让空盒子显示出来:
#sidebar .box:empty {
display: none;
}
注意,就算”box”div里面只有一个空格,它也不会被css当作空标签的,这样就不能匹配该选择器了。
浏览器支持
Internet Explorer (直到8.0版本)都不支持结构伪类。Firefox、Safari 和Opera 在其最新版本的浏览器中指出这些选择器。这意味着,使用这些选择器对网站的可用性和可访问性是很有用的,或者如果网站的用户中的大部分是使用IE而且你不想在某些细节上无视他们,最好还是保持使用通用的class和简单的选择器来迎合这些选择器。否则你会被搞疯的!
7. 否定选择器
否定选择器:not(),可以让你定位不匹配该选择器的元素
比如,如果你需要定义表单元素中的input元素,但是又不想包括submit类型的input的时候会灰常有用——你想它们有不同的样式,以看起来像按钮:
input:not([type=“submit”]) {
width: 200px;
padding: 3px;
border: 1px solid #000000;
}
另一个例子,你想你的日志的div中的所有段落(p)有比较大的字体,除了表示时间和日期的段落:
.post p:not(.date) {
font-size: 13px;
}
你可以想象这个选择器能带给你的潜力了吧,你能够从你的CSS文件中剥离(剔除)的无用的大量选择器也被它广泛支持吗?
浏览器支持
Internet Explorer在这里常常是让我们感到扫兴的东西:一点都不支持,甚至在IE8中。这大概意味着这些选择器将仍不得不等到一些开发者开始不再顾虑将它添加到他们的样式表中才会普及。
8. 伪元素
伪元素允许你操作HTML中不是真实存在的元素,比如一个文本块的第一行或者第一个字母。
伪元素在CSS 2.1中就已经存在,但是CSS 3说明书表示他们应该使用双冒号“::”,以与伪类区分开来。在CSS 2.1中,他们也是使用单个冒号“:”的。浏览器会将能够接受两种格式,除非这些伪元素只存在于CSS3中。
::first-line
::first-line伪元素将匹配block、inline-block、table-caption、table-cell等等级别元素的第一行
这对在你的文字块上添加一些微妙的排版细节相当有用,比如,将一片文章的第一行文字改成小写字母:
h1 + p::first-line {
font-variant: small-caps;
}
如果你专心的阅读了我们前面的内容,你将会了解到上面的语法意味着,紧紧的跟在H1标签之后(+)的段落会将其第一行文字显示为小写字母。
你也可以针对相关的div的第一行,而不用针对实际的段落标签(p):
div.post p::first-line { font-variant: small-caps; }
或者更进一步,定位某个特低的div的第一个段落的第一行:
div.post > p:first-child::first-line {
font-variant: small-caps;
}
这里,“》”符号表示你指定的是post div的直接子级元素,这样如果段落被包括在第二级div中,它就不会匹配这个选择器。
::first-letter
::first-letter伪元素将会匹配一个文本块的第一个字母,除非在同一行里面包含一些其它元素,比如图片。
和::first-line伪类一样,::first-letter通常用于给文本元素添加排版细节,比如下沉字母或首字母。
这里是如何使用::first-letter伪元素创建首字下沉的例子:
p {
font-size: 12px;
}
p::first-letter {
font-size: 24px;
float: left;
}
注意如果你在某些元素中同时使用::first-line 和::first-letter ,::first-letter 属性将覆盖从::first-line中继承下来的某些属性。
如果你不知道W3C规则的话,这个元素有时会产生意想不到的结果:它事实上是使用最长的规则的选择器!所以如果你计划使用它的话最好仔细的阅读一下 (其它选择器也一样)。
::before 和 ::after
::before和::after 伪元素用于在一个元素的前面或后面插入内容,纯CSS方法。
这些元素将继承它们将附加的元素的大部分属性。
假设你想在你的页面中的图标的描述前面添加文字“Graphic number x:”。你将无需写文字“Graphic number”,或者自己手动添加数字:
.post {
counter-reset: image;
}
p.description::before {
content: “Figure number ” counter(image) “: ”;
counter-increment: image;
}
那么这会产生什么?
首先,我们告诉HTML来创建“image”计数器。比如我们可以添加该属性到页面的body。同样我们也可以给该计数器起任何一个名字,只要你想,只要我们常常使用同样的名字引用它:自己试试吧!
那么我们想在class为”description”的每一个段落之前添加这一块内容: “Figure number ” — 注意只有我们在引号里面写的内容才会被创建到页面中,所以我们也要添加一个空格!
然后,我们就有了counter(image):这将用到我们之前在.post选择器中定义的属性。它默认会从数字1开始。
下一个属性在那里表示计数器知道对于每一个p.description,它需要将image计数器增加1 (counter-increment: image)。
它并不像看起来的那么复杂,而且还会灰常的有用。
::before和::after伪元素常常只使用content属性,来添加一些短语或排版元素,但是这里我们展示了我们如果以一种更加强大的结合counter-reset和counter-increment属性的方式来使用它们。
有趣的是: ::first-line 和::first-letter 伪元素可以匹配使用::before伪元素生成的内容,如果存在的话。
浏览器支持
如果使用单个冒号的话(比如, :first-letter, 而不是::first-letter),这些伪元素被IE8支持(但是不被IE7或6支持)。但是左右其他的主流浏览器都支持这些选择器。
结语
乏味的讲述终于结束了,现在该你来领悟本文的要义并自己尝试了: 开始通过创建实验性的页面并测试所有的这些选择器,在有疑问的时候返回这里并确保总是遵循W3C的规则,但是请不要只是坐在那里想这些选择器尚未被完全支持你就无视它们。
如果你敢于冒险,或者你不害怕放弃之前的遍地无用和非语义化的class和id,为什么不尝试一两个这些强大的CSS选择器到你的下一个项目中呢?我们保证你不会回头的!
原文地址:http://www.qianduan.net/taming-advanced-css-selectors.html