CSS学习摘要-层叠和继承

当有多个选择器作用在一个元素上时,哪个规则最终会应用到元素上?

其实这是通过层叠机制来控制的,这也和样式继承(元素从其父元素那里获得属性值)有关。

元素的最终样式可以在多个地方定义,它们以复杂的形式相互影响。这些复杂的相互作用使CSS变得非常强大,但也使其非常难于调试和理解。

层叠

CSS 是 Cascading Style Sheets 的缩写,这暗示层叠(cascade)的概念是很重要的。在最基本的层面上,它表明CSS规则的顺序很重要,但它比那更复杂。什么选择器在层叠中胜出取决于三个因素(这些都是按重量级顺序排列的——前面的的一种会否决后一种):

  1. 重要性(Importance)
  2. 专用性(Specificity)
  3. 源代码次序(Source order)

重要性

在CSS中,有一个特别的语法可以让一条规则总是优先于其他规则:!important。(常见于应用于iconfont图标属性后面)把它加在属性值的后面可以使这条声明有无比强大的力量。

让我们看一下这个例子:

<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. 你可以看到第三条规则 colorpadding被运用了, 但 background-color没有,为什么?实际上,这三种情况都应该应用,因为在源顺序后面的规则通常会覆盖较早的规则。
  2. 然而, 在前面的规则被运用了,因为 IDs/class 选择器优先于element选择器。
  3. 这两个元素都有 class并带有 better属性, 但是第二个元素有 id 值为winning 。 因为比起class而言id专用性更高(在一个页面上id是唯一的, 但很多元素可以拥有相同的class — ID 选择器在它们的目标中是非常优先的),红色背景色和1pixel的黑色边框都应应用于第二元素,第一个元素获得灰色背景色,没有边框,如类所指定。
  4. 第二个元素获得红色背景色,但没有边框。为什么?因为 !important 在第二条规则中的声明——在 border: none之后写入它意味着尽管id具有更高的优先性,该声明也将优先于前面规则中的边界值声明。

注意: 重载这个 !important 声明的唯一方法是在后面的源码或者是一个拥有更高特殊性的源码中包含相同的 !important 特性的声明。

知道 !important存在是很有用的,这样当你在别人的代码中遇到它时,你就知道它是什么了。但是!我们建议你千万不要使用它,除非你绝对必须使用它。您可能不得不使用它的一种情况是,当您在CMS中工作时,您不能编辑核心的CSS模块,并且您确实想要重写一种不能以其他方式覆盖的样式。 但是,如果你能避免的话,不要使用它。由于 !important 改变了层叠正常工作的方式,因此调试CSS问题,尤其是在大型样式表中,会变得非常困难。

要注意一个CSS声明的重要性取决于它被指定在什么样式表内——用户可以设置自定义样式表覆盖开发商的样式,例如用户可能有视力障碍,想设置字体大小对所有网页的访问是双倍的正常大小,以便更容易阅读。

相互冲突的声明将按以下顺序适用,后一种将覆盖先前的声明

  1. 在用户代理样式表的声明 (例如:浏览器在没有其他声明的默认样式).
  2. 用户样式表中的普通声明(由用户设置的自定义样式)。
  3. 作者样式表中的普通声明(这是我们设置的样式,Web开发人员)。
  4. 作者样式表中的重要声明
  5. 用户样式表中的重要声明

Web开发者的样式表覆盖用户的样式表是合理的,所以设计可以保持预期,但是有时候用户有很好的理由来重写web开发人员样式,如上所述,这可以通过在用户的规则中使用!important

专用性

专用性基本上是衡量选择器的具体程度的一种方法——它能匹配多少元素。如上面所示的示例所示,元素选择器具有很低的专用性。类选择器具有更高的专用性,所以将战胜元素选择器。ID选择器有甚至更高的专用性, 所以将战胜类选择器. 战胜ID选择器的唯一方法是使用 !important

一个选择器具有的专用性的量是用四种不同的值(或组件)来衡量的,它们可以被认为是千位,百位,十位和个位——在四个列中的四个简单数字:

  1. 千位:如果声明是在style 属性中该列加1分(这样的声明没有选择器,所以它们的专用性总是1000。)否则为0。
  2. 百位:在整个选择器中每包含一个ID选择器就在该列中加1分。
  3. 十位:在整个选择器中每包含一个类选择器、属性选择器、或者伪类就在该列中加1分。
  4. 个位:在整个选择器中每包含一个元素选择器或伪元素就在该列中加1分。

注意: 通用选择器 (*), 复合选择器 (+, >, ~, ‘ ‘) 和否定伪类 (: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*="zh-CN"] > .inline-warning 0 0 2 2 0022
#important div > div > a:hover, 在一个元素的 <style>属性里 1 1 1 3 1113

在我们继续之前,让我们看看一个行动中的例子。

这是我们将要使用的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;
}

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

