Web标准化运动的口号——分离、分离、分离。

在2003年的 SXSW 会议中, Steve Champeon 和 Nick Finck 做了一个名为“面向未来的全方位 Web 设计”的演讲,揭示了这种 Web 开发新方法的蓝图。 Steve 还给它取了个名称:渐进增强(Progressive Enhancement)。

从内容花生开始,将其标记为富含语义的 (X)HTML,接着给内容裹上一层富含奶油的 CSS。 最后,添加 JavaScript 作为糖果硬壳,这就做成了一颗可口无比的美味(并使得它不会在你手里融化)。1

CSS在其中扮演及其重要的角色。CSS 是 Cascading Style Sheets 的缩写,即层叠样式表。 为什么叫做“层叠样式表”呢?这跟它的特征有关系:层叠。

样式表可能有三种不同的来源:作者、用户和用户端。通俗的讲,作者就是开发者,用户就是使用浏览器的人,用户端就是浏览器。

这三种来源的样式表可能在范围上有重叠。比如,都设置了 P 元素的背景色和字体颜色。它们根据层叠的规则互相作用。

CSS 层叠对每一个样式规则2指定一个权重。如果要应用若干个规则,那么权重最大的那个规则具有优先权。

缺省时,作者样式表规则较用户样式表规则优先级高。不过,对于 "!important" 规则,保留其优先级。所有的用户规则和作者规则的权重都比浏览器缺省样式表中规则的权重大。

用户端样式表

来自浏览器的样式,被称作 UA style,是浏览器默认的样式。 比如,对于 DIV 元素,浏览器默认其 'display' 的特性值是 "block",而 SPAN 是 "inline"。

在 Firefox 的地址栏中输入:resource://gre/res/html.css,即可得到 Firefox 的浏览器默认样式表。

用户样式表

这个样式表是使用浏览器的用户,根据自己的偏好设置的样式表。

比如,用户希望所有 P 元素中的字体都默认显示成蓝色,可以先定义一个样式表,存成 css 文件。CSS 代码:

p{ color:blue; }

然后按下面的说明来设置即可。

1). IE

创建一个 CSS 文件,定义样式。然后,按如下图示,设置用户样式表,选择浏览,指向自定义样式。

2). Firefox

按以下步骤:

  1. 找到 Firefox 的 profile,Windows 下在这里:用户名\AppData\Roaming\Mozilla\Firefox\Profiles\dbsujefc.default\chrome。
    也可以这样打开: 帮助-->疑难排解信息-->应用基础-->打开所在文件夹-->chrome;
  2. 创建一个名为 userContent.css 的 CSS 文件,编辑加入所需要的样式。注意名字必须叫 userContent.css,不能更改。否则无效;
  3. 保存 userContent.css 文件然后重启 Firefox。

3). Chrome

Chrome 定义用户样式的方式暂未找到。

4). Safari

创建一个 CSS 文件,定义样式。然后,按如下图示,设置用户样式表。

5). Opera

创建一个 CSS 文件,定义样式。然后,按如下图示,设置用户样式表。

作者样式表

即开发者在开发网页时,所定义的样式表。

注:

  1. 以上内容译自Understanding Progressive Enhancement。最后一句话的幽默源自著名的巧克力广告词:只溶于口,不溶于手!
  2. 这里说到的“规则”,通俗的讲,就是定义的样式,或者 CSS 声明

!important 规则1

根据 CSS2.1 规范中的描述,'!important' 可以提高样式的优先级,它对样式优先级的影响是巨大的。
注意,'!important' 规则在 IE7 以前的版本中是被支持不完善。因此,经常被用作 CSS hack2

为了平衡开发者设置的样式和浏览器用户设定的样式,默认开发者的样式优于浏览器用户设置的样式;另外,声明了 '!important' 的样式优于普通声明。

注:

  1. 关于 '!important' 的详细信息,请参考 CSS2.1 规范 6.4.2 !important rules 中的内容;
  2. 见:

CSS 层叠顺序( Cascading order )

为了找到元素/特性组合的值,用户端必须应用如下的排列顺序:

  1. 对于目标媒介类型 (media type),找到存有疑问的元素和属性的所有声明。如果相关联的选择器匹配存有疑问的元素,并且目标媒介匹配包含声明并且和样式表的路径在所有链接上达到一致的 @media 规则中所有的媒介列表。
  2. 根据 CSS 样式的来源和重要性(是否含 !important ),给出了优先级的升序排列:
    • 用户端声明( UA declarations )
    • 一般用户声明( user normal declarations )
    • 一般作者声明( author normal declarations )
    • 加了 '!important' 的作者声明( author important declarations )
    • 加了 '!important' 的用户声明( user important declarations )
  3. 拥有相同重要性和来源的规则,按照 CSS specificity 来排序。此处,需要注意一下层叠顺序和选择器的特殊性1的关系。
    选择器的特殊性是在相同来源,相同重要性的规则之间判定最终哪个规则会起作用。
    比如, 同是开发者自己定义的样式,并且,没有使用 "!important" 规则,这样的样式才可以计算特殊性。
  4. 最后,根据先后次序来排列:如果两条规则具有相同的权重,相同的来源和相同的选择器特殊性,则后出现的规则超越先出现的规则。
    引入的样式表( @import )中的规则被认为出现在样式表本身的所有规则之前。

例:

用户自定义样式,userContent.css:

p{
background-color:black;
color:red !important;
}

按照上节中的做法,给浏览器设置用户样式。

测试页面,test.html:

<style>
p {
color: green !important;
}
</style>
<p style="background-color : white; color : blue;"> hello!! </p>

可自行测试结果。

注:

  1. 选择器的特殊性,即下节的 Selector's specificity

计算选择器的特殊性( Selector's specificity )

正如上面提到的,根据层叠顺序,优先级相同的样式,如何判断哪一条声明会起作用,取决于对其选择器特殊性的计算值。

例如,都是作者样式,并且没有使用 '!important' 规则:

<!DOCTYPE HTML>
<style type="text/css">
div {
width: 100px;
height: 100px;
}
#c1 #c2 div.con {
background-color: yellow;
}
div {
background-color: black;
}
#c2 div {
background-color: blue;
}
#c2 #content {
background-color: red;
}
</style>
<div id="c1">
<div id="c2">
<div id="content" class="con"></div>
</div>
</div>

如上代码中,多个样式中的 'background-color' 同时作用于 content,那么最后,到底 content 应该会是什么颜色呢?

这就应该求助于选择器特殊性的计算规则了。

特殊性的值可以看作是一个由四个数组成的一个组合,用 a,b,c,d 来表示它的四个位置。 依次比较 a,b,c,d 这个四个数比较其特殊性的大小。比如,a 值相同,那么 b 值大的组合特殊性会较大,以此类推。 注意,W3C 中并不是把它作为一个 4 位数来看待的。

a,b,c,d 值的确定规则:

  1. 如果 HTML 标签的 'style' 属性中该样式存在,则记 a 为 1;
  2. 数一下选择器中 ID 选择器的个数作为 b 的值。比如,以上样式中包含 '#c1' 和 '#c2' 的选择器;
  3. 其他属性以及伪类(pseudo-classes)的总数量是 c 的值。比如,上面例子中的 '.con',':hover' 等;
  4. 元素名和伪元素的数量是 d 的值;比如上面例子中的 ‘div’。

现在,应用上面的规则,计算例子中各个样式的特殊性的值,结果为:

<!DOCTYPE HTML>
<style type="text/css">
div {
width: 100px;
height: 100px;
}
#c1 #c2 div.con { /* a=0 b=2 c=1 d=1 -> specificity = 0,2,1,1 */
background-color: yellow;
}
div { /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */
background-color: black;
}
#c2 div { /* a=0 b=1 c=0 d=1 -> specificity = 0,1,0,1 */
background-color: blue;
}
#c2 #content { /* a=0 b=2 c=0 d=0 -> specificity = 0,2,0,0 */
background-color: red;
}
</style>
<div id="c1">
<div id="c2">
<div id="content" class="con"></div>
</div>
</div>

可见,'#c1 #c2 div.con" 的特殊性( [0,2,1,1] )最高,是背景色应该是黄色。

W3C 官方给出的例子:

*             {}  /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */
li {} /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */
li:first-line {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
ul li {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
ul ol+li {} /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */
h1 + *[rel=up]{} /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */
ul ol li.red {} /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */
li.red.level {} /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */
#x34y {} /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */
style="" /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */
------------------------------------------------------------------------
<HEAD>
<STYLE type="text/css">
#x97z { color: red }
</STYLE>
</HEAD>
<BODY>
<P ID=x97z style="color: green">
</BODY>

如上代码中,P 中字体的颜色应该为绿色。

非 CSS 显示的优先级

用户端应该优先考虑那些不是来自样式表的显示属性。如果是这样,这些非CSS呈现提示必须被转换到相应的CSS规则, 且其特殊性为零( 既,使其特殊性最低 ),并认为它的引入处于样式表的最顶端。它们可能被后续的样式规则所覆盖,

在 HTML 中,任何不属于以下列表中的属性都需要以显示属性对待:abbr, accept-charset, accept, accesskey, action, alt, archive, axis, charset, checked, cite, class, classid, code, codebase, codetype, colspan, coords, data, datetime, declare, defer, dir, disabled, enctype, for, headers, href, hreflang, http-equiv, id, ismap, label, lang, language, longdesc, maxlength, media, method, multiple, name, nohref, object, onblur, onchange, onclick, ondblclick, onfocus, onkeydown, onkeypress, onkeyup, onload, onload, onmousedown, onmousemove, onmouseout, onmouseover, onmouseup, onreset, onselect, onsubmit, onunload, onunload, profile, prompt, readonly, rel, rev, rowspan, scheme, scope, selected, shape, span, src, standby, start, style, summary, title, type (except on LI, OL and UL elements), usemap, value, valuetype, version.

例如,对于 align1 属性,各浏览器应当将它转换成 CSS 中的浮动。

注:

  1. 相关问题和解释,请参见:W3Help -- RX8015: IE6 IE7 IE8(Q) 没有完全正确地将 IMG、OBJECT、IFRAME、TABLE 元素的 align="left|right" 理解为浮动

CSS 层叠及样式表来源的更多相关文章

  1. web前端篇:CSS使用,样式表特征,选择器

    目录 web前端篇:CSS使用,样式表特征,选择器 1.CSS介绍 2.CSS使用 3.样式表特征 4.CSS选择器 5.选择器的优先级 6.练习题: web前端篇:CSS使用,样式表特征,选择器 1 ...

  2. CSS重构:样式表性能调优

    这两天窝在家里又看了本CSS相关的书:<CSS重构:样式表性能调优>.重构是指在不改变代码行为的前提下,重写代码,使其更加简洁.易于复用. 这本书读起来比较快,可挑自己感兴趣的读,前面三章 ...

  3. css三种样式表写法

    css三种样式表:1.内嵌样式表: <head>  <style type="text/css">   样式表写法  </style> < ...

  4. css选择器,样式表导入

    css笔记1.选择器(selecter)共9种 a.类型选择器 p{},body{} b.后代选择器 p h1{} c.ID选择 #idname{} d.类选择 .classname{} e.通用选择 ...

  5. [19/06/05-星期三] CSS基础_样式表的位置(内联、内部、外部样式)、块元素(div)、内联元素(span)、常用的选择器

    一.概念 CSS(Cascading Style Sheets,层叠样式表) 可以用来为网页创建样式表,通过样式表可以对网页进行装饰. 所谓层叠,就是可以将整个网页想象成是一层一层的结构,层次高的将会 ...

  6. CSS三种样式表

    1.外部样式表当样式需要应用于很多页面时,外部样式表将是理想的选择.在使用外部样式表的情况下,你可以通过改变一个文件来改变整个站点的外观.每个页面使用 <link> 标签链接到样式表. & ...

  7. Normalize.css重置化样式表

    Normalize.css是一种CSS reset的替代方案.它在默认的HTML元素样式上提供了跨浏览器的高度一致性.相比于传统的CSS reset,Normalize.css是一种现代的.为HTML ...

  8. CSS 四种样式表 六种规则选择器 五种常用样式属性

    新的html程序要在VS中编写了,在vs中安装ASP.NET和Web开发,并用ASP.NET Web 应用程序(.NETFramework)创建一个网页程序.添加一个html页 后面的代码都是在htm ...

  9. css网页重置样式表(多版本)

    Eric reset.css html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, ...

随机推荐

  1. include_path详细解析

    include_path详细解析     原文地址:http://www.laruence.com/2010/05/04/1450.html 1.php默认的包含路径为 .;C:\php\pear 即 ...

  2. centos7 安装教程

    1. 在安装的时候,不要用默认的最小安装.选择GNOME Desktop 2.自动分区的时候,选择自己进行分区 2个分区,1个大小为1024M的swap分区,剩下的分配一个ext3的分区.设备类型都选 ...

  3. FRM-10001, FRM-10002, FRM-10003 Oracle Form Builder Error Solution

    These errors occurred usually due to forms connection problem or some internal problem, the solution ...

  4. Django忘记管理员账号和密码的解决办法

    看着Django的教程学习搭建网站,结果忘记第一次创建的账号和密码了.结果搭建成功以后,一直无法登陆到管理页面,进行不下去了. 如图所示: 在网上找了很多的方法都不行,最后使用新建一个superuse ...

  5. 01_Spring概述

    Spring概述 1.什么是Spring ? Spring是分层的JavaSE/EE full-stack(一站式) 轻量级开源框架 * JavaEE 程序在服务器端被分为三层(Web层[表现层].业 ...

  6. CentOS6.4_常用命令

    1. 查看本机是否安装了 xxx软件,以及 xxx软件 的版本信息等: rpm -qa |grep  xxx(xxx代表软件名) 2. rpm -ivh 要安装的rpm文件包 3. 不care依赖项的 ...

  7. jquery.pagination.js分页

    参数说明 参数名 描述 参数值 maxentries 总条目数                           必选参数,整数 items_per_page 每页显示的条目数            ...

  8. MVC中Url请求与控制器的默认约定

    1.请求的url如:http://localhost:52481/Home/Browse?genre=1控制器方法:public string Browse(string genre) //这里返回值 ...

  9. python多线程下载

    # -*- coding=utf-8 -*- import sys import os import os.path import time import urllib.request, urllib ...

  10. lmdb存储的一些库相关函数

    MDB_env 为一个结构体,Opaque structure for a database environment. MDB_txn :Opaque structure for a transact ...