Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't getComputedStyle work with pseudo classes like :hover?

The function window.getComputedStyle is supposed to be able to get the computed style of pseudo classes like :hover, according to the documentation.

It's also explained as an answer in another question

But as the last comment says in that question, in fact it doesn't work at all, it just returns the normal style, not the :hover style. You can see for yourself in this jsfiddle. The alert returns the red color, not the green one.

The documentation on developer.mozilla.org also has an example, but that doesn't work either - see here.

In this question the answerer states in a comment that it won't work at all, but without giving an explanation.

Could it be that the stylesheet has to be fully rendered before the function returns the correct value? I've tried setting some delays, but nothing seems to work.

I've tried the latest Firefox, Chrome and IE browsers. Does anybody know why this function is not working as expected?

like image 704
lasseschou Avatar asked Jul 15 '12 20:07

lasseschou


People also ask

Can you hover a pseudo element?

To clarify, you CAN NOT give :hover to a pseudo element. There's no such thing as ::after:hover in CSS as of 2018.

Is hover pseudo-class?

The :hover CSS pseudo-class matches when the user interacts with an element with a pointing device, but does not necessarily activate it. It is generally triggered when the user hovers over an element with the cursor (mouse pointer).

Can CSS classes combine with pseudo-classes?

If you're talking about pseudo-classes, then yes, you can combine them in any order.

How do I target a pseudo element in JavaScript?

You can't select pseudo elements in jQuery because they are not part of DOM. But you can add a specific class to the parent element and control its pseudo elements in CSS. Show activity on this post. We can also rely on custom properties (aka CSS variables) in order to manipulate pseudo-element.


2 Answers

var style = window.getComputedStyle(element[, pseudoElt]);

where pseudoElt is "a string specifying the pseudo-element to match". A pseudo-element is something like ::before or ::after, those are elements which are generated by CSS styles. :hover, :visited or other similar effects are pseuodo-classes. They won't create new elements but apply specialized class styles to the element.

It's not possible to get the computed style of a pseudo-class, at least not with getComputedStyle. You can however traverse through the CSS rules and try to find a fitting selector, but I won't recommend you to do this, since some browsers won't follow the DOM-Level-2-Style rules and you would have to check which rule will affect your specific element:

/* Style */
p a:hover{ color:yellow; background:black;}
p > a:hover{ color:green; background:white;}
p > a+a:hover{ color:fuchsia; background:blue;}
// JS
var i,j, sel = /a:hover/;
for(i = 0; i < document.styleSheets.length; ++i){
    for(j = 0; j < document.styleSheets[i].cssRules.length; ++j){    
        if(sel.test(document.styleSheets[i].cssRules[j].selectorText)){
            console.log(
                document.styleSheets[i].cssRules[j].selectorText,
                document.styleSheets[i].cssRules[j].style.cssText
            );
        }
    }
}
Result:
p a:hover color: yellow; background: none repeat scroll 0% 0% black; 
p > a:hover color: green; background: none repeat scroll 0% 0% white;
p > a + a:hover color: fuchsia; background: none repeat scroll 0% 0% blue;

See also:

  • MDN: getComputedStyle examples
  • W3C: CSS2: 5.10 Pseudo-elements and pseudo-classes
  • SO: Setting CSS pseudo-class rules from JavaScript
like image 182
Zeta Avatar answered Sep 28 '22 20:09

Zeta


Note that there is a way to do this at least for Chrome with the remote debugging port turned on. Basically you need to use a WebSocket, connect to the remote debugger url, then issue the following commands:

send  { id: 1, method: "Inspector.enable" }
send  { id: 2, method: "DOM.enable" }
send  { id: 3, method: "CSS.enable" }
send  { id: 4, method: "DOM.getDocument" }
send  { id: 5, method: "DOM.querySelector", params: { nodeId: 1, selector: <<whatever you want>> } }
nodeId = response.result.nodeId
send  { id: 6, method: "CSS.forcePseudoState", params: { nodeId:, forcedPseudoClasses: [ "hover" <<or whatever>> ] } }

Then you can use the regular getComputedStyle, or the CSS.getComputedStyleForNode debugger API.

like image 35
Dylan Nicholson Avatar answered Sep 28 '22 20:09

Dylan Nicholson