下面是一段普通的代码:
css:
border:1px solid #ccc;
font-size:12px;
background:#F1F1F1;
padding:10px;
}
html:
但是这个时候需求增加了,在页面中不仅要有一个灰色的盒子可能还有蓝色的盒子,可能还有绿色(仅仅颜色不同,其他属性一样).
通常我们会想到:用群组选择器,把有相同定义的不同选择器放在一起,省了很多代码(其实就是一种简写)。好我们就做如下更改:
css:
.box-green{
border:1px solid #ccc;
font-size:12px;
padding:10px;
}
.box-gray{background:#F1F1F1}
.box-green{background:#66FF66}
html:
<div class="box-green">this is a green box</div>
但是这个时候需求又有变化了,根与应用的不同,盒子中有些要用到12号字,有些要用到14号字,有些要变局10px有些要20px,估计这个时候你就要头大了,用上面的方法来实现这个需求已经不再那么简练了,css代码会变得异常的复杂,那我们就来试验一下用组合的方式看能不能解决。
css:
.fs-14{font-size:14px}
.pd-10{padding:10px}
.pd-20{padding:20px}
.box{border:1px solid #ccc;}
.box.gray{background:#f1f1f1}
.box.green{background:#66ff66}
Html
<div class="box green fs-14 pd-10">this a gray fontsize14px padding10px box</div>
虽然在class上组合了好几个类,但是代码和逻辑都非常清晰,而且非常容易维护,随意组合随意扩展。从上面可以看到“组合”方式的优点是不言而喻的,但也不是十全十美,在拆分组合的时候一定不要过度,不然效果可能适得其反,每一个知识点要使用的恰到好处,和有效的组合起来才能让我们的代码更加优雅和艺术。
上面的样式用到了类选择器,下面就来看看CSS中几个常用的选择器:
类选择器
在 CSS 中,类选择器以一个点号显示:
在下面的 HTML 代码中,h1 和 p 元素都有 center 类。这意味着两者都将遵守 ".center" 选择器中的规则。
This heading will be center-aligned
</h1>
<p class="center">
This paragraph will also be center-aligned.
</p>
注意:类名的第一个字符不能使用数字!它无法在 Mozilla 或 Firefox 中起作用
ID选择器
id 选择器可以为标有特定 id 的 HTML 元素指定特定的样式。
id 选择器以 "#" 来定义。
下面的两个 id 选择器,第一个可以定义元素的颜色为红色,第二个定义元素的颜色为绿色:
#green {color:green;}
下面的 HTML 代码中,id 属性为 red 的 p 元素显示为红色,而 id 属性为 green 的 p 元素显示为绿色。
<p id="green">这个段落是绿色。</p>
注意:id 属性只能在每个 HTML 文档中出现一次。
派生选择器
通过依据元素在其位置的上下文关系来定义样式,通过合理地使用派生选择器,可以使标记更加简洁(每个标签用空格隔开)。
比方说,你希望列表中的 strong 元素变为斜体字,而不是通常的粗体字,可以这样定义一个派生选择器:
font-style: italic;
font-weight: normal;
}
请注意标记为 <strong> 的蓝色代码的上下文关系:
<p><strong>我是粗体字,不是斜体字,因为我不在列表当中,所以这个规则对我不起作用</strong></p> <ol><li><strong>
我是斜体字。这是因为 strong 元素位于 li 元素内。</strong></li>
<li>我是正常的字体。</li> </ol>
在上面的例子中,只有 li 元素中的 strong 元素的样式为斜体字,无需为 strong 元素定义特别的 class 或 id,代码更加简洁。
再看看下面的 CSS 规则:
strong {
color: red;
}
h2 {
color: red;
}
h2 strong
{
color: blue;
}
下面是它施加影响的 HTML:
<p>The strongly emphasized word in this paragraph is<strong>red</strong>.</p> <h2>This subhead is also red.</h2><h2>
The strongly emphasized word in this subhead is<strong>
blue</strong>
.</h2>
另外css有“优先级”的问题,即是指CSS样式在浏览器中被解析的先后顺序,优先级低的先解析,优先级高的后解析,后解析的覆盖先解析的(后来居上)。
那么这就存在一个优先级高低的判断问题,其实是有这么一个规律的:
一般而言,选择器越特殊,它的优先级越高。也就是选择器指向的越准确,它的优先级就越高。通常我们用1表示标签名选择器的优先级,用10表示类选择器的优先级,用100标示ID选择器的优先级。
例子:
- <div class="polaris">
- <span class="beijixing">
- beijixing
- </span>
- <span>
- polaris
- </span>
- </div>
如果通过.polaris span {color:red;} 把.polaris下面span内的字体设置成红色,这时,如果要改变.beijixing的颜色为蓝色,用下面的命令是不能实现的:
- .beijixing {color:blue;}
出现这种情况就是因为后一个命令的优先级较前一个命令的优先级低,后一个命令先执行,再执行前一个命令导致的。
比如上例当中 .polaris span {color:red;}的选择器优先级是 10 + 1 也就是11;而 .polaris 的优先级是10;浏览器自然会显示红色的字。
正因为有了优先级这个概念,在考虑选择器时要做到:
第一:准确的定位要控制的标签;
第二:使用最合理优先级的选择器;
第三:HTML和CSS代码尽量简洁美观。
派生选择器的定位原则(该原则设计到匹配的效率,就是查找到符合该css声明中选择器对应的html标签的速度)
在这里介绍一下对于派生选择器,浏览器是如何查找元素的呢?
浏览器CSS匹配不是从左到右进行查找,而是从右到左进行查找。比如DIV#divBox p span.red{color:red;},浏览器的查找顺序如下:先查找html中所有class='red'的span元素,找到后,再查找其父辈元素中是否有p元素,再判断p的父元素中是否有id为divBox的div元素,如果都存在则匹配上。
浏览器从右到左进行查找的好处是为了尽早过滤掉一些无关的样式规则和元素。比如如下html和css:
- <style>
- DIV#divBox p span.red{color:red;}
- ><style>
- <body>
- <div id="divBox">
- <p><span>s1</span></p>
- <p><span>s2</span></p>
- <p><span>s3</span></p>
- <p><span class='red'>s4</span></p>
- </div>
- </body>
如果按从左到右查找,哪会先查找到很多不相关的p和span元素。而如果按从左到右的方式进行查找,则首先就查找到<span class='red'>的元素。firefox称这种查找方式为key selector(关键字查询),所谓的关键字就是样式规则中最后(最右边)的规则,上面的key就是span.red。
对于派生层级关系,尽量做到简练,不要做不必要的匹配,以提高效率,和可读性。
如:不要在ID选择器前使用标签名
一般写法:DIV#divBox
更好写法:#divBox
解释: 因为ID选择器是唯一的,加上div反而增加不必要的匹配。(扩充理解:)。
最后有一点要注意:CSS 对大小写不敏感。不过存在一个例外:如果涉及到与 HTML 文档一起工作的话,class 和 id 名称对大小写是敏感的。
附网上另外的一些总结:
1.派生选择器是CSS里最昂贵的选择器,昂贵得可怕——特别是当它放在标签和通用符后面时。 就如下面这个东东一样,绝对的效率毒瘤:
html body ul li a { }
2.一个选择器渲染失败比这个选择器被渲染更高效
我不是很确定是否有更好的证据去证明这一点,因为如果你有大量的选择器在CSS样式表里无法找到,这样的事情貌似很离奇,但一点必需注意的是,从右到左的解释一个选择器来说,一旦它找不到,那它就会停止尝试。然而如果它找到了,那它就需要花更多精力去解释了。
试想一下为何你这样写选择器
思考下这东东:
#main-navigation li a { font-family: Georgia, Serif; }
你可能不需要从 a 选择器开始(如果你只是想换个字体)。下面这个可能更高效些:
#main-navigation { font-family: Georgia, Serif; }
我的理解:仅仅想改变#main-navigation下的li的a的字体,按图索骥的描述层级关系固然没错,但太固执了忽略了效率。
12