这里发生了什么?首先,我们只对本例的前七个规则感兴趣,正如您将注意到的,我们已经在每个注释中包含了它们的专用性值。

  • 前两个选择器正在竞争链接的背景颜色的样式——第二个赢得并使背景色为蓝色,因为它有一个额外的ID选择器在链中:其专用性值为201比101。
  • 第三个和第四个选择器在链接文本颜色的样式上进行竞争——第二个选择器获胜,使文本变白,因为缺少一个元素选择器,缺少的选择器被换成类选择器,它的值是十,而不是个位。所以专用性值为113和104。
  • 选择器5 - 7在徘徊在链接附近时的样式进行竞争。选择器六明显地输给了了五,其专用性值为23和24——它在链中少了一个元素选择器。然而选择器七同时击败了五和六——它有与五相同数量的子选择器在链中,但一个元素已被换为了一个类选择器。所以获胜的专用性值是33比23和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;
}

Result:

在这个例子中,因为专用性的关系,第一条规则中的color属性覆盖掉了第二条中的颜色值。但是,对于第一条中的 background-color和第二条中的text-decoration 的属性都在strong元素之中得到了体现。你也注意到了这个元素之中的字体是加粗的:这是浏览器默认的样式规则。

继承

CSS继承是我们需要研究的最后一部分,以获取所有信息并了解什么样式应用于元素。

其思想是,应用于某个元素的一些属性值将由该元素的子元素继承,而有些则不会。

  • 例如,对 font-familycolor进行继承是有意义的,因为这使得您可以很容易地设置一个站点范围的基本字体,方法是应用一个字体到 <html> 元素;然后,您可以在需要的地方覆盖单个元素的字体。如果要在每个元素上分别设置基本字体,那就太麻烦了。
  • 再如,让 margin paddingborderbackground-image 不被继承是有意义的。想象一下,如果您将这些属性设置在一个容器元素上,并将它们继承到每个子元素,然后不得不将它们全部放在每个单独的元素上,那么将会出现的样式/布局混乱。

哪些属性默认被继承哪些不被继承大部分符合常识。如果你想确定,你可以参考CSS参考资料—— 每个单独的属性页都会从一个汇总表开始,其中包含有关该元素的各种详细信息,包括是否被继承。

注:

font-family允许您通过给定一个有先后顺序的,由字体名或者字体族名组成的列表来为选定的元素设置字体。 属性的值用逗号隔开。浏览器会选择列表中第一个该计算机上有安装的字体,或者是通过 ‘ @font-face 指定的可以直接下载的字体。

padding属性设置一个元素的内边距,padding 区域指一个元素的内容和其边界之间的空间,该属性不能为负值。

background-image 属性用于为一个元素设置一个或者多个背景图像。图像在绘制时,以z方向堆叠的方式进行。先指定的图像会在之后指定的图像上面绘制。因此指定的第一个图像最接近用户。

控制继承

CSS为处理继承提供了四种特殊的通用属性值:

  • inherit: 该值将应用到选定元素的属性值设置为与其父元素一样。
  • initial :该值将应用到选定元素的属性值设置为与浏览器默认样式表中该元素设置的值一样。如果浏览器默认样式表中没有设置值,并且该属性是自然继承的,那么该属性值就被设置为 inherit
  • unset:该值将属性重置为其自然值,即如果属性是自然继承的,那么它就表现得像 inherit,否则就是表现得像 initial
  • revert:如果当前的节点没有应用任何样式,则将该属性恢复到它所拥有的值。换句话说,属性值被设置成自定义样式所定义的属性(如果被设置), 否则属性值被设置成用户代理的默认样式。

注意: initialunset 不被IE支持。

initial 是将属性的初始值( initial value)赋给元素 . initial 适用于所有的css 属性(属性的initial值可在属性表中查到),包括css 简写属性(全局属性)all.

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

Result:

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

  • 我们首先设置<body>color为绿色。
  • 由于color属性是自然继承的,所有的body子元素都会有相同的绿色。需要注意的是默认情况下浏览器设置链接的颜色为蓝色,而不是自然继承color属性,因此在我们列表中的第一个链接是蓝色的。
  • 第二个规则设置一个类 inherit 的元素内的链接,并从父类继承它的颜色。在这种情况下, 意思是说链接继承了父元素<li> 的颜色,默认情况下<li>的颜色来自于它的父元素 <ul> , 最后<ul>继承自 <body>元素,而<body>color 根据第一条规则设置成了绿色。
  • 第三个规则选择了在元素上使用类 initial 的任意链接然后设置他们的颜色为 initial 。通常, initial 的值被浏览器设置成了黑色,因此该链接被设置成了黑色。
  • 最后一个规则选择了在元素上使用类 unset 的所有链接然后设置它们的颜色为 unset ——即我们不设置值。因为color属性是一个自然继承的属性,它实际上就像把值设置成 inherit 一样。结果是,该链接被设置成了与body一样的颜色——绿色。

重新设置所有的属性值

CSS速写属性 all 能够被应用到每一个继承属性,一次性应用所有的继承属性。这里的值可以是继承属性里的任何一个 (inherit, initial, unset, or revert)。对于撤销对样式的修改,这是非常方便的一种方式。然后你就可以在开始新的修改之前,返回到一个已知的开始点。

全文摘要自MDN网络开发者网站

end

2018-5-31 周四

