codecamp

Cascade and inheritance

先决条件: 基本计算机知识,安装的基本软件,基本知识 developer.mozilla.org/en-US/Learn/Getting_started_with_the_web/Dealing_with_files\">处理文件,HTML基础(学习 HTML简介),以及 CSS的工作原理(了解此模块中的以前的文章)。
目的: 要了解级联和特异性,以及CSS中的继承如何工作。

元素的最终样式可以在许多不同的地方指定,它们可以以复杂的方式进行交互。 这种复杂的交互使CSS变得强大,但它也可能使它混乱和难以调试。 本文旨在澄清一些复杂性; 如果你不立即理解它,不要担心 - 这是CSS理论中最难理解的部分之一。 建议你现在尝试,但然后把它附近作为一个方便的指南,回来时,关于级联和继承的问题出来。

级联

CSS是级联样式表的首字母缩写,表示级联的概念很重要。 在其最基本的层面,它表明CSS规则的顺序很重要,但它比这更复杂。 什么选择器在级联中胜出取决于三个因素(这些按重量顺序列出 - 先前的将取代以后的选择):

  1. Importance
  2. Specificity
  3. Source order

重要性

在CSS中,有一个特殊的语法可以用来确保某个规则总是胜过所有其他规则:!important 将此添加到属性值的结尾将给它超级大国。

让我们看一个例子:

<p class="better">This is a paragraph.</p>
<p class="better" id="winning">One selector to rule them all!</p>
#winning {
  background-color: red;
  border: 1px solid black;
}

.better {
  background-color: gray;
  border: none !important;
}

p {
  background-color: blue;
  color: white;
  padding: 5px;
}

这将产生以下结果:

让我们通过这看看发生了什么。

  1. You'll see that the third rule's color and padding values have been applied, but the background-color hasn't. Why? Really all three should surely apply, because rules later in the source order generally override earlier rules.
  2. However, The rules above it win, because IDs/class selectors have higher specificity than element selectors (you'll learn more about this in the next section.)
  3. Both elements have a class of better, but the 2nd one has an id of winning too. Since IDs have an even higher specificity than classes (you can only have one element with each unique ID on a page, but many elements with the same class — ID selectors are very specific in what they target), the red background color and the 1 pixel black border should both be applied to the 2nd element, with the first element getting the gray background color, and no border, as specified by the class.
  4. The 2nd element does get the red background color, but no border. Why? Because of the !important declaration in the second rule — including this after border: none means that this declaration will win over the border value in the previous rule, even though the ID has higher specificity.

注意:覆盖此!important 声明的唯一方法是包含另一个相同特异性的!important 声明 >,稍后在源顺序中。

知道!important 存在是有用的,这样当你在其他人的代码中遇到它时,你知道它是什么。 我们建议你永远不要使用它,除非你绝对必须。 您可能必须使用它的一种情况是,当您在CMS上工作时,您无法编辑核心CSS模块,并且您确实要覆盖不能以任何其他方式覆盖的样式。 但真的,不要使用它,如果你可以避免它。 因为!important 改变了级联的正常工作方式,它可以使调试CSS问题真的很难解决,特别是在一个大的样式表。

还要注意的是,CSS声明的重要性取决于它指定的样式表 - 用户可以设置自定义样式表以覆盖开发人员的样式,例如用户可能视觉受损,并且想要设置 在他们访问的所有网页上的字体大小是正常大小的两倍,以便更容易阅读。

冲突声明将按以下顺序应用,稍后的声明将覆盖早期的声明:

  1. Declarations in user agent style sheets (e.g. the browser's default styles, used when no other styling is set).
  2. Normal declarations in user style sheets (custom styles set by a user).
  3. Normal declarations in author style sheets (these are the styles set by us, the web developers).
  4. Important declarations in author style sheets
  5. Important declarations in user style sheets

Web开发人员的样式表重写用户样式表是有意义的,所以设计可以保持原样,但有时用户有很好的理由重写Web开发人员样式,如上所述 - 这可以通过使用!重要 / code>。

特异性

特异性基本上衡量选择器的具体细节 - 它可以匹配多少个元素。 如上面所示的示例所示,元素选择器具有低特异性。 类选择器具有更高的特异性,因此将胜过元素选择器。 ID选择器具有更高的特异性,因此将胜过类选择器。 获得ID选择器的唯一方法是使用!important

选择器具有的特异性的量是使用四个不同的值(或分量)来测量的,其可以被认为是四列中的数千,数百,数十和一 - 四个单个数字:

  1. Thousands: Score one in this column if the matching selector is inside a <style> element or the declaration is inside a style attribute (such declarations don't have selectors, so their specificity is always simply 1000.) Otherwise 0.
  2. Hundreds: Score one in this column for each ID selector contained inside the overall selector.
  3. Tens: Score one in this column for each class selector, attribute selector, or pseudo-class contained inside the overall selector.
  4. Ones: Score one in this column for each element selector or pseudo-element contained inside the overall selector.

注意:通用选择器( * ),组合器( + > >,\'\')和否定伪类(:not )对特异性没有影响。

下表显示了一些孤立的例子,让你在心情。 尝试通过这些,并确保你明白为什么他们有我们给他们的特殊性。

选择器 数千 数百 那些 总特异性
h1 0 0 0 1 0001
#important 0 1 0 0 0100
h1 + p::first-letter 0 0 0 3 0003
li > a[href=*"en-US"] > .inline-warning 0 0 2 2 0022
#important div > div > a:hover, inside a <style> element 1 1 1 3 1113

注意:如果多个选择器具有相同的重要性特定性,哪个选择器胜出取决于哪个选择器稍后在源顺序 a>。

在我们继续之前,让我们看看一个行动的例子。 这里是我们将使用的HTML:

<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的例子:

/* 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;
}

我们从这段代码得到的结果如下:

那么这里发生了什么? 首先,我们只对这个例子的前七个规则感兴趣,并且你会注意到,我们在每个规则之前将它们的特异性值包括在注释中。

  • The first two selectors are competing over the styling of the link's background color — the second one wins and makes the background color blue because it has an extra ID selector in the chain: its specificity is 201 versus 101.
  • The third and fourth selectors are competing over the styling of the link's text color — the second one wins and makes the text white because although it has one less element selector, the missing selector is swapped out for a class selector, which is worth ten rather than one. So the winning specificity is 113 versus 104.
  • Selectors 5–7 are competing over the styling of the link's border when hovered. Selector six clearly loses to five with a specificity of 23 versus 24 — it has one fewer element selectors in the chain. Selector seven, however, beats both five and six — it has the same number of sub-selectors in the chain as five, but an element has been swapped out for a class selector. So the winning specificity is 33 versus 23 and 24.

注意:如果您还没有,请再次查看所有选择器,只是为了确保您了解为什么已显示特定值。

源顺序

如上所述,如果多个竞争选择器具有相同的重要性和特异性,则用于帮助决定哪个规则胜利是源顺序的第三因素 - 稍后的规则将胜过早先的规则。 例如:

p {
  color: blue;
}

/* This rule will win over the first one */
p {
  color: red;
}

而在此示例中,第一个规则获胜,因为源顺序被特殊性所取代:

/* This rule will win */
.footnote {
  color: blue;
}

p {
  color: red;
}

关于规则混合的注释

当考虑所有这些级联理论,以及什么样式应用于其他样式时,你应该牢记的是,所有这些发生在属性级别 - 属性重写其他属性,但是你不会得到覆盖其他规则的整个规则。 当几个CSS规则匹配相同的元素时,它们都应用于该元素。 只有之后,任何冲突的属性评估,看看哪些单独的风格将胜过其他。

让我们看一个例子。 首先,一些HTML:

<p>I'm <strong>important</strong></p>

现在一些CSS风格它:

/* specificity: 0002 */
p strong {
  background-color: khaki;
  color: green;
}

/* specificity: 0001 */
strong {
  text-decoration: underline;
  color: red;
}

结果:

结果:

遗产

CSS继承是我们需要调查以获得所有信息和理解应用于元素的样式的最后一个部分。 想法是应用到元素的一些属性值将被该元素的孩子继承,而一些不会。

  • For example, it makes sense for font-family and color to be inherited, as that makes it easy for you to set a site-wide base font by applying a font-family to the <html> element; you can then override the fonts on individual elements where needed. It would be really annoying to have to set the base font separately on every element.
  • As another example, it makes sense for margin, padding, border, and background-image to NOT be inherited. Imagine the styling/layout mess that would occur if you set these properties on a container element and had them inherited by every single child element, and then had to unset them all on each individual element!

默认情况下,哪些属性是继承的,哪些属性不是很常见。 但是,如果您确定要查看,可以查看 CSS参考 - 每个单独的属性 页面将使用包含有关该元素的各种详细信息(包括是否是继承的)的摘要表开始。

控制继承

CSS提供了三个特殊的值来处理继承:

  • inherit : This value sets the property value applied to a selected element to be the same as that of its parent element.
  • initial : This value sets the property value applied to a selected element to be the same as the value set for that element in the browser's default style sheet. If no value is set by the browser's default style sheet and the property is naturally inherited, then the property value is set to inherit instead.
  • unset : This value resets the property to its natural value, which means that if the property is naturally inherited it acts like inherit, otherwise it acts like initial.

inherit 值是最有趣的 - 它允许我们明确使一个元素从其父类继承一个属性值。

让我们来看一个例子。 首先一些HTML:

<ul>
  <li>Default <a href="#">link</a> color</li>
  <li class="inherit">Inherit the <a href="#">link</a> color</li>
  <li class="initial">Reset the <a href="#">link</a> color</li>
  <li class="unset">Unset the <a href="#">link</a> color</li>
</ul>

现在一些CSS样式:

body {
  color: green;
}

.inherit a {
  color: inherit;
}

.initial a {
  color: initial
}

.unset a {
  color: unset;
}

结果:

让我们解释一下这里发生了什么:

  • We first set the color of the <body> to green.
  • As the color property is naturally inherited, all child elements of body will have the same green color. It's worth noting that browsers set the color of links to blue by default instead of allowing the natural inheritance of the color property, so the first link in our list is blue.
  • The second rule sets links within an element with the class inherit to inherit its color from its parent. In this case, it means that the link inherits its color from its <li> parent, which, by default inherits its color from its own <ul> parent, which ultimately inherits its color from the <body> element, which had its color set to green by the first rule.
  • The third rule selects any links within an element with the class initial and sets their color to initial. Usually, the initial value set by browsers for the text color is black, so this link is set to black.
  • The last rule selects all links within an element with the class unset and sets their color to unset — we unset the value. Because the color property is a naturally inherited property it acts exactly like setting the value to inherit. As a consequence, this link is set to the same color as the body — green.

主动学习:使用级联

在这个主动学习中,我们希望您尝试编写一个新规则,该规则将覆盖默认情况下应用于链接的颜色和背景颜色。 您可以使用我们在 Controlling_inheritance 部分中查看的一个特殊值,在新规则中编写声明,该声明会将背景颜色重置为白色,而不使用实际 颜色值?

如果发生错误,您可以随时使用重置按钮重置。 如果您遇到问题,请按显示解决方案按钮查看一个潜在的答案。

下一步是什么

如果你理解这篇文章的大部分内容,那么做得很好 - 你已经开始熟悉CSS的基本机制。 中心理论的最后一点是盒子模型,我们将在下面讨论。

如果你没有完全理解级联,特异性和继承,那么不要担心! 这绝对是我们在课程中覆盖的最复杂的事情,甚至是专业的网络开发人员有时候会发现棘手的东西。 我们建议您在继续学习本课程的同时回到这篇文章,并继续思考。 回到这里,如果你开始遇到奇怪的问题,样式不按预期应用。 这可能是一个特殊性问题。

CSS values and units
The box model
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录
CSS

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }