Can I access the value of invalid/custom CSS properties from JavaScript?
Asked Answered
C

3

17

Assume I have the following CSS:

div {
    -my-foo: 42;
}

Can I later in JavaScript somehow know what the value of the -my-foo CSS property is for a given div?

Cletacleti answered 28/5, 2010 at 2:34 Comment(0)
S
13

I don't think you can access invalid property names, at least it doesn't work in Chrome or Firefox for me. The CSSStyleDeclaration simply skips the invalid property. For the given CSS:

div {
    width: 100px;
    -my-foo: 25px;
}

style:CSSStyleDeclaration object contains only the following keys:

0: width
cssText: "width: 100px"
length: 1

However, interestingly this is what the DOM-Level-2 Style spec says:

While an implementation may not recognize all CSS properties within a CSS declaration block, it is expected to provide access to all specified properties in the style sheet through the CSSStyleDeclaration interface.

implying that the CSSStyleDeclaration object ought to have listed the -my-foo property in the above example. Maybe there is some browser out there which supports it.

The code I used for testing is at http://jsfiddle.net/q2nRJ/1/.

Note: You can always DIY by parsing the raw text. For example:

document.getElementsByTagName("style")[0].innerText

but that seems like a lot of work to me, and not knowing your reasons for doing this, I can't say if a better alternate for your problem exists.

Sawyere answered 28/5, 2010 at 3:9 Comment(4)
very interesting, especially the part about the DOM spec saying that custom properties should be exposed in CSSStyleDeclaration. I found that Mozilla has a bug for this, and I would encourage you and others here who are interested in this to voice their opinion and vote for this bug. I also added a comment to the bug, better explaining the scenario in which I would like to use this. bugzilla.mozilla.org/show_bug.cgi?id=116694Cletacleti
I've added a comment to that same bug showing a concrete example how a custom CSS attribute could be used.Marsh
Wow that bug was filed in 2001. Still not resolved. I am sick of being a web developer.Coralline
Correct, browsers are supposed to preserve unknown styles and unknown rulesets in the CSSStyleDeclaration, but they don't. This has been an issue since....well since forever. There are some things browsers refused to do in terms of implementation, and once time passed, they figured they never needed to revisit it. As a result, no browser meets 100% compliance with even the earliest specs.Tait
C
3

CSS Custom Properties

DOM Level 2 style

As pointed out by Anurag, this was something proposed in DOM Level 2 and later deprecated. Internet Explorer was the only browser that implemented it and they stopped supporting it in Edge. IE expects that the property doesn't start with a dash so my-foo: 42; should work.

CSS variables style

Newer browsers support CSS variables. These start with a double dash: --my-foo: 42; (they can be reused elsewhere like this font-size: var(--my-foo);)

Example

CSS

div {
  --my-foo: 42;
  my-foo: 42;
}

JS

// Chrome 49, Firefox 31, Safari 9.1 (future Edge):
const cssVariable = bodyStyles.getPropertyValue('--my-foo')
// IE:
const cssCustomProperty = bodyStyles['my-foo']

Browser Support

Currently Microsoft Edge is the only browser with no support for either of these methods, but as of writing CSS variables in Edge are "under active development".

Contravallation answered 19/9, 2016 at 13:7 Comment(0)
L
0

In Mac 10.12.6(or other version, maybe), if you want to store some property in style like:

<span style="--my-foo: [{"a": "b"}]">text</span>

then you use span.style.getPropertyValue('--my-foo') to get, you will get the value like:

[{'a': 'b'}]

It's means that if you want to store some string/object in style(for some special purpose like .dtd limit etc.) by JSON.stringify the value, and want to parse back by JSON.parse, you will get stuck by parser err, the err message said 'single quote' not allow in JSON'.

try below in Mac 10.12.6 Safari:

var span = document.createElement('span');
span.id = 'some_id';
var data =  JSON.stringify([{d: 'e'}]);
span.style = `--b-c: ${data}`;
document.body.appendChild(span);
var f = document.getElementById('some_id').style.getPropertyValue('--b-c');
console.log('f:', f);
Leo answered 8/6, 2020 at 5:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.