如果前几天有人走过来问我 inherit
和 initial
之间的区别,我可能会回答
“什么,它们有区别吗?”
我已经编写 CSS 超过十年了,但我似乎一直没有理解 initial
到底是什么或它有什么作用。管它是无知、懒惰还是幸运,但 inherit
一直满足我的需要,我从未想过要研究什么时候应该使用 initial
而不是 inherit
。因此,这篇文章将分享我学到的一些东西。
initial
的含义
首先,规范帮助我们理解初始 _关键字_ 和初始 _值_ 之间的区别。
- 初始关键字: 如果属性的级联值是初始关键字,则属性的初始值将成为其指定值。
- 初始值: 每个属性都有一个初始值,在属性定义表中定义。如果属性不是继承属性,并且级联不会导致任何值,则属性的指定值将是其初始值。
嗯,好的。我将这些定义通过谷歌翻译(开玩笑!)后得到了以下结果
初始关键字是在初始值是最终输出的属性中声明的,该值由浏览器默认值定义。
因此,如果这里使用了 initial
关键字
.module {
color: initial;
}
…那么 initial
值可能会返回 black
,如果 black
是该元素属性的浏览器默认值。
inherit
的区别
它与 如果您认为这 听起来很像 inherit
,那么您绝对是对的。它确实听起来非常像。
但 initial
和 inherit
在 inherit
检查级联中是否存在其他属性以供使用之前再执行额外的一步来获取初始值方面有所区别。


