diff --git "a/mozilla/css/css-\346\240\267\345\274\217\345\237\272\347\241\200/css-\345\261\202\345\217\240\344\274\230\345\205\210\347\272\247\344\270\216\347\273\247\346\211\277.md" "b/mozilla/css/css-\346\240\267\345\274\217\345\237\272\347\241\200/css-\345\261\202\345\217\240\344\274\230\345\205\210\347\272\247\344\270\216\347\273\247\346\211\277.md" new file mode 100644 index 0000000000000000000000000000000000000000..7ae0ddf6fb34aa9af9e08c10043014266a20e80a --- /dev/null +++ "b/mozilla/css/css-\346\240\267\345\274\217\345\237\272\347\241\200/css-\345\261\202\345\217\240\344\274\230\345\205\210\347\272\247\344\270\216\347\273\247\346\211\277.md" @@ -0,0 +1,511 @@ +# 层叠、优先级与继承 + +本文旨在让你理解 CSS 的一些最基本的概念——层叠、优先级和继承——这些概念决定着如何将 CSS 应用到 HTML 中,以及如何解决冲突。 + + +## [冲突规则](https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Handling_conflicts#%E5%86%B2%E7%AA%81%E8%A7%84%E5%88%99) + +CSS 代表**层叠样式表**(Cascading Style Sheets),理解第一个词*层叠*(cascade)很重要——层叠的表现方式是理解 CSS 的关键。 + +在某些时候,在做一个项目过程中你会发现一些应该产生效果的样式没有生效。通常的原因是你创建了两个应用于同一个元素的规则。与[**层叠**](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_cascade/Cascade)密切相关的概念是[**优先级**(specificity)](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_cascade/Specificity),决定在发生冲突的时候应该使用哪条规则。设计元素样式的规则可能不是期望的规则,因此需要了解这些机制是如何工作的。 + +这里也有[**继承**](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_cascade/Inheritance)的概念,也就是在默认情况下,一些 css 属性继承当前元素的父元素上设置的值,有些则不继承。这也可能导致一些和期望不同的结果。 + +我们来快速地看下正在处理的关键问题,然后依次了解它们是如何相互影响的,以及如何和 CSS 交互的。虽然这些概念难以理解,但是随着不断的练习,你会慢慢熟悉它的工作原理。 + + +### [层叠](https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Handling_conflicts#%E5%B1%82%E5%8F%A0) + +样式表[**层叠**](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_cascade/Cascade)——简单的说,就是 CSS 规则的顺序很重要;当应用两条同级别的规则到一个元素的时候,写在后面的就是实际使用的规则。 + +下面的示例中,我们有两个关于 `
由于主题颜色被设置为蓝色,因此该颜色会被子元素继承。
+我们可以通过选择器定位元素来改变颜色,比如这个内容跨越元素。
+ +``` + +```css +body { + color: blue; +} + +span { + color: black; +} + +``` + +一些属性是不能继承的——举个例子如果你在一个元素上设置 [`width`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/width) 为 50% ,所有的后代不会是父元素的宽度的 50% 。如果这个也可以继承的话,CSS 就会很难使用了! + +## [理解这些概念是如何协同工作的](https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Handling_conflicts#%E7%90%86%E8%A7%A3%E8%BF%99%E4%BA%9B%E6%A6%82%E5%BF%B5%E6%98%AF%E5%A6%82%E4%BD%95%E5%8D%8F%E5%90%8C%E5%B7%A5%E4%BD%9C%E7%9A%84) + +这三个概念一起来控制 CSS 规则应用于哪个元素;在下面的内容中,我们将看到它们是如何协同工作的。有时候会感觉有些复杂,但是当你对 CSS 有更多经验的时候,你就可以记住它们,即便忘记了细节,可以在网上查到,有经验的开发人员也不会记得所有细节。 + + +## [理解继承](https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Handling_conflicts#%E7%90%86%E8%A7%A3%E7%BB%A7%E6%89%BF) + +我们从继承开始。下面的例子中我们有一个 [`++ +当前块引用设置了样式
+
++ +``` + +```css +blockquote { + background-color: orange; + border: 2px solid blue; +} + +.fix-this { + all: unset; +} + +``` + +试着将 `all` 改成其他可用的值然后观察有什么不一样。 + + +## [理解层叠](https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Handling_conflicts#%E7%90%86%E8%A7%A3%E5%B1%82%E5%8F%A0) + +我们现在明白了为什么嵌套在 HTML 结构中的段落和应用于正文中的 CSS 颜色相同,从入门课程中,我们了解了如何将文档中的任何修改应用于某个对象的 CSS,无论是把 CSS 指定某个元素还是创建一个类。现在,我们将要了解层叠如何定义在不止一个元素的时候怎么应用 CSS 规则。 + +有三个因素需要考虑,根据重要性排序如下,后面的更重要: + +1. **资源顺序** +2. **优先级** +3. **重要程度** + +我们从上往下看,看看浏览器是如何决定该应用哪个 CSS 规则的。 + +### [资源顺序](https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Handling_conflicts#%E8%B5%84%E6%BA%90%E9%A1%BA%E5%BA%8F) + +我们已经看到了顺序对于层叠的重要性。如果你有超过一条规则,而且都是相同的权重,那么最后面的规则会应用。可以理解为后面的规则覆盖前面的规则,直到最后一个开始设置样式。 + +资源顺序仅在规则的优先级相同时才体现出来,下面让我们看一下优先级: + +### [优先级](https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Handling_conflicts#%E4%BC%98%E5%85%88%E7%BA%A7_2) + +你会发现在一些情况下,有些规则在最后出现,但是却应用了前面的具有冲突的规则。这是因为前面的有更高的**优先级**——它范围更小,因此浏览器就把它选择为元素的样式。 + +就像前面看到的,类选择器的权重大于元素选择器,因此类上定义的属性将覆盖应用于元素上的属性。 + +这里需要注意虽然我们考虑的是选择器,以及应用在选中对象上的规则,但不会覆盖所有规则,只覆盖相同的属性。 + +这样可以避免重复的 CSS。一种常见的做法是给基本元素定义通用样式,然后给不同的元素创建对应的类。举个例子,在下面的样式中我给 2 级标题定义了通用样式,然后创建了一些类只修改部分属性的值。最初定义的值应用于所有标题,然后更具体的值通过对应类来实现。 + +```html +当前块引用未设置样式
+
这是个段落。
+一个选择器掌管一切!
+ +``` + +```css +#winning { + background-color: red; + border: 1px solid black; +} + +.better { + background-color: gray; + border: none !important; +} + +p { + background-color: blue; + color: white; + padding: 5px; +} + +``` + +让我们看看会发生什么——如果有什么疑问,试着删除一些属性: + +1. 你会发现第三个规则 [`color`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/color) 和 [`padding`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/padding) 的值被应用了,但是 [`background-color`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/background-color) 没有。为什么?应该三个都应用,因为顺序规则是后面覆盖前面。 +2. 无论如何,上面的规则赢了,因为类选择器比元素选择器有更高的优先级。 +3. 两个元素都有 `better` [`class`](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes#class),但是第二个有 [`id`](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes#id) 。因为 ID 选择器比类选择器优先级更高(一个页面只能有一个独特的 ID,但是很多元素都有相同的类——ID 对于目标非常独特),红色背景和 1px 黑色边框应该都被应用到第二个元素,第一个元素应该是灰色背景和 no border,根据类选择器。 +4. 第二个元素有红色背景但是没有边框。为什么?因为 `!important` 声明在第二条规则里——在 `border: none` 后面,说明即使计算优先级低,这个属性也使用这个值。 + +**备注:** 覆盖 `!important` 唯一的办法就是另一个 `!important` 具有相同*优先级*而且顺序靠后,或者更高优先级。 + +在一种情况下,你可能不得不使用它:当你不能编辑核心的 CSS 模块,不能用任何其他方式覆盖,而你又真的想要覆盖一个样式时。但说真的,如果可以避免的话就不要用它。 + + +## [CSS 位置的影响](https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Handling_conflicts#css_%E4%BD%8D%E7%BD%AE%E7%9A%84%E5%BD%B1%E5%93%8D) + +最后,也很有用,CSS 声明的优先级取决于定义它的样式表和级联层。 + +它让用户可以设置自定义样式表来覆盖开发人员定义的样式。例如用户可能视力受损,并想在所有网页上设置两倍的正常字体大小,以便更容易进行阅读。 + +也可以在级联层中声明开发人员定义的样式:你可以让非分层样式覆盖分层样式,或者你可以让后面的层中声明的样式覆盖先前的层中声明的样式。例如,作为开发人员,你可能无法编辑第三方的样式表,但你可以将外部的样式表导入级联层中,以便你自己的样式可以轻松地覆盖导入的样式,无需担心第三方选择器的优先级。 + +### [覆盖声明的顺序](https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Handling_conflicts#%E8%A6%86%E7%9B%96%E5%A3%B0%E6%98%8E%E7%9A%84%E9%A1%BA%E5%BA%8F) + +相互冲突的声明将按以下顺序应用,后一种声明将覆盖前一种声明: + +1. 用户代理样式表中的声明(例如,浏览器的默认样式,在没有设置其他样式时使用)。 +2. 用户样式表中的常规声明(由用户设置的自定义样式)。 +3. 作者样式表中的常规声明(这些是我们 web 开发人员设置的样式)。 +4. 作者样式表中的 `!important` 声明 +5. 用户样式表中的 `!important` 声明 +6. 用户代理样式表中的 `!important` 声明 + +**备注:** 标记为 `!important` 的样式的优先级顺序是颠倒的。web 开发人员的样式表覆盖用户的样式表是有意义的,因此设计可以按预期进行,但是有时用户有充足的理由覆盖 web 开发人员的样式,正如上面提到的——这可以通过在他们的规则中使用 `!important` 来实现。 + + +## [级联层的顺序](https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Handling_conflicts#%E7%BA%A7%E8%81%94%E5%B1%82%E7%9A%84%E9%A1%BA%E5%BA%8F) + +尽管[级联层](https://developer.mozilla.org/zh-CN/docs/Web/CSS/@layer)属于高级的主题,你可能不会立刻使用此特性,但了解层是如何级联的非常重要。 + +在级联层中声明 CSS 时,优先级的顺序由声明层的顺序来决定。在任何层之外声明的 CSS 样式会被按声明的顺序组合在一起,形成一个未命名的层,它会被当作最后声明的层。对于存在冲突的常规(没有 `!important` 声明)样式,后面的层比先前定义的层的优先级高。但对于带有 `!important` 标记的样式,其顺序相反——先前的层中的 important 样式比后面的层以及为在层中声明的 important 样式优先级要高。但内联样式比所有作者定义的样式的优先级都要高,不受级联层规则的影响。 + +当你在不同的层中有多个样式块,且其中提供了对于某一元素的单一属性的相互冲突的值时,声明该冲突样式的层的顺序将决定其优先级。而不是高优先级的层直接覆盖低优先级的层中的所有样式。需要注意的是单独的一个层中的样式的优先级仍旧会起作用。 + +```html +具有边框和背景的段落
+ + +``` + +```css +@layer firstLayer, secondLayer; + +p { + /* 0-0-1 */ + background-color: red; + color: grey !important; + border: 5px inset purple; +} +p#addSpecificity { + /* 1-0-1 */ + border-style: solid !important; +} + +@layer firstLayer { + #addSpecificity { + /* 1-0-0 */ + background-color: blue; + color: white !important; + border-width: 5px; + border-style: dashed !important; + } +} + +@layer secondLayer { + p#addSpecificity { + /* 1-0-1 */ + background-color: green; + color: orange !important; + border-width: 10px; + border-style: dotted !important; + } +} + +``` + +让我们讨论一下上例以了解发生了什么。示例中,声明了两个级联层,按 `firstLayer` 和 `secondLayer` 的顺序声明。即使 `secondLayer` 的优先级更高,但其中声明的样式没有被使用。为什么?因为不分层的常规样式具有更高的优先级,覆盖了层中的常规样式,不论层的优先级如何,而具有 important 的样式,则是先前声明的层会覆盖后声明的层,而不是层的优先级。 + +如果你修改示例中 CSS 的第一行为 `@layer secondLayer, firstLayer;`,就会修改层声明的顺序,所有 `firstLayer` 中的 important 样式会被 `secondLayer` 中的冲突值覆盖。