本文旨在让你理解CSS的一些最基本的概念——层叠、优先级和继承——这些概念决定着如何将CSS应用到HTML中,以及如何解决冲突。
目标:学习层叠、优先级,以及在CSS中继承是如何工作的。
CSS代表层叠样式表(Cascading Style Sheets),理解第一个词cascading很重要— cascade 的表现方式是理解CSS的关键。
在某些时候,在做一个项目过程中你会发现一些应该产生效果的样式没有生效。通常的原因是你创建了两个应用于同一个元素的规则。cascade, 和它密切相关的概念是 specificity,决定在发生冲突的时候应该使用哪条规则。设计元素样式的规则可能不是期望的规则,因此需要了解这些机制是如何工作的。
这里也有继承的概念,也就是在默认情况下,一些css属性继承当前元素的父元素上设置的值,有些则不继承。这也可能导致一些和期望不同的结果。
我们来快速的看下正在处理的关键问题,然后依次了解它们是如何相互影响的,以及如何和css交互的。虽然这些概念难以理解,但是随着不断的练习,你会慢慢熟悉它的工作原理。
Stylesheets cascade(样式表层叠) — 简单的说,css规则的顺序很重要;当应用两条同级别的规则到一个元素的时候,写在后面的就是实际使用的规则。
下面的例子中,我们有两个关于 h1
的规则。h1
最后显示蓝色 — 这些规则有相同的优先级,所以顺序在最后的生效。
h1 { color: red; } h1 { color: blue; } <h1>This is my heading.</h1>
浏览器是根据优先级来决定当多个规则有不同选择器对应相同的元素的时候需要使用哪个规则。它基本上是一个衡量选择器具体选择哪些区域的尺度:
class
属性值的元素 — 所以它的优先级就要高一点。举例时间! 下面我们再来介绍两个适用于 h1
的规则。下面的 h1
最后会显示红色 — 类选择器有更高的优先级,因此就会被应用——即使元素选择器顺序在它后面。
.main-heading { color: red; } h1 { color: blue; } <h1 class="main-heading">This is my heading.</h1>
稍后我们会详细解释优先级评分和其他相关内容。
继承也需要在上下文中去理解 —— 一些设置在父元素上的css属性是可以被子元素继承的,有些则不能。
举一个例子,如果你设置一个元素的 color
和 font-family
,每个在里面的元素也都会有相同的属性,除非你直接在元素上设置属性。
body { color: blue; } span { color: black; } <p>As the body has been set to have a color of blue this is inherited through the descendants.</p> <p>We can change the color by targetting the element with a selector, such as this <span>span</span>.</p>
一些属性是不能继承的 — 举个例子如果你在一个元素上设置 width
50% ,所有的后代不会是父元素的宽度的50% 。如果这个也可以继承的话,CSS就会很难使用了!
我们从继承开始。下面的例子中我们有一个ul
,里面有两个无序列表。我们已经给 <ul>
设置了 border, padding 和 font color.
color 应用在直接子元素,也影响其他后代 — 直接子元素<li>
,和第一个嵌套列表中的子项。然后添加了一个 special
类到第二个嵌套列表,其中使用了不同的颜色。然后通过它的子元素继承。
.main { color: rebeccapurple; border: 2px solid #ccc; padding: 1em; } .special { color: black; font-weight: bold; } <ul class="main"> <li>Item One</li> <li>Item Two <ul> <li>2.1</li> <li>2.2</li> </ul> </li> <li>Item Three <ul class="special"> <li>3.1 <ul> <li>3.1.1</li> <li>3.1.2</li> </ul> </li> <li>3.2</li> </ul> </li> </ul>
像 widths (上面提到的), margins, padding, 和 borders 不会被继承。如果borders可以被继承,每个列表和列表项都会获得一个边框 — 可能就不是我们想要的结果!
哪些属性属于默认继承很大程度上是由常识决定的。
CSS 为控制继承提供了四个特殊的通用属性值。每个css属性都接收这些值。
层叠算法决定如何找出要应用到每个文档元素的每个属性上的值。
来源 | 重要程度 | |
---|---|---|
1 | 用户代理 | 普通 |
2 | 用户 | 普通 |
3 | 页面作者 | 普通 |
4 | CSS动画 | 见下节 |
5 | 页面作者 | !important |
6 | 用户 | !important |
7 | 用户代理 | !important |
8 | css 过渡(css transitions) | |
CSS 的 shorthand 属性 all
可以用于同时将这些继承值中的一个应用于(几乎)所有属性。它的值可以是其中任意一个(inherit
, initial
, unset
, or revert
)。这是一种撤销对样式所做更改的简便方法,以便回到之前已知的起点。
下面的例子中有两个blockquote 。第一个用元素本身的样式 ,第二个设置 all
为 unset
blockquote { background-color: red; border: 2px solid green; } .fix-this { all: unset; } <blockquote> <p>This blockquote is styled</p> </blockquote> <blockquote class="fix-this"> <p>This blockquote is not styled</p> </blockquote>
试着将 all
改成其他可能的值然后观察有什么不一样。
我们现在明白了为什么嵌套在html结构中的段落和应用于正文中的css颜色相同,从入门课程中,我们了解了如何将文档中的任何修改应用于某个对象的css,无论是把css指定某个元素还是创建一个类。现在,我们将要了解层叠如何定义在不止一个元素的时候怎么应用css规则。
有三个因素需要考虑,根据重要性排序如下,前面的更重要:
我们从下往上,看看浏览器是如何决定该应用哪个css规则的。
我们已经看到了顺序对于层叠的重要性。如果你有超过一条规则,而且都是相同的权重,那么最后面的规则会应用。可以理解为后面的规则覆盖前面的规则,直到最后一个开始设置样式。
在你了解了顺序的重要性后,会发现在一些情况下,有些规则在最后出现,但是却应用了前面的规则。这是因为前面的有更高的优先级 — 它范围更小,因此浏览器就把它选择为元素的样式。
就像前面看到的,类选择器的权重大于元素选择器,因此类上定义的属性将覆盖应用于元素上的属性。
这里需要注意虽然我们考虑的是选择器,以及应用在选中对象上的规则,但不会覆盖所有规则,只有相同的属性。
这样可以避免重复的 CSS。一种常见的做法是给基本元素定义通用样式,然后给不同的元素创建对应的类。举个例子,在下面的样式中我给2级标题定义了通用样式,然后创建了一些类只修改部分属性的值。最初定义的值应用于所有标题,然后更具体的值通过对应类来实现。
h2 { font-size: 2em; color: #000; font-family: Georgia, ‘Times New Roman‘, Times, serif; } .small { font-size: 1em; } .bright { color: rebeccapurple; } <h2>Heading with no class</h2> <h2 class="small">Heading with class of small</h2> <h2 class="bright">Heading with class of bright</h2>
现在让我们来看看浏览器如何计算优先级。我们已经知道一个元素选择器比类选择器的优先级更低会被其覆盖。本质上,不同类型的选择器有不同的分数值,把这些分数相加就得到特定选择器的权重,然后就可以进行匹配。
一个选择器的优先级可以说是由四个部分相加 (分量),可以认为是个十百千 — 四位数的四个位数:
style
的属性(内联样式)则该位得一分。这样的声明没有选择器,所以它得分总是1000。注: 通用选择器 (*
),组合符 (+
, >
, ~
, ‘ ‘),和否定伪类 (:not
) 不会影响优先级。
警告: 在进行计算时不允许进行进位,例如,20 个类选择器仅仅意味着 20 个十位,而不能视为 两个百位,也就是说,无论多少个类选择器的权重叠加,都不会超过一个 ID 选择器。
下面有几个单独的例子,有空可以看看。试着思考下,理解为什么优先级是这样定的。我们还没有深入介绍选择器,不过你可以在MDN上面找到每个选择器的详细信息 selectors reference.
选择器 | 千位 | 百位 | 十位 | 个位 | 优先级 |
---|---|---|---|---|---|
h1 |
0 | 0 | 0 | 1 | 0001 |
h1 + p::first-letter |
0 | 0 | 0 | 3 | 0003 |
li > a[href*="en-US"] > .inline-warning |
0 | 0 | 2 | 2 | 0022 |
#identifier |
0 | 1 | 0 | 0 | 0100 |
内联样式 | 1 | 0 | 0 | 0 | 1000 |
在我们继续之前,先看看这个例子。
/* specificity: 0101 */ #outer a { background-color: red; } /* specificity: 0201 */ #outer #inner a { background-color: blue; } /* specificity: 0104 */ #outer div ul li a { color: yellow; } /* specificity: 0113 */ #outer div ul .nav a { color: white; } /* specificity: 0024 */ div div li:nth-child(2) a:hover { border: 10px solid black; } /* specificity: 0023 */ div li:nth-child(2) a:hover { border: 10px dashed black; } /* specificity: 0033 */ div div .nav:nth-child(2) a:hover { border: 10px double black; } a { display: inline-block; line-height: 40px; font-size: 20px; text-decoration: none; text-align: center; width: 200px; margin-bottom: 10px; } ul { padding: 0; } li { list-style-type: none; } <div id="outer" class="container"> <div id="inner" class="container"> <ul> <li class="nav"><a href="#">One</a></li> <li class="nav"><a href="#">Two</a></li> </ul> </div> </div>
这里发生了什么? 首先,我们先看看最上面的选择器规则,你会发现,我们已经把优先级计算出来放在最前面的注释里。
有一个特殊的 CSS 可以用来覆盖所有上面所有优先级计算,不过需要很小心的使用 — !important
。用于修改特定属性的值, 能够覆盖普通规则的层叠。
看看这个例子,有两个段落,其中一个有ID。
原文:https://www.cnblogs.com/yanjianjiang/p/14846411.html