区别示例
查看 CodePen 上由 CSS-Tricks (@css-tricks) 创建的 CSS Initial 与 Inherit。
看到了吗?左侧框中的属性都设置为继承 .module
类,因为它是最接近的父元素。另一方面,右侧框中的属性设置为 initial
,它将元素的属性重置为浏览器默认值。
initial
何时使用 我喜欢将 initial
视为一个硬重置。随着 CSS 的增长,样式很容易变得复杂,而使用 initial
是一种将元素恢复到其自然状态的方法。如果 initial
是老式的任天堂游戏,我将使用它来模拟将有问题的游戏卡从控制台中取出并 吹吹(尽管这样做 据说毫无效果)。
但这并不意味着 initial
是重置的灵丹妙药。这是因为初始值仍然受浏览器默认值的影响,而我们知道浏览器默认值可能会 因浏览器而异。
哦,等等,您使用 CSS 重置 吗?您可以预期它们用作初始值。
底线:我将使用 initial
来完全清除元素的任何继承样式,并使用 inherit
来确保元素从最近的父元素获取提示。
更实用的用例
以下是如何使用 initial
在表格中创建交替颜色线的示例。
查看 CodePen 上由 CSS-Tricks (@css-tricks) 创建的 CSS Initial。
浏览器支持
MDN 有一个很好的细分,介绍了 initial
的当前支持情况。请注意 IE 支持的明显缺失。
Chrome | Safari | Firefox | Opera | IE | Android | iOS |
---|---|---|---|---|---|---|
是 | 是 | 19 | 15 | 否 | 是 | 是 |
总结
我一直绞尽脑汁想找到一些 initial
的有趣用例。虽然我认为能够在元素上使用默认样式具有很大的潜在用途,但我还没有在实际应用中遇到过它们——但这可能更多地反映了我个人而不是属性值本身。
当 all
作为属性 获得更多支持时,这将非常有用。这样,声明 all: initial
将成为在任何元素上创建重置的真正强大的工具。
请分享您在项目中必须使用 initial
的任何情况。如果您用它来完成任何棘手的任务,则加分。
“将要”而不是“gonna”。
Woowoo,那是语法警察的声音!
哦,拜托!
display: none
对每个元素都有效,当您想使用类隐藏某些内容时,它很有用。但是,如果您想在不为每个元素创建多个选择器的情况下,以给定元素的正确值显示它,该怎么办?
没错,您可以使用
initial
。这正是我希望
initial
在任何地方都得到支持的原因。这很好!
还值得注意的是,
display: initial;
似乎始终返回display: inline;
,因此如果使用不当,可能会出现一些问题。不幸的是,正如 Geoff 指出的那样,这个很好的用例实际上不会像您希望的那样工作。
initial
值是为每个属性定义的(例如,为display
),而不是为任何特定的标签名称(例如,li
)。HTML 标签名称和显示类型之间的关联是通过浏览器样式表应用的,该样式表被视为一个普通的 CSS 样式表,它在处理网站的任何样式之前运行。这些默认样式与你自己的代码一样,都会被initial
重置。相反,有极少数属性,例如
font-family
,其规范没有指定初始值。在这种情况下,浏览器的默认值就是初始值。但是,如果浏览器对标题和段落应用不同的字体系列,那又是浏览器样式表,而initial
值会将它们都重置为相同的总体默认值(无论它是什么)。@Amelia:所以我对它的一个用例就是它不适用的用例?好吧,这就是 web 开发。感谢你让我摆脱了我的希望和梦想:D:D:D
如果再有一个关键字可以重置为浏览器默认值,那就太好了,类似于
将块级元素重置为
block
,将内联元素重置为inline
等。这是真的吗?我的理解是,它仍然会将你的样式重置为浏览器默认值,而不是重置样式表中设置的默认值。我的意思是,如果后者是这种情况,我会非常高兴,如果是的话,请有人告诉我,这样我至少有一个理由对 CSS 感到高兴 :)
当我第一次开始深入研究时,我也想过完全相同的事情,但我发现 CSS 重置确实会作为值返回。你可以通过添加 CSS 重置并查看它如何影响样式来玩弄示例笔。
http://codepen.io/team/css-tricks/pen/wazyoV
据我所知,
initial
不会使用重置中指定的 value。但是,它可能看起来像是这样,因为许多属性的初始值与重置定义的 value 相同。这意味着它恰好与重置相同。以下是一个initial
明显不使用重置中定义的 value 的示例。Paul 说得对。虽然这在很多情况下都有效,但它更多是巧合而不是设计。
大多数标准的“CSS 重置”技术的目的是取消浏览器的默认 HTML 样式表,而是将 value 设置为 CSS 初始值。在这些情况下,你可以使用
initial
并获得相同的效果。但是,如果你使用任何其他类型的 CSS 重置(重置为除规范中定义的初始值之外的 value),你无法使用
initial
来重新创建它。例如,如果你使用重置将box-sizing
更改为每个元素和 before/after 伪元素的border-box
,这与box-sizing: initial
非常不同。完全缺乏 IE 支持使其毫无意义。
同意,这使得 IE 毫无意义。
IE 团队一直都在睡觉。当伟大的浏览器做了一些事情的时候,IE 无处可寻!
IE 太糟糕了。毫无疑问。但是,如果他们不支持它,你就不能真正使用它。我讨厌它,但这就是它的现状。
这篇文章中的一些图表和散文有点误导人。
initial
不等同于从:root
继承,它也不总是“浏览器默认值”。http://codepen.io/telic/pen/NqdjwV
初始值独立于级联中设置的任何 value,包括用户代理样式表中设置的默认值!例如,上面示例笔中的
initial
value 导致内部 div 成为内联而不是块级。我当然可以理解这一点,尽管图表说明的是一种情况,而不是所有情况。你在这里当然是正确的!
我找到了这个
来源
看起来它会重置为规范中定义的 value,与元素的默认 value 无关。因此
display
将为a
、div
、table
甚至option
设置为inline
。对我来说,它基本上是无用的。这篇文章似乎对“initial”有一个基本的误解。它不像“inherit”,它与根元素上设置的属性无关,除了根元素通常不会被过多地设置样式。
“Initial”仅仅是属性在任何 value 被样式表设置之前(无论是浏览器(又名“UA”)样式表、作者(web 设计师或开发人员)样式表还是用户样式表)的 value。
UA 样式表可以被认为是“浏览器默认值”,并且在不同的浏览器之间差异很大。这些差异主要由重置样式表消除,这些样式表还会删除许多有用的 value,例如段落的边距。
但是所有符合规范的浏览器都以规范中定义的初始 value 开始。这就是为什么 UA 样式表有“div { display: block }”,但它们不需要“span { display: inline }”,因为无论元素是什么,内联都是“display”属性的“默认”初始 value,直到样式表将其设置为其他值。
另一方面,“inherit”意味着 value 来自 HTML 中的父元素。某些属性(如“color”)会自动继承,无需在样式表中设置任何内容。这就是为什么如果你在 P 标签上设置了“color: green”,你也不必在 P 内的 SPAN 上设置它(除非你担心 UA 样式表为 SPAN 明确设置了颜色,但这从未发生过)。
如果你使用“inherit”关键字作为 value,它会强制从父元素继承 value,即使它是通常不会自动继承的属性,例如“float”。因此,如果你在元素 A 上有“float: inherit”,并且该元素 A 的父元素 B 有“float: left”,那么元素 A 也将在浮动元素 B 内浮动到左侧。
@Brad 你说得完全正确,除了一个有点令人困惑的事情:
initial
和inherit
关键字在规范中是类似的,事实上它们是在同一个地方定义的。这是因为它们都覆盖了确定属性 value 的常规规则。我相信这种规范的相似性导致了人们认为功能也相似。@tom 我不认为说它们“覆盖了确定属性 value 的常规规则”是真正准确的。关键字为属性提供了 value,就像任何 value 一样。无论“initial”或“inherit”关键字是否有效,仍然取决于选择器特异性顺序、是否使用了“!important”,以及作者样式表是否覆盖 UA 样式表,就像任何其他 value 一样。
使关键字 value 不同于大多数其他 value 的是,使用的 value 与指定的 value 不同(本身并不罕见),但“initial”从属性的初始 value(如属性规范中定义)获得其使用 value,“inherit”从其 HTML 父元素的使用 value 获得其使用 value。这两个效果彼此非常不同,但它们使用关键字的方式与任何属性使用关键字的方式相同,例如“none”或“solid”。所有关键字 value 都分配了一些有意义的 value,这些 value 通常取决于属性,这些关键字也是如此。它们都以字母“i”开头,我想这可能更容易混淆它们。
它们在同一规范中定义并不意味着它们是相似的,就像“border”与“background”相似一样,因为它们在同一规范中,并且定义在彼此附近。同样,“solid”和“none”也不相似(作为边框样式),仅仅因为它们应用于同一规范中的相同属性,并且定义在彼此附近。使“initial”和“inherit”相似的主要原因是它们可以应用于任何属性。
要真正理解这两个关键字在分配给属性时所做的事情,你只需要理解它们的含义。无论是否存在可以用作属性 value 的关键字,其含义都存在。我认为有些人感到困惑,因为关键字是可以设置的东西。但是,即使没有设置,所有属性都有一个初始 value,而且很多属性都会自动继承。在任何 CSS 规则应用之前具有一个初始 value,这与查看 HTML 层次结构以查看父元素是否具有也应应用于子元素的属性 value(如颜色或字体大小)是一个非常不同的概念。一旦你理解了这两个概念,那么你能够使用的关键字的含义应该非常清楚和独特。
@Brad
initial
和inherit
都是关键字,它们是级联对任何属性的有效结果,而且在计算指定 value 时会得到特殊处理;来自级联级别 3 工作草案这就是我所说的它们相似的原因。我所说的“覆盖通常的规则”是指,通常属性的指定值与它的级联值相同(如果有);例外是级联值为
inherit
或initial
。如你所说,这与!important
意义上的覆盖不同,所以我可能用词不当;我的意思是,如果这些关键字是级联的结果,它们会改变属性值的计算方式。@Tom,好的,但要知道,使用值与指定值不同并不罕见。例如:‘width’可以指定为‘auto’或百分比,但使用值为以px为单位测量的具体长度。
@Brad
当然,是的。
initial
的独特之处在于它将指定值设置为与级联值不同。因此,HTML<div style="width: initial;"></div>
(假设没有其他 CSS)将使该div
上的width属性具有“initial”的级联值、“auto”的指定值和一些具体宽度(以px为单位)的计算值。看起来像是可以用来给自己制造麻烦的绳子。
也就是说,我接受它。对于那些只使用浏览器默认的Times New Roman字体的时候来说,它简直是完美的选择!
我不知道这一点,我一直只使用‘inherit’,所以知道‘initial’到底有什么作用真是太好了。
我犹豫着说出来,因为我认为你对CSS的了解比我多,但我认为你错过了
initial
的要点。初始值的存在是为了所有可能的值都需要一个默认值。CSS规范不能假设有任何用户代理样式表,因此它需要为所有可能的属性定义一个默认值。这些值大多是你所期望的,但有一些怪癖。由于这些是默认值,并且不引用任何类型的选择器,因此它们在所有元素的所有时间都是一样的。例如,如上面评论中所述,display
的初始值为inline
,这对span
元素来说是有意义的,但对div
或p
来说就不太合适了。(你可以在规范的第 4.1 节中查看初始值的列表)。所以你对规范的谷歌翻译并不完全正确。更好的描述应该是
(注意,还有一些额外的复杂情况:你会在表格中看到,一些初始值被列为特定于用户代理的;但是,这与任何用户代理样式表是分开的,最好将其视为浏览器的硬编码默认值。此外,我还忽略了指定值和计算值之间的区别,这一点很重要,因为
initial
关键字实际上设置的是指定值。)那么为什么要使用
initial
呢?老实说,除了好奇心之外,我想不出任何实际的理由。它肯定不能用作硬重置;从CSS解析器的角度来看,p { display: initial; }
和p { display: inline; }
之间没有区别,那么为什么要使用可读性较差的版本呢?一个实际的解决方案是使用initial在应用零字体大小技巧以消除内联块元素之间的空白后恢复字体大小。
如果HTML根元素大小保持不变,那么最终结果应该总是相同的:跳过继承。在这个特定的上下文中,initial至少能够更好地解释正在发生的事情。
当然,如今这只是一个非常小的用例:它需要基于模板的JS DOM使用或手动编写的HTML。像React或Mithril这样的现代DOM管理工具天生就没有空白问题。
非常好的总结!我认为你在这里说得没错,而且对我来说,它的用例也很模糊。有趣的是,虽然规范不能假设用户代理样式表,但事实上它们在很大程度上被广泛使用。这意味着一个更好(更具包容性)的定义可能是
我也绞尽脑汁想出一个好的用例。也许这就是为什么我直到现在才开始熟悉
initial
,并且在这么长时间内没有使用它。:)在开发将在各种环境中使用的窗口小部件或 Web 组件时,使用
initial
是一个好时机。#my-widget * { whatever: initial; }
比创建专门针对窗口小部件的重置表要容易得多。那么,各种环境是否排除了任何IE(台式机或移动设备)?那它有什么用呢?
我(尝试)只使用在所有地方都受支持的属性,或者在不使用的情况下不会产生灾难性影响的属性。但使用initial可能会完全破坏布局,所以在我看来,使用它并不安全。
排除IE是一个很好的用例,尽管规范编写者并没有这样打算。例如,‘display:none; display:initial’将在IE中隐藏某些内容,而在所有其他浏览器中将其显示为‘inline’。
这个列表真的很棒。这是我第一次访问你的博客,我对你的文章印象非常深刻。你也可以看看我的官方博客......谢谢。
http://www.1bag.co/
这些文章中缺少的是一个警告,提醒人们不要使用这些属性,因为它们对不支持它们的浏览器来说可能非常有害。就像这里一样,这可能是IE,但也存在其他情况,比如Firefox中的Display table(定位问题)或Chrome中的transform怪癖,或者(<9?) Safari中的Background-size值。
再加上只在某些浏览器中进行选择性测试,而且主要是在一个平台上,这会导致网站无法在所有地方正常工作,而这正是网络的意义所在,对吧?
我实际上看到了一个例子,一个经验不足的开发人员使用initial来设置“Position”,这完全破坏了IE中的布局,而只需使用类似Position: static这样的东西就能使它在(几乎)所有浏览器中正常工作。
抱歉,但说实话,我认为像CodePen这样的网站负有一定责任,因为它们倾向于谈论新事物,而且不可否认地,这些新事物很令人兴奋,但它们没有适当地警告人们在旧浏览器或功能较弱的浏览器(这些浏览器并非总是IE)中存在的问题。
我最近遇到了这个问题,因为我认为
initial
正如你所说的,将值重置回该元素的浏览器默认值。但它实际上重置的是属性,而不是元素。
请参见此处定义的display的初始值为
inline
。https://mdn.org.cn/en-US/docs/Web/CSS/display请查看Jack McNicol ( @jackmcpickle) 在 CodePen 上创建的示例 xGrzYx。
为了清楚起见:“inherit”也不会将值重置回元素默认值。它将值设置为父元素的该属性的值。
@Brad Kemper:使用 display: initial 来隐藏 IE 中的内容(但也猜想包括像 Android 和 Opera Mini 这样的旧浏览器?)听起来像是一个糟糕的 hack。我想没有回退机制吧?:(
在我看来,这似乎不是一个好主意。如果你这样做,你到底在测试什么?“只向那些理解
initial
关键字的浏览器显示此内容吗?”有很多更好的方法来进行功能测试或用户代理嗅探。