4

I made a function that overwrite the the :hover of some elements on a page. It fades between the normal and the :hover effect. That for i had to create a .hover class in my CSS file. I think this is a little unclean. How could i read the the :hover pseudo class contents?

Michael M.
  • 10,486
  • 9
  • 18
  • 34
meo
  • 30,872
  • 17
  • 87
  • 123
  • you might want to revisit this question. The owner of the accepted answer has edited it to point out that it is wrong. – Quentin Oct 31 '22 at 11:14

5 Answers5

11

Using getComputedStyle as on the accepted answer won't work, because:

  1. The computed style for the hover state is only available when the element is actually on that state.
  2. The second parameter to getComputedStyle should be empty or a pseudo-element. It doesn't work with :hover because it's a pseudo-class.

Here is an alternative solution:

function getCssPropertyForRule(rule, prop) {
    var sheets = document.styleSheets;
    var slen = sheets.length;
    for(var i=0; i<slen; i++) {
        var rules = document.styleSheets[i].cssRules;
        var rlen = rules.length;
        for(var j=0; j<rlen; j++) {
            if(rules[j].selectorText == rule) {
                return rules[j].style[prop];
            }
        }
    }
}

// Get the "color" value defined on a "div:hover" rule,
// and output it to the console
console.log(getCssPropertyForRule('div:hover', 'color'));

Demo

bfavaretto
  • 71,580
  • 16
  • 111
  • 150
  • Suspiciously identical, but [this answer](http://stackoverflow.com/a/16966533/2231440)'s method allows for selectors that aren't the entire rule selector. – Trojan Jul 22 '14 at 16:08
  • 3
    This will not work on stylesheets on other domains due to domain restrictions. so it's partial solution – MindFold Jan 03 '15 at 15:04
4

You could access document.styleSheets and look for a rule that is applied on that specific element. But that’s not any cleaner than using a simple additional class.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • 1
    stylesheets loaded from external files are not available in document.styleSheets. – Jacob Rask Feb 11 '13 at 12:01
  • @JacobRask — That's not true. **External** files are accessible. **Cross-origin** files are not by default but can be accessed via `` **+** a suitable `access-control-allow-origin` header on the response from example.com. – Quentin Oct 31 '22 at 11:29
1

UPDATE: I somehow got this wrong. The below example doesn't work. See @bfavaretto's comment for an explanation.

In Firefox, Opera and Chrome or any other browser that correctly implements window.getComputedStyle is very simple. You just have to pass "hover" as the second argument:

<!DOCTYPE html>

<html>
<head>
<meta charset="UTF-8">
<style type="text/css">
div {
  display: block;
  width: 200px;
  height: 200px;
  background: red;
}
div:hover {
  background: green;
}
</style>
</head>
<body>

<div></div>

<script type="text/javascript">
window.onload = function () {
    var div = document.getElementsByTagName("div")[0];
    var style = window.getComputedStyle(div, "hover");
    alert(style.backgroundColor);
};
</script>
</body>
</html>

But I don't believe there's yet a solution for Internet Explorer, except for using document.styleSheets as Gumbo suggested. But there will be differences. So, having a .hover class is the best solution so far. Not unclean at all.

Community
  • 1
  • 1
Ionuț G. Stan
  • 176,118
  • 18
  • 189
  • 202
  • thx! Maybe its not unclean but the person that uses my function has to know that he has to do .hover class. It would be nice to avoid this. – meo Aug 16 '09 at 20:17
  • @david, out of curiosity, how are you going to handle the IE issue? – Ionuț G. Stan Aug 16 '09 at 20:19
  • @Ionut: this is a great example of some browser inconsistency which isn't worth your time fixing. If someone is using an inferior browser, they'll still get a working website, it just won't have the nice little touches. – nickf Aug 17 '09 at 06:40
  • @nickf, I totally agree with that, but there are cases when the client desperately wants the same look in the browser she's using (IE6). I'm experiencing such issues. Otherwise progressive enhancement is the way to go. – Ionuț G. Stan Aug 17 '09 at 06:44
  • i always do progressive enhancement. But we still have something like 30% IE6 hits on our servers, so i cant just ignore it :/ but i would love to – meo Aug 17 '09 at 12:24
  • @Ionut: I don't know yet how i gonna handle this. Maybe there just gonna be this ".hover" class to add to the CSS if the user want to use the function in IE browser. In the other case its juste gonna do nothing and let IE use the standart css :hover function. – meo Aug 17 '09 at 12:37
  • This doesn't seem work for me in either Firefox 3.6, Chrome 4 or Opera 9.5. The alert just shows the value of the non-hovered background colour. In Firefox and Chrome it alerts `rgb(255, 0, 0)`. In Opera it alerts `#ff0000`. – Phil Ross Mar 31 '10 at 20:41
  • 6
    This won't work, because `getComputedStyle` expects a pseudo-element as the second parameter, and `hover` is a pseudo class. If you remove that, it will work, but will only give you the hover value if it runs while the element is actually on `hover` state. [demo](http://jsfiddle.net/A82Ax/). – bfavaretto Sep 27 '12 at 19:40
  • @bfavaretto hmm, you're right. I wonder why I put this here back then. Maybe I misinterpreted the value I saw in the alert box, and thought it worked. I'll delete the answer. Thanks for pointing out the mistake. – Ionuț G. Stan Sep 27 '12 at 20:34
  • I added an alternative solution as an answer. This question caught my attention after [another question](http://stackoverflow.com/q/12626480/825789) was closed as a duplicate of this one. – bfavaretto Sep 27 '12 at 20:49
0

If there are any people here who use the questions accepted answer but it won't work, here's a nice function that might:

function getPseudoStyle(id, style) {
    var all = document.getElementsByTagName("*");
    for (var i=0, max=all.length; i < max; i++) {
        var targetrule = "";
        if (all[i].id === id) {
            if(all[i].selectorText.toLowerCase()== id + ":" + style) { //example. find "a:hover" rule
                targetrule=myrules[i]
            }
        }
        return targetrule;
    }
}
Zach Saucier
  • 24,871
  • 12
  • 85
  • 147
C-TZ
  • 659
  • 1
  • 5
  • 15
  • This is a **very** specific approach that will only work if (a) the CSS selector that applies the rule uses a single ID selector + single psuedo-class (b) it isn't overridden by the cascade and (c) you define `myrules` (which, as it stands, will cause the code to throw a reference error) and (d) the element you are looking for is the **last** element in the document which meets condition A. – Quentin Oct 31 '22 at 11:20
-1

There is an alterantive way to get :hover pseudo class with javascript. You can write your styles of hover pseudo class in a content property.

p::before,
p::after{
  content: 'background-color: blue; color:blue; font-size: 14px;';
}

then read from it via getComputedStyle() method:

console.log(getComputedStyle(document.querySelector('p'),':before').getPropertyValue('content'));
johannesMatevosyan
  • 1,974
  • 2
  • 30
  • 40
  • The is an incredibly fragile approach that depends on the developer keeping the `content` value and `:hover` rules in sync *while accounting for the cascade*. – Quentin Oct 31 '22 at 11:16