CSS改变DOM吗?

3
我在想CSS是否会改变DOM。 我问这个问题的原因是,每当我用CSS更改一个元素时,我并没有看到它的值在“element”.style属性中发生变化。

1
不,它不会。这个观察是正确/预期的。浏览器开发者工具将显示计算样式表的值。 - user2864740
所以如果我理解正确,每当DOM被渲染时,它会将样式表的值作为默认/初始值? - Ben Ashkenazi
在某种程度上是的,尽管显式元素样式属性更像是“覆盖”而不是“默认”。然后CSS渲染引擎会将所有样式表值(内联元素样式、外部样式表和内置浏览器默认样式表)合并在一起,并根据优先级确定要应用的规则。单个元素样式更像是“覆盖”,因为只有!important可以改变这些值。这也是为什么它们通常作为最后的选择更好的原因。 - user2864740
这些样式源也是“实时”的,任何对它们的更改(由浏览器观察到)都将反映在渲染中。无论如何,DOM仍然只提供值。 - user2864740
3个回答

3
不,CSS不会改变DOM。

0

不,CSS 不会改变 DOM。 使用 :after 或 :before 注入的内容也不会改变 DOM。


我明白,非常有趣。那么CSS改变了什么?为什么它不影响DOM? - Ben Ashkenazi
@BenAshkenazi - CSS与HTML文档结合形成渲染树。DOM是用于操作HTML文档的API。 - Alohci
所以如果我理解正确,每当DOM呈现时,它会将样式表的值作为默认/初始值? - Ben Ashkenazi

0

实际上...有一些情况下CSS可以改变DOM,但这有点牵强,因为它不会改变DOM树的结构,除非在一个更加牵强的情况下...

在HTML规范中有一个正在渲染的定义,在某些情况下会影响DOM的行为,基于CSS计算样式。

例如,

  • HTMLImageElement可以通过widthheight IDL属性值的改变是否正在渲染来改变:

onload = (evt) => {
  console.log( 'rendered', document.getElementById( 'disp' ).width );
  console.log( 'not rendered', document.getElementById( 'no-disp' ).width );
}
img { width: 100px; } 
#no-disp { display: none; }
<img id="disp" src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png">
<img id="no-disp" src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png">

  • 没有被渲染的元素不能成为可聚焦的元素:

document.getElementById( 'rendered' ).focus();
console.log( document.activeElement ); //  <input id="rendered">
document.getElementById( 'rendered' ).blur();

document.getElementById( 'not-rendered' ).focus();
console.log( document.activeElement ); //  <body>
#not-rendered {
  display: none;
}
<input id="rendered">
<input id="not-rendered">

而唯一一种情况下,DOM树被修改的是关于内部文档的DOM树:当一个<object>或<embed>元素的样式设置为display:none时,根据规范, 它的内部文档应该重新加载:

每当发生以下条件之一时

[...]

...用户代理必须在DOM操作任务源上为对象元素排队一个元素任务,以执行以下步骤来(重新)确定对象元素代表什么。

这意味着简单地切换这样一个<object>或<embed>元素的渲染状态就会完全重新加载其内部文档,也就是它的DOM树。

现在,只有Safari的行为是这样的,Firefox从未实现过这种行为,而Chrome最近更改了他们的以与FF的一致,违反规范。
对于Safari用户,这里有一个展示它的示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接