views:

3804

answers:

7

I'm looking for a way to change the CSS rules for pseudo-class selectors (such as :link, :hover, etc.) from JavaScript.

So an analogue of the CSS code: a:hover { color: red } in JS.

I couldn't find the answer anywhere else; if anyone knows that this is something browsers do not support, that would be a helpful result as well.

A: 

While I cannot speak for all browsers, a bit of digging found the MSDN reference for CSS attributes that indicates that the pseudo-classes are not scriptable in IE.

ADDED: Mozilla's documentation also lacks any indication of support for setting pseudo-classes/element styles from a script.

DocMax
Two downvotes in a week on an almost 2 yr old response? Is it because the info has changed or because there are alternate ways of accomplishing the same thing? In either case, since my data was right in Nov. 08 is a downvote really warranted?
DocMax
@DocMax: I didn't downvote you (I might have, if you weren't already on -2), but DOM Level 2 allows you to manipulate stylesheets and their rules - and it's been a recommendation since the year 2000. Sure, Microsoft haven't implemented it yet but they have their own proprietary method - see bobince's answer. I assume you got the downvotes because your answer is incorrect. Since you can manipulate a stylesheet from JS, you certainly can add, change and remove rules that contain pseudo classes.
Andy E
A: 

JQuery selectors do not support this. I think they would if that is possible.

Sergey
+10  A: 

You can't style a pseudo-class on a particular element alone, in the same way that you can't have a pseudo-class in an inline style="..." attribute (as there is no selector).

You can do it by altering the stylesheet, for example by adding the rule:

#elid:hover { background: red; }

assuming each element you want to affect has a unique ID to allow it to be selected.

In theory the document you want is http://www.w3.org/TR/DOM-Level-2-Style/Overview.html which means you can (given a pre-existing embedded or linked stylesheet) using syntax like:

document.styleSheets[0].insertRule('#elid:hover { background-color: red; }', 0);
document.styleSheets[0].cssRules[0].style.backgroundColor= 'red';

IE, of course, requires its own syntax:

document.styleSheets[0].addRule('#elid:hover', 'background-color: red', 0);
document.styleSheets[0].rules[0].style.backgroundColor= 'red';

Older and minor browsers are likely not to support either syntax. Dynamic stylesheet-fiddling is rarely done because it's quite annoying to get right, rarely needed, and historically troublesome.

bobince
+1 very useful stuff
Anurag
A: 

As already stated this is not something that browsers support.

If you aren't coming up with the styles dynamically (i.e. pulling them out of a database or something) you should be able to work around this by adding a class to the body of the page.

The css would look something like:

a:hover { background: red; }
.theme1 a:hover { background: blue; }

And the javascript to change this would be something like:

// Look up some good add/remove className code if you want to do this
// This is really simplified

document.body.className += " theme1";
Nathaniel Reinhart
+2  A: 

A function to cope with the cross-browser stuff:

addCssRule = function(/* string */ selector, /* string */ rule) {
  if (document.styleSheets) {
    if (!document.styleSheets.length) {
      var head = document.getElementsByTagName('head')[0];
      head.appendChild(bc.createEl('style'));
    }

    var i = document.styleSheets.length-1;
    var ss = document.styleSheets[i];

    var l=0;
    if (ss.cssRules) {
      l = ss.cssRules.length;
    } else if (ss.rules) {
      // IE
      l = ss.rules.length;
    }

    if (ss.insertRule) {
      ss.insertRule(selector + ' {' + rule + '}', l);
    } else if (ss.addRule) {
      // IE
      ss.addRule(selector, rule, l);
    }
  }
};
cheers, just what i needed!
Anurag
A: 

You can use Javascript to switch one stylesheet off and to switch another on. A method is described at A List Apart.

TRiG
A: 

Switching stylesheets in and out is the way to do it. Here is a library to build stylesheets dynamically, so you can set styles on the fly:

http://www.4pmp.com/2009/11/dynamic-css-pseudo-class-styles-with-jquery/

SlappyTheFish