The following code fails in Chrome, Safari, works fine in Firefox
"use strict";
document.body.style = "background-color: green;";
<p>background should be green</p>
The following code fails in Chrome, Safari, works fine in Firefox
"use strict";
document.body.style = "background-color: green;";
<p>background should be green</p>
Remove the "using strict" and it works.
Is that a bug in Chrome and Safari or a bug in Firefox? MDN says setting the style
is valid.
-
Read more carefully.
styles can not be set by assigning a string to the (read only) style property
– SLaks Commented Sep 8, 2015 at 22:44 - The code works on Chromium 50 (maybe before). – Oriol Commented Feb 2, 2016 at 19:27
1 Answer
Reset to default 13Problem
Not all browsers support assigning assigning a string which contains a textual representation of a CSS declaration block to the style
property.
element.style = styleString; // Might not work
Workaround
As a workaround, you can set it as a content attribute, or to the cssText
property:
element.setAttribute('style', styleString);
element.style.cssText = styleString;
Standard behavior
On older browsers pliant with DOM L2 Style and ES5, the assignment should
- Throw in strict mode
- Be ignored in non-strict mode.
On newer browsers pliant with CSSOM and ES5, the assignment should
- Always work
Full details
According to the DOM Level 2 Style spec, the style
property is defined in the ElementCSSInlineStyle
interface as follows:
interface ElementCSSInlineStyle {
readonly attribute CSSStyleDeclaration style;
};
Therefore, the style
property should be implemented as an accessor property with a getter but without a setter.
Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'style'); /* {
configurable: true,
enumerable: true,
get: function(){...},
set: undefined
} */
According to ECMAScript 5, when you attempt to assign some value to a property like that, an error must be thrown in strict mode:
When an assignment occurs within strict mode code, [...] the LeftHandSide also may not be a reference [...] to an accessor property with the attribute value {[[Set]]:undefined} [...]. In these cases a TypeError exception is thrown.
However, DOM L2 Style is superseded by the newer CSS Object Model (CSSOM).
According to the that spec, the style
IDL attribute of the interface ElementCSSInlineStyle
, implemented by HTMLElement
, is defined as a [PutForwards]
extended attribute:
[NoInterfaceObject]
interface ElementCSSInlineStyle {
[SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
};
That means that setting the style
property must behave like setting the cssText
one of the CSSStyleDeclaration
. Therefore, those must be equivalent:
element.style = styleString;
element.style.cssText = styleString;
And that's why it works on newer browsers.