如果几天之前有人走近我,然后问我inherit
和initial
有什么区别,我可能会这样回答:
“啥?有区别?”
CSS 我写了十多年,但总是没去触碰initial
到底是个什么。称之为无知、懈怠也好,或者运气好也罢,反正我就是没有在意它,并且在可能会用到这个值的场合甚至没有想去查询一下。所以,这篇文章就要分享一些我刚学到的东西。
# initial 是什么意思
首先,规范可以帮助我们理解“initial关键字”和“初始值(initial value)”之间的区别:
- Initial 关键字: 如果一个属性的层叠值是一个 initial 关键字,则这个属性的 initial 值就是其 指定值(specified value -- 译注:此处指规范中针对这个属性的初始值)
- 初始值: 每个属性都有个初始值,定义在该属性的规范表中。如果该属性不是一个可继承属性,并且层叠关系没有导致一个值,则 指定值 就被作为初始值
呃...好吧。我用 Google 翻译(说着玩的!)浏览了那些定义,并且总结出这一句:
`initial 关键字`是作为初始值最终输出的属性而声明的,并由浏览器默认设定来定义。
所以,如果 initial 关键字被这样使用:
.module {
color: initial;
}
...并且如果浏览器默认将该元素的颜色属性值设为了 black,则初始值就应该会返回 black。
# 和 inherit 又有什么区别呢
如果你在琢磨:“这和inherit
非常像呀”,那你绝对是正确的 -- 的确非常像。
但让initial
和inherit
有所区别的额外步骤是,inherit
会检查在采用初始值之前,是否可以继承层叠关系中的其他属性值。

如上图所示,H1 尝试去继承一个颜色值,并在 body 元素上找到了。

# 举个例子来说明区别
<div class="module">
<div class="inherit">
<h1>Inherited Styles</h1>
<p>这里会继承父元素 .module 的样式</p>
</div>
</div>
<div class="module">
<div class="initial">
<h1>Initial Styles</h1>
<p>这里将被重置为浏览器设置的初始值</p>
</div>
</div>
body {
background-color: #eaeaea;
display: flex;
}
.module {
background-color: #fff;
border: 1px solid #ddd;
color: red;
font-family: Helvetica;
font-size: 18px;
padding: 20px;
width: 50%;
}
.inherit {
color: inherit;
font-family: inherit;
font-size: inherit;
}
.initial {
color: initial;
font-family: initial;
font-size: initial;
}
.initial h1 {
color: initial;
}
看到了吧?左边的所有属性都继承了其父元素 .module ,而另一边则通过 initial 关键字,被重置为浏览器默认的属性。
# 什么时候使用 initial
我习惯于将 initial 视为一种 `hard reset`。随着 CSS 不断增长,样式很容易变得费解,这时使用 initial 就不失为一种让事情清晰的途径,让元素回到其原本的状态。如果用老式的任天堂红白机打个比方,initial 就是和把游戏卡带从控制台拔出再插回去一样的重置动作(尽管这样做也不见得有效)。
但这并不意味着 initial 就是重置的银弹(译注:西方传说中对付狼人等恶魔的特效武器)。因为初始值始终服从于浏览器的默认,而众所周知每个浏览器是不一样的。
等等,你要用 CSS resets (https://meyerweb.com/eric/tools/css/reset/) ?那么你可以将其视为(浏览器)初始值的替代。
简单来说:使用 initial 来完全消除任何样式继承,而用 inherit 确保元素从最靠近的父元素上继承样式。
# 更实用的一个用例
这里有一个 initial 如何被用于创建表格中的交替彩色线条的例子:
<thead>
<tr>
<td>Dad</td>
<td>Show</td>
<td>Job</td>
</tr>
</thead>
<tbody>
<tr>
<td>Homer Simpson</td>
<td>The Simpsons</td>
<td>Safety Inspector</td>
</tr>
<tr>
<td>Hank Hill</td>
<td>King of the Hill</td>
<td>Propane & Accessories</td>
</tr>
<tr>
<td>Peter Griffin</td>
<td>Family Guy</td>
<td>Safety Inspector</td>
</tr>
<tr>
<td>Bob Belcher</td>
<td>Bob's Burgers</td>
<td>Head Chef</td>
</tr>
<tr>
<td>Fred Flinstone</td>
<td>The Flinstones</td>
<td>Crane Operator</td>
</tr>
</tbody>
</table>
/* DEMO STYLES */
body {
color: #999;
}
table {
background-color: #fff;
}
tbody tr { /*自定义的颜色和背景色*/
background-color: #eaeaea;
color: #ff9e2c;
}
tbody tr:nth-child(odd) { /*浏览器默认的样式*/
background-color: inherit;
color: initial;
}
/* PRESENTATONAL STYLES */
body {
background-color: #333;
font-family: Helvetica;
padding: 25px 0;
}
table {
box-shadow: 1px 2px 3px #222;
margin: 0 auto;
}
thead {
background-color: #ff9e2c;
color: #fff;
font-size: 1.25em;
font-weight: 800;
text-shadow: 0 1px 2px #c56a00;
}
tbody tr {
border-top: 1px solid #ccc;
}
tbody tr:last-child {
border-bottom: 1px solid #ccc;
}
td {
padding: 10px 15px;
}
# 浏览器支持程度
MDN 上有关于 initial 当前支持程度的分类,注意醒目的 IE 不支持。
# 结语
我已经绞尽脑汁来举出一些有意思的 initial 用例了。虽然我发现了很多可以将其用作元素默认样式的潜在价值,但我还没在一个实用的应用中遇到它们 -- 尽管这更多是归因于我而非这个属性本身。
使其变得真正有用的,将会是 all
作为一个属性获得更多支持的时候。声明 all: initial
将成为重置元素真正强大的工具。
.module {
all: unset;
}
----------------------------------------
