CSS选择器、CSS hack及CSS执行效率
主要内容:
1.CSS选择器、优先级与匹配原理
2.CSS引入的方式有哪些? link和@import的区别是?
3.CSS hack
4.如何书高效CSS
一、CSS选择器、优先级与匹配原理
CSS选择器大概可以分为:1.id选择器(#myid) 2.类选择器(.myclassname) 3.标签选择器(div,h1,p) 4.相邻选择(h1+p)6.后代选择器(li a)7.通配符选择器(*) 8.属性选择器(a[rel=‘externaml‘]) 9.伪类选择器(a:hover)
选择器安类型分可以分为:元素选择器、关系选择器、伪类选择器、属性选择器、伪对象选择器
1.1 元素选择器
选择符 | 类型 | 版本 | 简介 |
* | 通配选择符 | CSS2 | 所有元素对象 |
E | 类型(HTML)选择符 | CSS1 | 以文档语言对象类型作为选择符 |
E#myid | id选择符 | CSS1 | 以唯一标识符id属性等于myid的E对象作为选择符 |
E.myclass | class选择符 | CSS1 | 以class属性包含myclass的E对象 |
备注:E是Element的缩写,表示元素的意思
1.2 关系选择器
选择符 | 类型 | 版本 | 简介 |
E F | 包含选择符 | CSS1 | 选择所有被E元素包含的F元素 |
E>F | 子选择符 | CSS2 | 选择所有作为E元素的所有直接子元素F, |
E+F | 相邻选择符 | CSS2 | 选择紧帐号在E元素之后F元素 |
E~F | 兄弟选择符 | CSS3 | 选择E元素所有兄弟元素F |
1.3 属性选择器
选择符 | 版本 | 简介 | 举例 |
E[att] |
CSS2 | 选择具有att属性的E元素 | |
E[att="val"] | CSS2 | 选择具有att属性值等于val的E元素 | |
E[att~="val"] | CSS2 | 选择具有att属性且属性值为用空格分隔的字词列表,其中一个等于val的E元素。 | |
E[att|="val"] | CSS2 | 选择具有att属性且属性值为以val开头并用连接符"-"分隔的字符串的E元素。 | |
E[att^="val"] | CSS3 | 选择具有att属性且属性值为以val开头的字符串的E元素。 | |
E[att$="val"] | CSS3 | 选择具有att属性且属性值为以val结尾的字符串的E元素。 | |
E[att*="val"] | CSS3 | 选择具有att属性且属性值为包含val的字符串的E元素。 |
1.4 伪类选择器
选择符 | 版本 | 简介 |
E:link |
CSS1 | 设置超链接a在未被访问前的样式。 |
E:visited | CSS1 | 设置超链接a在其链接地址已被访问过时的样式。 |
E:hover | CSS1/CSS2 | 设置元素在其鼠标悬停时的样式。 |
E:active | CSS1/CSS2 | 设置元素在被用户激活(在鼠标点击与释放之间发生的事件)时的样式。 |
E:focus | CSS1/CSS2 | 设置元素在成为输入焦点(该元素的onfocus事件发生)时的样式。 |
E:lang() | CSS2 | 匹配使用特殊语言的E元素。 |
E:not() | CSS3 | 匹配不含有s选择符的元素E。 |
E:root | CSS3 | 匹配E元素在文档的根元素。 |
E:fist-child | CSS2 | 匹配父元素的第一个子元素E。 |
E:last-child | CSS3 | 匹配父元素的最后一个子元素E。 |
E:only-child | CSS3 | 匹配父元素仅有的一个子元素E。 |
E:nth-child(n) | CSS3 | 匹配父元素的第n个子元素E。 |
E:nth-last-child(n) | CSS3 | 匹配父元素的倒数第n个子元素E。 |
E:first-of-type | CSS3 | 匹配同类型中的第一个同级兄弟元素E。 |
E:last-of-type | CSS3 | 匹配同类型中的最后一个同级兄弟元素E。 |
E:only-of-type | CSS3 | 匹配同类型中的唯一的一个同级兄弟元素E。 |
E:nth-of-type(n) | CSS3 | 匹配同类型中的第n个同级兄弟元素E。 |
E:nth-last-of-type(n) | CSS3 | 匹配同类型中的倒数第n个同级兄弟元素E。 |
E:empty | CSS3 | 匹配没有任何子元素(包括text节点)的元素E。 |
E:checked | CSS3 | 匹配用户界面上处于选中状态的元素E。(用于input type为radio与checkbox时) |
E:enabled | CSS3 | 匹配用户界面上处于可用状态的元素E。 |
E:disabled | CSS3 | 匹配用户界面上处于禁用状态的元素E。 |
E:target | CSS3 | 匹配相关URL指向的E元素。 |
@page:first | CSS3 | 设置页面容器第一页使用的样式。仅用于@page规则 |
@page:left | CSS3 | 设置页面容器位于装订线左边的所有页面使用的样式。仅用于@page规则 |
@page:right | CSS3 | 设置页面容器位于装订线右边的所有页面使用的样式。仅用于@page规则 |
1.5 伪对象选择器
选择符 | 版本 | 简介 |
E:first-letter/E::first-letter | CSS1/CSS3 | 设置对象内的第一个字符的样式。 |
E:first-line/E::first-line | CSS1/CSS3 | 设置对象内的第一行的样式。 |
E:before/E::before | CSS2/CSS3 | 设置在对象前(依据对象树的逻辑结构)发生的内容。用来和content属性一起使用 |
E:after/E::after | CSS2/CSS3 | 设置在对象后(依据对象树的逻辑结构)发生的内容。用来和content属性一起使用 |
E::selection | CSS1/CSS3 | 设置对象被选择时的颜色。 |
计算指定选择器的优先级:重新认识CSS的权重
- 通配选择符的权值 0,0,0,0
- 标签的权值为 0,0,0,1
- 类的权值为 0,0,1,0
- 属性选择的权值为
0,0,1,10,0,1,0 - 伪类选择的权值为 0,0,1,0
- 伪对象选择的权值为 0,0,0,1
- ID的权值为 0,1,0,0
- important的权值为最高 1,0,0,0
使用的规则也很简单,就是 选择器的权值加到一起,大的优先;如果权值相同,后定义的优先 。虽然很简单,但如果书写的时候没有注意,很容易就会导致CSS的重复定义,代码冗余。
从上面我们可以得出两个关键的因素:
- 权值的大小跟选择器的类型和数量有关
- 样式的优先级跟样式的定义顺序有关
总结:
比较同一级别的个数,数量多的优先级高,如果相同即比较下一级别的个数 ,至于各级别的优先级,大家应该已经很清楚了,就是:
important > 内联 > ID > 类 >
标签 | 伪类 | 属性选择 > 伪对象 > 继承 > 通配符 通配符 > 继承
这也就解释了为什么11个标签的定义会比不上1个类的定义,1个类加11个标签会比不上2个类的权重高。
二.CSS引入的方式有哪些? link和@import的区别是?
共有四种引入方式分别是:
1.使用STYLE属性,将STYLE属性直接加在个别的元件标签里(如:TD
STYLE="COLOR:BLUE; font-size:9pt; font-family:"标楷体";
line-height:150%>
这种用法的优点是可灵巧应用样式于各标签,但是缺点则是没有整篇文件的【统一性】)
2. 使用STYLE标签 将样式规则写在<STYLE>...</STYLE>标签之中。 (如:<STYLE TYPE="text/css"> <!-- body {color: #666;background: #f0f0f0;font-size: 12px;} td,p {color:#c00;font-size: 12px;} --> </STYLE> 这种用法的优点就是在於整篇文件的统一性,只要是有声明的的元件即会套用该样式规则。缺点就是在个别元件的灵活度不足。 )
3. 使用 LINK标签 将样式规则写在.css的样式文件中,再以<link>标签引入。(如: <link rel=stylesheet type="text/css" href="example.css"> 这种用法的优点就是在於可以把要套用相同样式规则的数篇文件都指定到同一个样式档案即可。缺点也是在个别文件或元件的灵活度不足。 )
2. 使用@import引入 跟link方法很像,但必须放在<STYLE>...</STYLE> 中 <STYLE TYPE="text/css"> <!-- @import url(css/example.css); --> </STYLE>
三.CSS
hack
3.1 什么是CSS hack
由于不同的浏览器,甚至同一浏览器的不同版本对CSS的解析认识不一样,导致生成的页面效果不一致,写出针对不同浏览器CSS code就称为CSS hack。
常用的CSS hack 有三种:条件Hack、属性级Hack、选择符级Hack
条件Hack
语法:
<!--[if <keywords>? IE
<version>?]> HTML代码块 <![endif]-->
取值:
<keywords>
if条件共包含6种选择方式:是否、大于、大于或等于、小于、小于或等于、非指定版本
是否:指定是否IE或IE某个版本。关键字:空
- 大于:选择大于指定版本的IE版本。关键字:gt(greater than)
- 大于或等于:选择大于或等于指定版本的IE版本。关键字:gte(greater than or equal)
- 小于:选择小于指定版本的IE版本。关键字:lt(less than)
- 小于或等于:选择小于或等于指定版本的IE版本。关键字:lte(less than or equal)
- 非指定版本:选择除指定版本外的所有IE版本。关键字:!
- 示例:
1 <!DOCTYPE html> 2 <html lang="zh-cn"> 3 <head> 4 <meta charset="utf-8" /> 5 <title>if条件Hack_CSS参考手册_web前端开发参考手册系列</title> 6 <meta name="author" content="Joy Du(飘零雾雨), dooyoe@gmail.com" /> 7 <meta name="copyright" content="www.doyoe.com" /> 8 <style> 9 h1{margin:10px 0;font-size:16px;} 10 span{display:none;} 11 .not-ie{display:inline;} 12 </style> 13 <!--[if IE]> 14 <style> 15 .ie{display:inline;} 16 .not-ie{display:none;} 17 </style> 18 <![endif]--> 19 20 <!--[if IE 5]> 21 <style> 22 .ie5{display:inline;} 23 </style> 24 <![endif]--> 25 26 <!--[if IE 6]> 27 <style> 28 .ie6{display:inline;} 29 </style> 30 <![endif]--> 31 32 <!--[if IE 7]> 33 <style> 34 .ie7{display:inline;} 35 </style> 36 <![endif]--> 37 38 <!--[if IE 8]> 39 <style> 40 .ie8{display:inline;} 41 </style> 42 <![endif]--> 43 44 <!--[if IE 9]> 45 <style> 46 .ie9{display:inline;} 47 </style> 48 <![endif]--> 49 </head> 50 <body> 51 <div> 52 您正在使用 53 <span class="not-ie">非IE</span> 54 <span class="ie">IE</span> 55 <span class="ie5">5</span> 56 <span class="ie6">6</span> 57 <span class="ie7">7</span> 58 <span class="ie8">8</span> 59 <span class="ie9">9</span> 60 浏览器 61 </div> 62 </body> 63 </html> 64
属性Hack
示例:
1 <!DOCTYPE html> 2 <html lang="zh-cn"> 3 <head> 4 <meta charset="utf-8" /> 5 <title>属性级Hack_CSS参考手册_web前端开发参考手册系列</title> 6 <meta name="author" content="Joy Du(飘零雾雨), dooyoe@gmail.com" /> 7 <meta name="copyright" content="www.doyoe.com" /> 8 <style> 9 h1{margin:10px 0;font-size:16px;} 10 .test{ 11 color:#c30; /* For Firefox */ 12 [;color:#ddd;]; /* For webkit(Chrome and Safari) */ 13 color:#090\0; /* For Opera */ 14 color:#00f\9; /* For IE8+ */ 15 *color:#f00; /* For IE7 */ 16 _color:#ff0; /* For IE6 */ 17 } 18 </style> 19 </head> 20 <body> 21 <div class="test">在不同浏览器下看看我的颜色吧</div> 22 </body> 23 </html> 24
选择符级Hack
示例代码:
1 <!DOCTYPE html> 2 <html lang="zh-cn"> 3 <head> 4 <meta charset="utf-8" /> 5 <title>选择符级Hack_CSS参考手册_web前端开发参考手册系列</title> 6 <meta name="author" content="Joy Du(飘零雾雨), dooyoe@gmail.com" /> 7 <meta name="copyright" content="www.doyoe.com" /> 8 <style> 9 * html .test{color:#090;} 10 * + html .test{color:#ff0;} 11 .test:lang(zh-cn){color:#f00;} 12 .test:nth-child(1){color:#0ff;} 13 </style> 14 </head> 15 <body> 16 <div class="test">在不同浏览器下看看我的颜色吧</div> 17 </body> 18 </html> 19
CSS Hack 的顺序
使用 Firefox 作为平台, 只要代码写得够标准, 其实要 Hack 的地方不会很多的, IE 以外的浏览器几乎都不会有问题, 所以可以暂时忽略,顺序如下:Firefox -> IE6 -> IE7 -> 其他
四、关于CSS的执行效率
- 样式系统从最右边的选择符开始向左进行匹配规则。只要当前选择符的左边还有其他选择符,样式系统就会继续向左移动,直到找到和规则匹配的元素,或者因为不匹配而退出。
- 如果你非常在意页面的性能那千万别使用CSS3选择器。实际上,在所有浏览器中,用 class 和 id 来渲染,比那些使用同胞,后代选择器,子选择器(sibling, descendant and child selectors)对页面性能的改善更值得关注。
- ID最快,Universal最慢 有四种类型的key selector,解析速度由快到慢依次是:ID、class、tag和universal
-
不要tag-qualify (永远不要这样做 ul#main-navigation { } ID已经是唯一的,不需要Tag来标识,这样做会让选择器变慢。)
-
后代选择器最糟糕(换句话说,下面这个选择器是很低效的: html body ul li a { })
-
CSS3的效率问题(CSS3选择器(比如 :nth-child)能够漂亮的定位我们想要的元素,又能保证我们的CSS整洁易读。但是这些神奇的选择器会浪费很多的浏览器资源。)
Google 资深web开发工程师Steve Souders对CSS选择器的效率从高到低做了一个排序:
- 1.id 选择器(#myid)2.类选择器 (.myclassname)3.标签选择器(div,h1,p)4.相邻选择器(h1+p)5.子选择器(ul < li)6.后代选择器(li a)7.通配符选择器(*)8.属性选择器(a[rel="external"])9.伪类选择器(a:hover,li:nth-child)
- 上面九种选择器中ID选择器的效率是最高,而伪类选择器的效率则是最低
- 详细的介绍大家还可以点击Writing efficient CSS selectors。
以上内容都本人从博客园和其它相关资料总结出来的,希望对家有帮忙,有写的不对地方请大家多谅解,谢谢!!