Posted by akasuna on 2011年04月06日 at 9:30 AM
可能你已经学过了 CSS 的 ID 选择器、类选择器和后代选择器,但是这就够了吗?
可能不太够,对于 CSS 而言,还有很多灵活的使用方法。
本文将向你介绍一些常用的 CSS 选择器方法,其中有一些是 CSS3 选择器,只有比较新的浏览器才支持,但是这些新选择器同样要记住,因为像 IE6 之类旧浏览器终将被淘汰。
OK,开始。
1. *
* { margin: 0; padding: 0; }
此星号将选择当前页面内所有标签,相信很多人都使用过这招来清空浏览器默认的 margin 和 padding,如果是在测试的时候,用这招当然没什么问题,但是在正式的产品中尽量不要这样用,据说它会大大加重浏览器的负担,而且也没必要清空所有标签的 margin 和 padding。
* 同样可以作为子选择器使用:
#container * { border: 1px solid black; }
以上代码将为 ID 为 container 容器内所有标签加上一个像素宽的黑色实线边框。
2. #X
#container { width: 960px; margin: auto; }
以 # 开头的选择器允许我们根据 ID 来选择标签,这种选择器最为常用。ID 选择器用法比较严格,对于一个 HTML 文档而言,不允许出现 ID 相同的标签,因此 ID 选择器只能选择一个标签。
3. .X
.error { color: red; }
这个是类选择器,类选择器和 ID 选择器的区别是 HTML 中的类可以重复,也就是说通过类选择器可以选择多个标签,当 HTML 中的多个标签有共同特性时,可以把他们定义为一个类,这样在 CSS 中就可以很容易的选择它们。
4. X Y
li a { text-decoration: none; }
这个一般称为后代选择器。例如,你并不像选择所有超链接,而只想选择 li 标签中的超链接,就可以用后代选择器。
5. X
a { color: red; } ul { margin-left: 0; }
如果你想通过标签类型来选择页面上的所有标签,可以使用这种标签选择器。例如,你想要选择页面上所有超链接,可以使用 a { }。
6. X:visited 和 X:link
a:link { color: red; } a:visited { color: purple; }
这是伪类选择器,我们可以使用 a:link 来选择所有没被点击过的超链接,也可以用 :visited 来选择所有被点击过或访问过的超链接。
7. X + Y
ul + p { color: red; }
这个可以称为邻近选择器,以上面的代码为例,它只能选择紧跟着 ul 的 p 标签,而且只有 ul 后面的第一个 p 会被选中。
8. X > Y
div#container > ul { border: 1px solid black; }
X > Y 和 X Y 的不同之处前者只能选择 X 的直接后代。例如如下标签:
<div id="container"> <ul> <li> List Item <ul> <li> Child </li> </ul> </li> <li> List Item </li> <li> List Item </li> <li> List Item </li> </ul> </div>
基于以上 HTML 代码,#container > ul 选择器只能选择 id 为 container 的 div 下面的 ul,而 li 下面的 ul 却选择不到。
9. X ~ Y
ul ~ p { color: red; }
这种选择器和 X + Y 有相似之处,但是又没有 X + Y 严格,对于邻近选择器(ul + p)而言,只能选择紧跟着 ul 的第一个 p 标签,而 ul ~ p 却可以选择 ul 后面的所有 p 标签。
10. X[title]
a[title] { color: green; }
这个称为属性选择器,例如上面的代码,只能选择出具有 title 属性的超链接。
11. X[href="foo"]
a[href="http://akasuna.com"] { color: #1f6053; }
上面的 CSS 代码,只会选择链接到 http://akasuna.com 的超链接设置为绿色,而其它超链接则不受影响。如果你想为指向不同站点的超链接指定不同的颜色,这是个好方法。
12. X[href*="akasuna"]
a[href*="akasuna"] { color: #1f6053; }
这种方法更为常见,*= 表示指定的字符串必须出现在属性的值里面,这样一来,akasuna.com,demo.akasuna.com,bbs.akasuna.com 甚至是 akasuna2.com 都将被此选择器选择到。
13. X[href^="http"]
a[href^="http"] { background: url(path/to/external/icon.png) no-repeat; padding-left: 10px; }
有些网站会在超链接的旁边显示一个图标来表示此链接为外部链接,估计大多数人都见过这样的设计,此图标用来提醒访客,点击此链接将打开另外一个完全不同的网站。
其实要做到这点也很容易,只要判断一下超链接地址的开头部分就行了,如果超链接的 href 属性是以 http 开头的,那么就说明它是外部链接,就像上面的代码那样。
注意:我们这里判断的是
http而非http://,一是没必要,二是为了兼顾https://之情况。另外,使用这种方法的话,有一个前提,所有内部链接都用相对路径而非绝对路径,这样才能保证内部链接不是以
http开头。
如果我们要为那些链接向图片的超链接设置特定的样式呢,这种情况就要判断超链接地址的末尾部分了。
14. X[href$=".jpg"]
a[href$=".jpg"] { color: red; }
使用 $,表示的是字符串的末尾部分,这里我们要查找那些链接向图片的超链接,也就是 url 地址是以 .jpg 结尾的那些。注意,这里没有考虑 .gif 和 .png 的情况。
15. X[data-*="foo"]
a[data-filetype="image"] { color: red; }
接着上面的第 14 条,如果我们兼顾各种图片格式,例如:png,jpg,jpeg,gif,又该怎么办呢?你可能会想到下面这种方法:
a[href$=".jpg"], a[href$=".jpeg"], a[href$=".png"], a[href$=".gif"] { color: red; }
但是这样写起来稍微有点痛苦,而且低效。其实我们这里可以使用自定义属性,为所有指向图片的超链接添加一个属性 data-filetype,如:
<a href="path/to/image.jpg" data-filetype="image"> Image Link </a>
然后就可以在 CSS 里面使用标准的选择器来选择这些超链接了。
a[data-filetype="image"] { color: red; }
16. X[foo~="bar"]
a[data-info~="external"] { color: red; } a[data-info~="image"] { border: 1px solid black; }
参照上面的第 15 条那个自定义属性,我们可以创建一个 data-info 属性,这个属性值可以接收多个值:
<a href="path/to/image.jpg" data-info="external image"> Click Me, Fool </a>
这样一来,通过一个属性就可以表达两层意思:1. 它是外部链接;2. 它是指向图片的链接。然后就可以用 CSS 分别对此超链接设置样式:
/* 选择 data-info 属性中包含有 "external" 的那些超链接 */ a[data-info~="external"] { color: red; } /* 选择 data-info 属性中包含有 "image" 的那些超链接 */ a[data-info~="image"] { border: 1px solid black; }
17. X:checked
input[type=radio]:checked { border: 1px solid black; }
又是一个伪类选择器,它能选择那些被选中的标签,例如单选框、复选框等,用起来应该很简单。
18. X:after
这个不是伪类,而是伪元素,对应的还有 :before,从字面上看,它们分别表示元素的前面和后面,实际上它们的功能是在元素的前面或后面添加内容,需要和 CSS 的 content 属性配合使用,如:
h1:after { content:url(logo.gif) }
在显示时,标题内容后会插入一张图片,这就是伪元素 :after 的作用。
19. X:hover
div:hover { background: #e3e3e3; }
拜托,这个大家都会的,它表示当鼠标在元素上悬停时的样式。
注意:在老版本 IE 中,这个伪类只对超链接有效,对其它任何元素无效!
常见的用法是,当鼠标悬停的找链接上的时候,给超链接设置一个底部边框:
/* order-bottom: 1px solid black; 的效果看起来比 text-decoration: underline; 要好一些 */ a:hover { border-bottom: 1px solid black; }
20. X:not(selector)
div:not(#container) { color: blue; }
嗯,这个伪类选择器比较有用。试想一下,如果你要选择页面中除了 id 为 container 之外的所有 div,这段代码应该就是你想要的。
或者,你想要选择页面中除了 p 标签外的所有标签:
*:not(p) { color: green; }
但是这应该很少用到。
21. X::pseudoElement
p::first-line { font-weight: bold; font-size: 1.2em; }
我们可以使用伪元素(这里用的是 :: 哦)为元素的某部分设定样式,例如段落的第一行,或者第一个字母。切忌,这种方法只对块级元素起作用。
为段落的第一个字母设定样式:
p::first-letter { float: left; font-size: 2em; font-weight: bold; font-family: cursive; padding-right: 2px; }
这段代码将为页面上所有段落设置首字下沉的效果,这种样式在报纸上经常可以看到。
22. X:nth-child(n)
li:nth-child(3) { color: red; }
nth-child 伪类选择器以一个整数作为参数,不包括 0,要从 1 开始。如果你想选择列表元素中的第 2 个,可以使用 li:nth-child(2)。
这个方法当然也可以用来选择多个元素,例如 li:nth-child(4n) 就可以用来选择列表元素中的第 4 个,第 8 个,第 12 个 ……(4 的倍数)。
23. X:nth-last-child(n)
li:nth-last-child(2) { color: red; }
如果一个 ul 中的有 400 个条目,而你只想选择其中的倒数第 2 个,该怎么办呢?
相比 li:nth-child(399) 而言,nth-last-child(2) 也许更为适合。
24. X:nth-of-type(n)
ul:nth-of-type(3) { border: 1px solid black; }
有时候,你不是想选择 ul 中的第 3 个 li,而是想选择第 3 个 ul,而这些 ul 又没有 id, 该怎么办呢?
此时应该使用 nth-of-type(n),上述代码将为页面中的第三个 ul 设置一个 1 个像素的黑色边框。
25. X:nth-last-of-type(n)
ul:nth-last-of-type(3) { border: 1px solid black; }
请参照第 23 条中的 nth-last-of-type 自行理解。
26. X:first-child
ul li:first-child { border-top: none; }
这个伪类用来选择父元素中的第一个子元素,对应的还有 X:last-child。你可以用它来删除列表中第一个元素和最后一个元素的边框。
例如,有一个列表,如果列表中每个元素都有一个 border-top 和 border-bottom,那么第一个元素和最后一个元素的边框看起来就有点多余了。
很多人都会想到为第一个元素和最后一个元素分别设置一个 first 和 last 类名称,然后通过这个类名称清楚他们的边框。这样当然也是可以的,但是用伪类同样也可以达到效果,具体请看下面的第 27 条。
27. X:last-child
ul > li:last-child { color: green; }
和 first-child 对应,last-child 用来选择父元素中的最后一个子元素。结合上面的第 26 条,有如下示例:
HTML 代码
<ul> <li> List Item </li> <li> List Item </li> <li> List Item </li> </ul>
CSS 代码
ul { width: 200px; background: #292929; color: white; list-style: none; padding-left: 0; } li { padding: 10px; border-bottom: 1px solid black; border-top: 1px solid #3c3c3c; }
这段 CSS 代码为列表设置了背景色,消除了 ul 默认的内边距,并对每个 li 设置了边框,边框颜色深于 ul 的背景色。

问题来了,正如图片上所示,此无序列表的最顶端和最低端也有边框,这看起来有点不爽。下面我们用 :first-child 和 :last-child 来解决这个问题:
li:first-child { border-top: none; } li:last-child { border-bottom: none; }

效果如图所示,最顶端和最低端的边框没有了,问题解决了。
28. X:only-child
div p:only-child { color: red; }
实际上,你可能会发现 only-child 这种伪类并不常用,但是在某些场合,你还非用它不可。
only-child 用来选择那些是父元素中唯一的子元素的元素(独生子女!)。例如上面的代码,如果某个 div 中只有一个段落,那么这个段落将会以红色字体显示,如果有多个段落,则不受影响。
看下面的 HTML 代码:
<div> <p> My paragraph here. </p> </div> <div> <p> Two paragraphs total. </p> <p> Two paragraphs total. </p> </div>
这段 HTML 代码中,第二个 div 中有 2 个段落,这两个选择器不会被此选择器选择到;而第一个 div 中只有 1 个段落,因此这个段落是 only-child,它会以红色字体显示。
29. X:only-of-type
li:only-of-type { font-weight: bold; }
跟第 28 条类似,都是选择子元素。区别是:第 28 条中,选择的是唯一子元素(独生子女,不管是男的还是女的,反正只有一个);而第 29 条中,选择的是某类型的唯一元素(可以有多个孩子,但是性别不能相同,假如是两男一女,那么这个唯一女性将被选择到)。
30. X:first-of-type
first-of-type 伪类选择的是相同类型元素中的第一个元素。
为了便于理解,不妨来做个测试,请将如下代码拷贝至文本编辑器中:
<div> <p> My paragraph here. </p> <ul> <li> List Item 1 </li> <li> List Item 2 </li> </ul> <ul> <li> List Item 3 </li> <li> List Item 4 </li> </ul> </div>
此时,如果让你用 CSS 选择 List Item 2,该如何做呢?
方案一:
有多种方法可以达到效果,先来看第一种,使用 first-of-type
ul:first-of-type > li:nth-child(2) { font-weight: bold; }
这段代码的意思是,先找到页面中的 ul,找到了 2 个 ul,那么选择第 1 个,然后再此无序列表中选择第 2 个 li。
方案二:
第二种方法是用邻近选择器
p + ul li:last-child { font-weight: bold; }
找到紧跟着 p 元素的 ul,然后选择此 ul 中的最后一个 li 即可。
方案三:
ul:first-of-type li:nth-last-child(1) { font-weight: bold; }
跟方案一类似,先找到第一个 ul,然后找到其倒数第一个 li。
结语
如果你在使用如 IE 6 之类的低版本浏览器,那么以上有些比较新 CSS 选择器可能不适合。但是不要因为自己使用的是低版本浏览器,就不学习这些新的 CSS 选择器,不学的话吃亏的还是自己。这里有一个浏览器兼容性列表,另外你也可以使用 Dean Edward 的 IE9.js 让你的低版本 IE 支持一些IE9 的特性。
另外,当使用一些如 jQuery 之类的 JS 库的时候,尽量在使用过程中用标准的 CSS3 选择器,而非 JS 库自定义的选择器,如果可能的话,JS 库使用浏览器自身的 CSS 解析器,比使用 JS 库自定义的解析器 速度更快。
本文翻译自 The 30 CSS Selectors you Must Memorize,并稍作修改。基本上每种选择器都有对应的 DEMO,请至原文查看。
这一篇很全面啊,发现很多以前都没用到过,用全了的话能使调整页面样式更得心应手,收藏了。
可能也不是很全
但是这些应该是最常用的,我也是在其它网站上看到的,觉得不错,就转了。
第6点以后的选择器对IE6来说都是杯具
小白飘过…evernote了
作为基本,都要学习。
只用过,前面几种呵
后面的那些,老版本的 IE 都不太支持
暂时不用也好
又一位代码强人
其实也就是前面 6 中用得比较多
后面的那些,都还不常用
技术性东西我应该好好学学
的确用的着啊
俺是文盲!看不懂!实在不好意思了博主!但支持是肯定要的,呵呵!
浏览器兼容情况呢?
其实即使在老版本IE不死的情况下,后面那些在有些地方也很有用,比如用在Firefox的Usertyle脚本的时候,因为很多时候你想选择的元素指定ID或者Class,可能用一般的选择器选择不到
有机会要多请教请教啊,老大,不然被忽悠了就完蛋了
可惜IE大多都不支持。
好文章,非常喜欢!