Inject New CSS Rules
If you need to change the style of an element with JavaScript, it's typically better to change a class name and have the CSS already on the page take effect and change the style. However, there are exceptions to every rule. For instance, you might want to programmatically change the a pseudo class (e.g. :hover). You can't do that through JavaScript for the same reason inline style="" attributes can't change pseudo classes.
You'll need to inject a new <style> element onto the page with the correct styles in it. Best to inject it at the bottom of the page so it overrides your CSS above it. Easy with jQuery:
function injectStyles(rule) {
var div = $("<div />", {
html: '­<style>' + rule + '</style>'
}).appendTo("body");
}
Usage
injectStyles('a:hover { color: red; }');
Demo
More Information
- Style injection quirks in IE (Ryan Seddon).
- Stack Overflow thread.
Good post, but wouldn’t it be preferable to simply add a class that solely changes the hover state? For instance add a class of .hoverChange, and in the CSS just add a rule like .hoverChange:hover{ color: red; }?
Possibly. But you just can’t know every possible situation. Like I mentioned above, what if you need to programmatically calculate what the style will be?
Isn’t a style element supposed to go in head, since it’s metadata content and all. That is, unless the scope attribute is present… See style element
Yeah it is, but there’s never been a browser where it didn’t work no matter where you put it. I think think it’s like 0.0001% safer to use body instead of head. Come to think of it, I think the safest possible way is to target the first script tag it can find (there must be one somewhere, since this is JavaScript running) and insert the style element after it.
The
<div>and­(as opposed to just<style>) are an awkward but necessary evil. However beware ofhtml:instead oftext(). It means it isn’t escaped. This can be problematic if you use special characters in strings that are expected to be unescaped in CSS but the element will consider HTML if not escaped:Also, you might want to keep the dom cleaner by using this:
or:
This one is actually even a little more fun as you can create pretty much any CSS you could create in a stylesheet, using any of the selectors the browser supports, and they can be
document.styleSheets[0].insertRule(“body {background:red;}”, 0);
document.styleSheets[0].deleteRule(0)
The 0 is the position index. I actually have a class scribbled up for this stuff that does things like detect and map standards CSS to vendor prefixed , produces re-usable CSS for CSS3D stuff like carousels , cubes , pyramids (with textures),manipulates keyframe rules etc. It will even tell me all the classes that effect an element , elements or even elements matching a regular expression query. The only reason this other stuff is mentioned is simply to point out just how much can actually be done working at the rule level