Does CSS change the DOM?

Viewed 710

I was wondering if CSS changes the DOM. The reason I am asking, is that whenever I change an Element with CSS, I don't see it's value changed in the "element".style properties.

3 Answers

No. CSS does not change the DOM. Nor content injected using :after or :before alter the DOM.

Actually... there are a few cases where CSS can change the DOM, but it's a bit far-stretched, as it won't change the DOM-tree structure, except in one yet even more far stretched case...

There is a being rendered definition in the HTML specs that does impact the behavior of the DOM in some cases, based on CSS computed styles.

For instance,

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">

  • Elements that are not being rendered can not be focusable elements:

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">

And the one case where the DOM tree is modified, concerns the DOM tree of an inner Document: When an <object> or an <embed> element has its style set to display:none, per specs, its inner Document should be reloaded:

Whenever one of the following conditions occur

[...]

  • the element changes from being rendered to not being rendered, or vice versa,

...the user agent must queue an element task on the DOM manipulation task source given the object element to run the following steps to (re)determine what the object element represents.

So this means that simply switching the being rendered state of such an <object> or <embed> element is supposed to reload entirely its inner Document, which means also its DOM tree.

Now, only Safari behaves like that, Firefox never implemented that behavior, and Chrome did recently change their to match FF's one, against the specs.
For Safari users, here is a fiddle demonstrating it.

Related