9

I want to get an element in the DOM and then lookup what rules in my CSS file(s) are contributing to it's appearance. Similar to what firebug or webkits inspector does. Is there a way to do this in JavaScript?

Update:

I should provide a constraint and a specific example - I am only interested in achieving this in webkit based browsers so cross-browser difficulties are not so much an issue. What I am specifically trying to achieve is this. Let's say I have a stylesheet as follows:

     div {
        background: #f0f0f0;
     }

     .example {
        padding: 10px;
     }

And then let's say some html code like this:

  <div id="test" class="example">
     <hgroup>
        <h1>Test</h1>
        <h2>A sample file to play with.</h2>
     </hgroup>
     <ul class="sample">
        <li id="item_1">Item 1</li>
        <li id="item_2">Item 2</li>
     </ul>
  </div>

So then in javascript I want to be able to have a function that can find the selectors from the CSS that are styling the object:

get_selectors_for(document.getElementById('test'))
// should return:
// ['div','.example']

How complicated is it to reverse query selectors knowing we only need to worry about webkit as opposed to all browsers?

Jim Jeffers
  • 17,572
  • 4
  • 41
  • 49
  • I should mention I'm only interested in doing this in webkit. Not so much cross browser. – Jim Jeffers Dec 19 '10 at 12:19
  • possible duplicate of [Find all CSS rules that apply to an element](http://stackoverflow.com/questions/2952667/find-all-css-rules-that-apply-to-an-element) – Bergi Sep 24 '13 at 13:31

5 Answers5

13

This is what you want. WebKit only. I found out about getMatchedCSSRules by looking at the chromium web inspector source.

  function getAppliedSelectors(node) {
    var selectors = [];
    var rules = node.ownerDocument.defaultView.getMatchedCSSRules(node, '');

    var i = rules.length;
    while (i--) {
      selectors.push(rules[i].selectorText);
    }
    return selectors;
  }
Hemlock
  • 6,130
  • 1
  • 27
  • 37
5

A cross-browser solution I've had good success with is http://www.brothercake.com/site/resources/scripts/cssutilities/

It is very powerful and accurate, derives a lot more information than the webkit-only function mentioned above, and it works on all styles (including those that are cross-site and that aren't active or have been overridden).

GunnerGuyven
  • 541
  • 6
  • 8
2

Is it possible? Absolutely...is it simple (especially cross-browser with IE in the mix), not so much. If you're really interested in doing this, check out the Firebug Lite CSS source here. At least the methods are decently commented showing what information each is fetching.

....or if you're wanting simply to inspect in a browser that doesn't have an inspector, just use Firebug Lite.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • Thanks Nick, I'm really only interested in doing this in webkit. I should have been more specific but am now glad I left it a bit broad! – Jim Jeffers Dec 19 '10 at 12:20
1

There is a reliable way of getting it, mentioned in this blog post:

function getStyle(oElm, strCssRule){
    var strValue = "";
    if(document.defaultView && document.defaultView.getComputedStyle){
        strValue = document.defaultView
            .getComputedStyle(oElm, "").getPropertyValue(strCssRule);
    }
    else if(oElm.currentStyle){
        strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
            return p1.toUpperCase();
        });
        strValue = oElm.currentStyle[strCssRule];
    }
    return strValue;
}

If you are using Firefox and Firebug, you can try running this code in StackOverflow, to see what you get:

document.defaultView.getComputedStyle(document.getElementById("custom-header"),"")

And with IE and Firebug Lite, you could do:

document.getElementById("custom-header").currentStyle
Ege Özcan
  • 13,971
  • 2
  • 30
  • 51
  • 2
    Thanks but I think this looks up a computed style from the CSS. So this code would help me find out the font-size is 10px;. I don't think it necessarily is meant to find the specific selectors in the CSS is it? – Jim Jeffers Dec 19 '10 at 12:32
  • This code would help you find the css rules applied to an element. It doesn't matter where they are originated but the fact that they are applied. – Ege Özcan Dec 19 '10 at 14:36
  • 1
    This is what i was looking for. `getComputedSyle` do what `getMatchedCSSRules` cannot do, because when there are crosdomain stylesheets `getMatchedCSSRules` returns null – jscripter Mar 22 '14 at 08:41
  • I think this is the solution for this question: https://stackoverflow.com/questions/27957680 – Kokizzu Jan 15 '15 at 07:32
1

Well, it's an old subject. Good for Webkit for offering a solution. As suggested, I've looked into firebug-lite and... surprise!! For every node it loops over every rule in every stylesheet checking if the selector matches our nodes or not.

vitko
  • 11
  • 1