1

I am familiar with the use of setting inline styles on elements using the elements style property. For style properties which are hyphenated in a style sheet, the most common example is to use the dot-property, using a camel cased version of the property, eg,

element.style.fontSize = "14pt";

And like any other object, the same can be accomplished using the bracketed key form, eg:

element.style["fontSize"] = "14pt";

However, I discovered by accident, using the hyphenated property as a key also works in Firefox:

element.style["font-size"] = "14pt";

I am wondering if this form is reliable in all browsers. Ie, for element.style, will the hyphenated version alongside of the camel-cased version of the property always be present, and point to the same value? Is it part of the spec, or is this just an implementation detail for Firefox? My research of the use of inline styles in w3.org and MDN have not made this detail clear to me, as all examples I have seen only show the dot-property using the camel-cased version.

The bracketed key form is useful in some cases such as iterating over various properties, and to not have to deal with both the hyphenated and camel cased versions of the keys would be especially helpful, however I want to be sure this is reliable.

Edit: I'm hoping to find something definitive, like something in the spec which directly addresses this, or something in the definition of the element.style property which would make it absolutely clear.

Edit: It was suggested that my answer could be found in How do I reference a JavaScript object property with a hyphen in it? , however this does not actually answer my question. This (like the title states) asks a general js question as to how to deal with js properties with hyphens (even though the op happened to use element.style as an example.) What I am asking is specific to element.style, and whether in all browsers, will the hyphenated version of the property always exist alongside of the camel-cased version, and point to the same value?

TylerH
  • 20,799
  • 66
  • 75
  • 101
KevinHJ
  • 1,014
  • 11
  • 24

2 Answers2

2

The documentation links to the relevant specification.

An HTMLElement.prototype.style getter results in a CSS2Properties object which inherits from CSSStyleDeclaration, the specification of which has a few relevant paragraphs about camel-cased properties:

The camel-cased attribute attribute, on getting, must return the result of invoking getPropertyValue() with the argument being the result of running the IDL attribute to CSS property algorithm for camel-cased attribute.

Setting the camel-cased attribute attribute must invoke setProperty() with the first argument being the result of running the IDL attribute to CSS property algorithm for camel-cased attribute, as second argument the given value, and no third argument. Any exceptions thrown must be re-thrown.

… and about dashed properties:

The dashed attribute attribute, on getting, must return the result of invoking getPropertyValue() with the argument being dashed attribute.

Setting the dashed attribute attribute must invoke setProperty() with the first argument being dashed attribute, as second argument the given value, and no third argument. Any exceptions thrown must be re-thrown.

The mentioned IDL attribute to CSS property algorithm is a way of normalizing a property key before getting or setting the actual key and value. Therefore, the equivalence of the camel-cased and hyphenated version of properties is specified.

But there’s a single exception: float. Because ECMAScript editions 1, 2, and 3 disallowed reserved words as property names, using element.style.float was impossible; since the 5th edition it’s possible. The usable property is called cssFloat and the spec has this to say about cssFloat:

The cssFloat attribute, on getting, must return the result of invoking getPropertyValue() with float as argument. On setting, the attribute must invoke setProperty() with float as first argument, as second argument the given value, and no third argument. Any exceptions thrown must be re-thrown.

However, older browsers don’t follow this specification (or convention before the spec existed) very well. See Where do the JavaScript style property names come from?: old Internet Explorer versions use styleFloat instead of cssFloat.


CSS didn’t always have a specification; many parts were underspecified or simply unspecified and relied on conventions among browser vendors. It’s not easy to accurately find out the implementation reality of this feature, but after some “Internet history” digging, I found:

According to the compatibility table for CSSStyleDeclaration, Internet Explorer ≤8 didn’t support it (properly), but all other browsers did since the beginning.

The current CSSOM specification remained unchanged in this part since the beginning (September 2015).

A previous version of the specification had a complete table to translate properties from one form to the other, but the property normalization remained the same (July 2011).

A specification which goes back to August 2001 has one relevant passage about getting and setting properties and a table of all camel-cased CSS properties implemented on the same interface. The passage is about CSS2Properties and says:

The CSS2Properties interface represents a convenience mechanism for retrieving and setting properties within a CSSStyleDeclaration. The attributes of this interface correspond to all the properties specified in CSS2. Getting an attribute of this interface is equivalent to calling the getPropertyValue method of the CSSStyleDeclaration interface. Setting an attribute of this interface is equivalent to calling the setProperty method of the CSSStyleDeclaration interface.

getPropertyValue and setProperty do accept the hyphenated CSS properties in this version, and, as the quote says, “the attributes of this interface correspond to all the properties specified in CSS2”. However, it seems that the exact correspondence is implied; i.e. the fact that fontSize maps to font-size, or that they’re supposed to yield the same result, may be underspecified. It also seems to imply that "fontSize" is an acceptable argument to getPropertyValue, which it isn’t.

Furthermore, the specification only was a proposed recommendation shortly before that (i.e. before 13 November, 2000), and in terms of conformance to the DOM Level 2 CSS spec, this CSS2Properties interface was optional:

The interface found within this section are [sic!] not mandatory.

It doesn’t sound as if it’s very likely that browsers from the early 2000s support this equivalence between hyphenated and camel-cased CSS properties.

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
1

Works in

  • Chrome 92 Mac
  • Safari 14.1.2 Mac
  • Firefox 89 and 91 Mac

const element1 = document.getElementById("e1");
const element2 = document.getElementById("e2");
const element3 = document.getElementById("e3");


element1.style.fontSize = "14pt";
element2.style["fontSize"] = "14pt";
element3.style["font-size"] = "14pt";
p { font-size: 9pt;}
<p>Text</p>
<p id="e1">Text</p>
<p id="e2">Text</p>
<p id="e3">Text</p>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • Thanks. I'm hoping to find something definitive, like something in the spec which directly addresses this, or something in the definition of the element.style property which would make it absolutely clear. – KevinHJ Aug 16 '21 at 12:51