Can I fetch the value of a non-standard CSS property via Javascript?

I am trying to read a custom (non-standard) CSS property, set in a stylesheet (not the inline style attribute) and get its value. Take this CSS for example:

#someElement {
  foo: 'bar';
}

I have managed to get its value with the currentStyle property in IE7:

var element = document.getElementById('someElement');
var val = element.currentStyle.foo;

But currentStyle is MS-specific. So I tried getComputedStyle() in Firefox 3 and Safari 3:

var val = getComputedStyle(element,null).foo;

...and it returns undefined. Does anyone know a cross-browser way of retreiving a custom CSS property value?

(As you might have noticed, this isn't valid CSS. But it should work as long as the value follows the correct syntax. A better property name would be "-myNameSpace-foo" or something.)

Answers:

Answer

Firefox does not carry over tags, attributes or CSS styles it does not understand from the code to the DOM. That is by design. Javascript only has access to the DOM, not the code. So no, there is no way to access a property from javascript that the browser itself does not support.

Answer

Modern browsers will just throw away any invalid css. However, you can use the content property since it only has effect with :after, :before etc. You can store JSON inside it:

#someElement {
    content: '{"foo": "bar"}';
}

Then use code like this to retrieve it:

var CSSMetaData = function() {

    function trimQuotes( str ) {
         return str.replace( /^['"]/, "" ).replace( /["']$/, "" );   
    }

    function fixFirefoxEscape( str ) {
        return str.replace( /\\"/g, '"' );
    }

    var forEach = [].forEach,
        div = document.createElement("div"),
        matchesSelector = div.webkitMatchesSelector ||
                          div.mozMatchesSelector ||
                          div.msMatchesSelector ||
                          div.oMatchesSelector ||
                          div.matchesSelector,
        data = {};

    forEach.call( document.styleSheets, function( styleSheet ) {
        forEach.call( styleSheet.cssRules, function( rule ) {
            var content = rule.style.getPropertyValue( "content" ),
                obj;

            if( content ) {
                content = trimQuotes(content);
                try {
                   obj = JSON.parse( content );
                }
                catch(e) {
                    try {

                        obj = JSON.parse( fixFirefoxEscape( content ) );
                    }
                    catch(e2) {
                        return ;
                    }

                }
                data[rule.selectorText] = obj;
            }
        });

    });


    return {

        getDataByElement: function( elem ) {
            var storedData;
            for( var selector in data ) {
                if( matchesSelector.call( elem, selector ) ) {
                    storedData = data[selector];
                    if( storedData ) return storedData;

                }
            }

            return null;
        }
    };

}();
var obj = CSSMetaData.getDataByElement( document.getElementById("someElement"));
console.log( obj.foo ); //bar

Note, this is only for modern browsers. Demo: http://jsfiddle.net/xFjZp/3/

Answer

By reading in the Stylesheet info in IE, you CAN get these "bogus" properties, but only in IE that I'm aware of.

var firstSS = document.styleSheets[0];
var firstSSRule = firstSS.rules[0];
if(typeof(firstSSRule.style.bar) != 'undefined'){
  alert('value of [foo] is: ' + firstSSRule.style.bar);
} else {
  alert('does not have [foo] property');
}

Its ugly code, but you get the picture.

Answer

I too have some pages that work wonderfully in MSIE, but have lots of info in styles and style sheets. So I'm thinking about workarounds. One thing Firefox does allow, mercifully, is putting inline attributes into the DOM. So here's a partial strategy:

  1. Replace each inline style in the html document with a corresponding "nStyle", e.g., <span class="cls1" nStyle="color:red; nref:#myid; foo:bar"> ... </span>

  2. When the page is loaded, do the following with each element node: (a) copy the value of the nStyle attribute into the tag's cssText, and at the same time (b) convert the nonstandard attributes into an easier format, so that, e.g., node.getAttribute('nStyle') becomes the object {"nref":"#myid", "foo":"bar"}.

  3. Write a "calculatedStyle" function that gets either the style or the nStyle, depending on what's available.

Writing a rough parser for style sheets might enable a similar strategy for them, but I have a question: How do I get over the hurdle of reading the style sheet without censorship from Firefox?

Answer

One way would of course be to write your own CSS-parser in Javascript. But I believe that is really over the top.

Answer

Maybe you can try with LESS. It's The Dynamic Stylesheet language and you can create non-standard css attributes, commands that will compile later.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.