所有 CSS 规则都允许用于所有 HTML 元素吗?它们是否都可以继承?
Are all CSS rules allowed on all HTML elements and can they all be inherited?
鉴于某些 CSS 规则是针对特定 HTML 元素量身定制的(一些示例 - object-fit
用于 <img>
、<video>
等;stroke
、fill
和各种 SVG 元素的其他 SVG 规则)并且在其他元素上使用时意义不大:
- 将任何有效CSS规则应用于任何HTML元素是否合法?
- 任何规则都可以继承吗?
- 什么是继承值,特别是当它继承自使用特定 属性 没有意义的元素时?
我的具体问题是这样的。我正在开发一个带有模块化 CSS 的按钮组件。在此按钮内,我可能有一个用于显示图标的 SVG 元素。我希望能够从组件外部将某些样式应用于图标(即描边和填充),同时保留适当的封装(所以深度选择器是禁忌)。
为了解决这个问题,我将 SVG 设置为从按钮继承描边和填充。如果我现在将这些属性应用到按钮,图标会继承它们,我会得到想要的结果!
然而,这让我想知道我所做的是否有效以及其他浏览器是否会表现相同。
这似乎是常识,但要找到明确的答案却出奇地困难。如果有人能指出规范的摘录甚至一些支持表,我会很高兴!
考虑到我编写代码的方式,显示 100% 准确的示例有点过分,但基本上我是在问这是否有效:
.icon {
stroke: inherit;
fill: inherit;
}
.button {
stroke: #FFF;
fill: #999;
}
<button class="button">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
<g stroke-width="2" transform="translate(1 1)">
<path d="M14 2L2 14"/>
<circle cx="8" cy="8" r="8"/>
</g>
</svg>
<span>My button</span>
</button>
is it still legal to apply any valid CSS rule to any HTML element?
是的,但如果它不受支持或不适用于此类元素,它可能会被您的浏览器忽略。
Furthermore, can any rule be inherited?
是的,但您应该注意继承考虑计算值,这可能会有所不同:
The inherit CSS keyword causes the element for which it is specified to take the computed value of the property from its parent element. It can be applied to any CSS property, including the CSS shorthand all. ref
我没有与 SVG 相关的简单示例,但这是另一个:
.box {
display:inline-block;
float:left;
width:200px;
height:200px;
border:1px solid red;
}
.box > div {
display:inherit;
border:1px solid green;
}
<div class="box">
<div>text</div>
</div>
请注意内部 div 将如何使 display
等于 block
而不是 inline-block
因为 float 将强制显示的计算值被阻塞 .box
为避免处理继承问题,您可以考虑 CSS 个适用于您的案例的变量:
.icon {
stroke: var(--s);
fill: var(--f);
}
.button {
--s: #FFF;
--f: #999;
}
<button class="button">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
<g stroke-width="2" transform="translate(1 1)">
<path d="M14 2L2 14"/>
<circle cx="8" cy="8" r="8"/>
</g>
</svg>
<span>My button</span>
</button>
Temani 的回答很有帮助,为我指明了正确的方向。经过一番研究后,我想我现在可以 post 对我自己的问题给出一个更详尽和正确引用的答案。
将任何有效的 CSS 规则应用于任何 HTML 元素是否合法?
对,就是。这在 CSS2.1 规范中说明得很清楚:https://www.w3.org/TR/CSS2/about.html#applies-to(CSS3 是 CSS2.1 的 module-based backwards-compatible 扩展,所以这个仍然适用)。它说:
All elements are considered to have all properties, but some properties have no rendering effect on some types of elements. For example, the 'clear' property only affects block-level elements.
所有元素都被认为具有所有属性隐式意味着任何属性可以在任何元素上设置
某些属性对某些元素没有渲染效果表示某些元素在渲染时忽略某些属性(这并不意味着它们不能被继承,请继续阅读)。
任何规则都可以继承吗?
要回答这个问题,让我们看一下 CSS 值和单位模块级别 3 规范:https://www.w3.org/TR/css3-values/#common-keywords。它指出:
All CSS properties also accept the CSS-wide keyword values as the sole component of their property value.
共有三个 CSS-wide 关键字值:initial
、inherit
和 unset
。
规范本质上是说任何 属性 都可以使用 inherit
作为其值,因此问题的答案是 是 。然而,重要的细节是如何确定继承值。正如 Temani 已经指出的那样,它并不像看起来那么简单。
如何计算继承值?
CSS 级联和继承级别 3 规范是关于级联和继承的重要读物:https://www.w3.org/TR/css-cascade-3/。它指出:
The inherited value of a property on an element is the computed value of the property on the element’s parent element.
根据规范,这是我确定任何元素上任何 属性 的 计算值 过程的简化版本:
收集元素上 属性 的所有 声明值 - 即在中找到的所有相关且有效的 CSS 声明开发人员样式表和样式属性、用户代理样式表等
确定 级联值 - 所有声明值的获胜值(这是规则优先的地方,单个规则排在首位)。
如果没有级联值,使用继承值如果属性被继承
如果 属性 未被继承(请参阅此问题以获取默认继承的属性列表:Which CSS properties are inherited?),使用 initial值。根据规范,每个 属性 都有一个初始值(例如,初始 font-size
是 medium
;值得注意的是,它不是像 16px
这样的绝对值!)。
此时一个属性将有some 分配给它的值,但它可能是一个相对值,即依赖于其他一些 CSS 属性(例如百分比值取决于一些绝对值,例如parent 的绝对尺寸)。在此步骤中,将尽可能解析一个值,使其明确无歧义,并为继承做好准备.
重要的是要注意,就像规范为每个 属性 定义了一个 初始值 一样,它还定义了如何导出 计算值。例如。 MDN 为 font-size:
指定了这个计算值
as specified, but with relative lengths converted into absolute lengths
所以 medium
仍然是 medium
,但是 1.2em
变成了 19.2px
(如果 parent 的字体大小是 16px
).
重要的一点
相同的级联和继承规范指出:
The computed value exists even when the property does not apply (as defined by the “Applies To” line). However, some properties may change how they determine the computed value based on whether the property applies to the element.
因此每个元素都会有一个 计算值 用于每个 属性,但可能不会使用它(so-called 使用的值,即计算值后的下一步,是none)。计算出的值将被继承。
这对我的 SVG 按钮示例意味着什么:
- 我绝对可以在
<button>
上设置 stroke
和 fill
。它会在渲染自身时忽略此 属性,但如果需要,会将其传递给它的 children。
- child SVG 默认会继承这些属性(我什至不需要明确指定)。
stroke
和 fill
的计算值没有任何注意事项,因此我可以预期会继承正确的颜色(确实如此!)。
鉴于某些 CSS 规则是针对特定 HTML 元素量身定制的(一些示例 - object-fit
用于 <img>
、<video>
等;stroke
、fill
和各种 SVG 元素的其他 SVG 规则)并且在其他元素上使用时意义不大:
- 将任何有效CSS规则应用于任何HTML元素是否合法?
- 任何规则都可以继承吗?
- 什么是继承值,特别是当它继承自使用特定 属性 没有意义的元素时?
我的具体问题是这样的。我正在开发一个带有模块化 CSS 的按钮组件。在此按钮内,我可能有一个用于显示图标的 SVG 元素。我希望能够从组件外部将某些样式应用于图标(即描边和填充),同时保留适当的封装(所以深度选择器是禁忌)。
为了解决这个问题,我将 SVG 设置为从按钮继承描边和填充。如果我现在将这些属性应用到按钮,图标会继承它们,我会得到想要的结果!
然而,这让我想知道我所做的是否有效以及其他浏览器是否会表现相同。
这似乎是常识,但要找到明确的答案却出奇地困难。如果有人能指出规范的摘录甚至一些支持表,我会很高兴!
考虑到我编写代码的方式,显示 100% 准确的示例有点过分,但基本上我是在问这是否有效:
.icon {
stroke: inherit;
fill: inherit;
}
.button {
stroke: #FFF;
fill: #999;
}
<button class="button">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
<g stroke-width="2" transform="translate(1 1)">
<path d="M14 2L2 14"/>
<circle cx="8" cy="8" r="8"/>
</g>
</svg>
<span>My button</span>
</button>
is it still legal to apply any valid CSS rule to any HTML element?
是的,但如果它不受支持或不适用于此类元素,它可能会被您的浏览器忽略。
Furthermore, can any rule be inherited?
是的,但您应该注意继承考虑计算值,这可能会有所不同:
The inherit CSS keyword causes the element for which it is specified to take the computed value of the property from its parent element. It can be applied to any CSS property, including the CSS shorthand all. ref
我没有与 SVG 相关的简单示例,但这是另一个:
.box {
display:inline-block;
float:left;
width:200px;
height:200px;
border:1px solid red;
}
.box > div {
display:inherit;
border:1px solid green;
}
<div class="box">
<div>text</div>
</div>
请注意内部 div 将如何使 display
等于 block
而不是 inline-block
因为 float 将强制显示的计算值被阻塞 .box
为避免处理继承问题,您可以考虑 CSS 个适用于您的案例的变量:
.icon {
stroke: var(--s);
fill: var(--f);
}
.button {
--s: #FFF;
--f: #999;
}
<button class="button">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
<g stroke-width="2" transform="translate(1 1)">
<path d="M14 2L2 14"/>
<circle cx="8" cy="8" r="8"/>
</g>
</svg>
<span>My button</span>
</button>
Temani 的回答很有帮助,为我指明了正确的方向。经过一番研究后,我想我现在可以 post 对我自己的问题给出一个更详尽和正确引用的答案。
将任何有效的 CSS 规则应用于任何 HTML 元素是否合法?
对,就是。这在 CSS2.1 规范中说明得很清楚:https://www.w3.org/TR/CSS2/about.html#applies-to(CSS3 是 CSS2.1 的 module-based backwards-compatible 扩展,所以这个仍然适用)。它说:
All elements are considered to have all properties, but some properties have no rendering effect on some types of elements. For example, the 'clear' property only affects block-level elements.
所有元素都被认为具有所有属性隐式意味着任何属性可以在任何元素上设置
某些属性对某些元素没有渲染效果表示某些元素在渲染时忽略某些属性(这并不意味着它们不能被继承,请继续阅读)。
任何规则都可以继承吗?
要回答这个问题,让我们看一下 CSS 值和单位模块级别 3 规范:https://www.w3.org/TR/css3-values/#common-keywords。它指出:
All CSS properties also accept the CSS-wide keyword values as the sole component of their property value.
共有三个 CSS-wide 关键字值:initial
、inherit
和 unset
。
规范本质上是说任何 属性 都可以使用 inherit
作为其值,因此问题的答案是 是 。然而,重要的细节是如何确定继承值。正如 Temani 已经指出的那样,它并不像看起来那么简单。
如何计算继承值?
CSS 级联和继承级别 3 规范是关于级联和继承的重要读物:https://www.w3.org/TR/css-cascade-3/。它指出:
The inherited value of a property on an element is the computed value of the property on the element’s parent element.
根据规范,这是我确定任何元素上任何 属性 的 计算值 过程的简化版本:
收集元素上 属性 的所有 声明值 - 即在中找到的所有相关且有效的 CSS 声明开发人员样式表和样式属性、用户代理样式表等
确定 级联值 - 所有声明值的获胜值(这是规则优先的地方,单个规则排在首位)。
如果没有级联值,使用继承值如果属性被继承
如果 属性 未被继承(请参阅此问题以获取默认继承的属性列表:Which CSS properties are inherited?),使用 initial值。根据规范,每个 属性 都有一个初始值(例如,初始
font-size
是medium
;值得注意的是,它不是像16px
这样的绝对值!)。此时一个属性将有some 分配给它的值,但它可能是一个相对值,即依赖于其他一些 CSS 属性(例如百分比值取决于一些绝对值,例如parent 的绝对尺寸)。在此步骤中,将尽可能解析一个值,使其明确无歧义,并为继承做好准备.
重要的是要注意,就像规范为每个 属性 定义了一个 初始值 一样,它还定义了如何导出 计算值。例如。 MDN 为 font-size:
指定了这个计算值
as specified, but with relative lengths converted into absolute lengths
所以 medium
仍然是 medium
,但是 1.2em
变成了 19.2px
(如果 parent 的字体大小是 16px
).
重要的一点
相同的级联和继承规范指出:
The computed value exists even when the property does not apply (as defined by the “Applies To” line). However, some properties may change how they determine the computed value based on whether the property applies to the element.
因此每个元素都会有一个 计算值 用于每个 属性,但可能不会使用它(so-called 使用的值,即计算值后的下一步,是none)。计算出的值将被继承。
这对我的 SVG 按钮示例意味着什么:
- 我绝对可以在
<button>
上设置stroke
和fill
。它会在渲染自身时忽略此 属性,但如果需要,会将其传递给它的 children。 - child SVG 默认会继承这些属性(我什至不需要明确指定)。
stroke
和fill
的计算值没有任何注意事项,因此我可以预期会继承正确的颜色(确实如此!)。