原文地址:https://www.cnblogs.com/tielemao/p/9119755.html

时间: 2024-07-30 09:51:45

CSS学习摘要-层叠和继承的相关文章

CSS学习摘要-引入样式

CSS学习摘要-引入样式 注:主要是摘录自MDN 网络开发者这个网站的. CSS 实际上如何工作? 当浏览器显示文档时,它必须将文档的内容与其样式信息结合.它分两个阶段处理文档: 浏览器将 HTML和 CSS转化成 DOM(文档对象模型).DOM在计算机内存中表示文档.它把文档内容和其样式结合在一起. 浏览器显示 DOM 的内容. 如何将你的 CSS 应用到你的 HTML 上 这有你常见的三种不同方式将 CSS 应用到 HTML 文档上,有的方式比其他方式更有用.在这里,我们将简要回顾一下每一种

CSS选择器、层叠、继承的那些事

题外话 最近看了<精通CSS,高级web标准解决方案>这本书.所以接下来的几篇文章结合自己的理解,参照本书做一下总结. 好,废话不多说,开始进入正题. CSS的前世今生 在很久很久以前,早期的浏览器只支持简易版本的HTML,使用HTML添加基本的格式和结构.但是随着web的流行,人们开始不满足于只有结构和文本的样式了!! 看一下1999年搜狐的页面: 人都是爱美的,所以HTML开始用来表现页面了,这样一来就web领域就变得一团糟了,试想一下当你把所有的样式都装在同一个HTML文档的时候,是多么

CSS学习摘要-盒子模型

注:全文摘要自网络开发者网站,当然间隔也会整理一些思路和格式排版添加进去. CSS框模型(译者注:也被称为"盒模型")是网页布局的基础 --每个元素被表示为一个矩形的方框,框的内容.内边距.边界和外边距像洋葱的膜那样,一层包着一层构建起来.浏览器渲染网页布局时,它会算出每个框的内容要用什么样式,周围的洋葱层有多大,以及框相对于其它框放在哪里.在理解如何创建 CSS 布局之前,你需要理解框模型. 框属性 文档的每个元素被构造成文档布局内的一个矩形框,框每层的大小都可以使用一些特定的CSS

CSS学习摘要-浮动与清除浮动

float 浮动float CSS属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它.该元素从网页的正常流动中移除,尽管仍然保持部分的流动性(与绝对定位相反). 一个浮动元素是float的值不为none的元素. /* Keyword values */float: left;float: right;float: none;float: inline-start;float: inline-end; /* Global values */float: inherit;float

CSS 层叠与继承

三种继承css方式 1.段内继承 <p style="color: red;font-size:50px;">样式原文</p> 原文变成 红色, 原文字体变大 两个都是通过改变样式属性的值去实现的. 语法详解: 1.每个样式属性会有不同的值, "color: red" 通过冒号表达color的属性. 2.属性间要用分号间隔和闭合 3.font-size 属于复合属性 2. 文档内继承 <style>        全局style

css 学习笔记 一

 css学习笔记1 1.选择特定元素的选择符: 上下文选择符 标签1 标签2 {声明}      其中标签2是要选择的目标,而只有在标签1是其祖先元素(不一定是父元素)的情况下才会被选中.     css代码: body代码: 理解:section标签 article标签就属于上下文的关系,即article为section的后代,只有应用了section的样式,才能应用article的样式.注意:继承关系中的空格问题,有空格的表示祖先与后代的关系,css写法,body的代码为,说明页面样式表文件

CSS学习之float解析

转自:http://www.w3cplus.com/css/float.html 一.float是什么? float即为浮动,在CSS中的作用是使元素脱离正常的文档流并使其移动到其父元素的“最左边”或“最右边”.下面解释下这个定义中的几个名词的概念: 文档流:在html中文档流即为元素从上至下排列的顺序. 脱离文档流:元素从正常的排列顺序被抽离. 最左边/最右边:上述的移动到父元素最左和最右是指元素往左或往右移动直到碰到另一个浮动元素或父元素内容区的边界(不包括padding). 二.float

html+css学习笔记 2[标签]

img标签/a标签 <img src="图片地址" alt="图片名"/>  图片(单标签)alt属性 是图片名字,是给百度搜索引擎抓取使用:     a标签: 链接/下载/锚点 href地址等于标签id     target 链接打开方式     blank  新窗口     self     当前窗口     <base target="_blank"/> 定义页面链接默认打开方式   常见标签 div        

CSS学习笔记总结和技巧

跟叶老师说项目,他叫我写一个静态首页,看起来挺简单的,但是下手才发现在真的不会怎么下手啊,什么模型啊模块啊都不懂,写毛线啊!! 如图:页面下拉还有侧栏,中间内容等. 可是答应跟老师做了,不能怂啊,于是硬着头皮,花两三天看在慕课网上学习Bootstrap(讲得挺好的,建议大白去看一下),其实我刚看完不久,里面很多东西其实作者都总结得很不错,还有演示. 收获很多,打算再看一下HTML的div+css布局,花一两天时间就可以写完那个界面.就是这么自信,哈哈哈~ 不逼自己一把,你永远不知道自己有多优秀.