解析
一旦 CSS 被浏览器下载, CSS 解析器就会被打开来处理它遇到的任何 CSS. 这可以是单个文档内的 CSS,<style > 标记内的 CSS, 也可以是 DOM 元素的 style 属性内嵌的 CSS. 所 有 CSS 都根据语法规范进行解析和标记. 解析完成后, 就会生成有一个包含所有选择器, 属性和属性各自值的数据结构.
例如, 考虑以下 CSS:
- .fancy-button {
- background: green;
- border: 3px solid red;
- font-size: 1em;
- }
以上 CSS 片段将生成如下数据结构, 以便在后续的过程中方便使用:
值得注意的一件事是, 浏览器将 background 和 border 的简写还原成普通写法, 也就是一个一个属性的声明, 因为简单写主要方便开发人员的编写, 但从这里开始, 浏览器只处理普通写法. 完解析成之后, 浏览器引擎继续构建 DOM 树.
计算
既然我们已经解析了现有内容中的所有样式, 接着就是对它们进行样式计算了. 我们尝试尽量对所有值减少到一个标准化的计算值. 当离开计算阶段时, 任何维度值都被缩减为三个可能的输出之一: auto, 百分比或像素值. 为了清晰起见, 让我们看几个例子, 看 web 开发人员写了什么, 以及计算后的结果:
现在我们已经计算了数据存储中的所有值, 是时候处理级联了.
级联
由于 CSS 来源有多种, 所以浏览器需要一种方法来确定哪些样式应该应用于给定的元素. 为此, 浏览器使用一个名为 特殊性(specificity) 的公式, 它计算选择器中使用的标记, 类, id 和属性选择器的数值, 以及 !important 声明的数值.
通过内联 style 属性在元素上定义的样式被赋予一个等级, 该等级优先于 <style> 块或外部样式表中的任何样式. 如果 Web 开发人员使用 !important 某个值, 则该值将胜过任何 CSS, 无论其位置如何, 除非还有 !important 内联.
同一级别的个数, 数量多的优先级高, 假设同样即比较下一级别的个数. 至于各级别的优先级例如以下:
!important> 内联> ID> 类> 标签 | 伪类 | 属性选择> 伪对象> 通配符> 继承
选择器的特殊性由选择器本身的组件确定, 特殊性值表述为 5 个部分, 如:
0,0,1,0,1
(1), 对于选择器中给定的各个 !important 属性值, 加 1,0,0,0,0 .
(2), 对于选择器中给定的各个 ID 属性值, 加 0,0,1,0,0 .
(3), 对于选择器中给定的各个类属性值, 属性选择器或伪类, 加 0,0,0,1,0 .
(4), 对于选择器中给定的各个元素和伪元素, 加 0,0,0,0,1 . 伪元素是否具有特殊性? 在这方面 CSS2 有些自相矛盾, 不过 CSS2.1 很清楚的指出, 伪元素具有特殊性, 而且特殊性为 0,0,0,0,1, 同元素特殊性相同.
(4), 结合符 (+> [] ^= $= 等等特殊符号) 和通配符 (*) 对特殊性没有任何贡献, 此外通配符的特殊性为 0,0,0,0,0. 全是 0 有什么意义呢? 当然有意义! 子元素继承祖先元素的样式根本没有特殊性, 因此当出现这种情况后, 通配符选择器定义的样式声明也要优先于子元素继承来的样式声明. 因为就算特殊性是 0, 也比没有特殊性可言要强.
为了说明这一点, 让我们说明一些选择器及其计算后的权重数值:
而当优先级与多个 CSS 声明中任意一个声明的优先级相等的时候, CSS 中最后的那个声明将会被应用到元素上.
在下面的示例中, p 将具有蓝色背景.
- p {
- background: red;
- }
- p {
- background: blue;
- }
现在 CSS 将生成以下数据结构, 在本文中, 我们将继续在此基础上进行构建.
来源
CSS 也有来源, 但它们的用途不同:
- <body>
- <p>Hello world</p>
- <style>
- body {
- width: 50px;
- }
- </style>
- </body>
- <article>
- <button>SHARE IT</button>
- <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pellentesq</p>
- </article>
- <style>
- article {
- min-width: 400px;
- max-width: 800px;
- background: rgb(191, 191, 191);
- padding: 5px;
- }
- button {
- float: left;
- background: rgb(210, 32, 79);
- padding: 3px 10px;
- border: 2px solid black;
- margin: 5px;
- }
- p {
- margin: 0;
- }
- </style>
- <body>
- <p>
- <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Cras nibh orci, tincidunt eget enim et, pellentesque condimentum risus.
- Aenean sollicitudin risus velit, quis tempor leo malesuada vel. Donec consequat
- aliquet mauris. Vestibulum ante ipsum primis in faucibus
- </p>
- </p>
- <style>
- body {
- columns: 2;
- column-fill: auto;
- height: 300px;
- }
- </style>
- </body>
- background;
- border;
- <body>
- <p id="one">
- Item 1
- </p>
- <p id="two">
- Item 2
- </p>
- <style>
- body {
- background: lightgray;
- }
- p {
- width: 300px;
- height: 300px;
- position: absolute;
- background: white;
- z-index: 2;
- }
- #two {
- background: green;
- z-index: 1;
- }
- </style>
- </body>
- <p class="clippy"></p>
- <style>
- .clippy {
- width: 100px;
- height: 100px;
- animation: pulse 1s infinite;
- background: url(clippy.svg);
- }
- @keyframes pulse {
- from {
- transform: scale(1, 1);
- }
- to {
- transform: scale(2, 2);
- }
- }
- </style>
- button {
- float: left;
- background: rgb(210, 32, 79);
- padding: 3px 10px;
- border: 2px solid black;
- }
- button:hover {
- background: teal;
- color: black;
- }
来源: http://www.css88.com/web/css/13847.html