views:

757

answers:

12

In firefox, I have the following fragment in my .css file

tree (negative){  font-size: 120%; color: green;}

Using javascript, how do I change the rule, to set the color to red?

NOTE:
I do not want to change the element.
I want to change the rule. Please do not answer with something like

...

element.style.color = 'red';

A: 

As there is no HTML element tree I am going to assume that tree is the id or class of another element.

You would first retrieve the DOM element by id:

var tree = document.getElementById("tree");

Now tree represents your DOM element and you can manipulate it any way you like:

tree.style.color = "red";

Here is a great reference for mapping css properties to their javascript equivalent.

Andrew Hare
I don't want to change the element style, I want to change the CSS rule
Noah
I don't understand what you mean - do you want to edit the actual stylesheet? Changing the style is changing the rule in memory for that element.
Andrew Hare
You can't edit the CSS as far as I know. At least, I've never seen it done.
Oli
Yes, I want to dynamically change the actual style sheet rule, so that all elements using that rule will also change
Noah
Well the actual stylesheet lives on the server and the javascript executes on the client so without some heavy-duty server-side coding, what you want is not possible. Why will changing the rule in memory not work?
Andrew Hare
Changing the rule is memory is what I want to do. I don't want to iterate all elements, changing "green" to "red", since I am only going to change elements with specific properties. I want to change the rule so that when I navigate to the next page, I don't have to make all the changes again.
Noah
A: 

I'm not sure you can do actual class/selector overrides. You would need to target each element that used the .tree class and set the CSS. The quickest and easiest way would be through jQuery (or another similar framework):

$('.tree').each(function() { this.style.color = "red"; });

You could even use the built-in CSS functions:

$('.tree').css('color', 'red');

(I did it the first way to show you how standard JS would do it. The $(...) part is jQuery for selecting all elements with the .tree class. If you're not using jQuery, you'd need alternative code.)

If tree is an ID, not a class (there should only be one on the page) so using getElementById should be fine. Your code should look like the other answer.

Oli
A: 

for( var i in document.getElementsByTagName("tree") ){
   document.getElementsByTagName("tree")[i].style.color = "red";
}
ForYourOwnGood
This looks like a performance nightmare.
Andrew Hare
I don't want to iterate all elements, changing "green" to "red", since I am only going to change elements with specific properties. I want to change the rule so that when I navigate to the next page, I don't have to make all the changes again.
Noah
A: 

As I said in another answer's comment, I've never seen this done how you want. I've only ever targeted elements the same way as the CSS renderer would and changed each element style.

I did see this though: jQuery.Rule

It sounds like it does what you want but the demo causes my browser to flip out a bit. I'd invite you to look at the source to see it really does do what you want, and if you want to use it without jQ, use it as a starting point.

Edit: yes this should work. It works by appending another <style> tag to the page and writing out your overrides within. It's fairly simple to follow if you wanted to port it to plain JS.

Oli
A: 

For debugging, you can use Firebug to change the CSS rules on-the-fly.

Peter Boughton
+1  A: 

You can change CSS rules in style sheets through the CSS Object Model (currently known as DOM Level 2 Style). However, if you literally have "tree (negative)" in your style sheet that rule will be dropped and not appear in the Object Model at all.

Anne
A: 

If you want to change the rendered css rules from one page request to the next then some sort of server-side scripting will be required. Otherwise the original style sheet would simply reload at the next page request.

If you want to use an event on the first page to force the server-side action then you can use AJAX to actually change the CSS rule for the user.

Noah Goodrich
A: 

"I want to change the rule so that when I navigate to the next page, I don't have to make all the changes again."

It sounds like what you might want then is a remote request ("ajax") back to the server with the request you want to make, and generate a dynamic stylesheet which is sent back to the client?

How/why is this Firefox specific?

Peter Boughton
I specified FF, since I didn't want to read about an IE centric answer.
Noah
Then specify "cross-browser" or similar. There's a lot of different browsers out there; IE and FF are just two.
Peter Boughton
+2  A: 

What you're looking for is the document.styleSheets property, through which you can access your css rules and manipulate them. Most browsers have this property, however the interface is slightly different for IE.

For example, try pasting the following in FF for this page and pressing enter:

javascript:alert(document.styleSheets[0].cssRules[1].cssText)

For me that yields the string "body { line-height: 1; }". There are methods/properties that allow you to manipulate the rules.

Here's a library that abstracts this interface for you (cross-browser): http://sheetup.com/

Crescent Fresh
+1  A: 

Check the links given in the answers to this question.

Christoph
A: 

I want to change the rule so that when I navigate to the next page, I don't have to make all the changes again.

There are two approaches I can think of here. Namely client side and/or server side.

Client side: Store the theme setting into cookies and load them up next time by javascript.

Server side: If your site have an login system, you may also store the user preference into the database and generate the webpages with this inforamtion in mind next time on.

Utimately, you are still writing things like element.style.color = . But, they should get what you want.

billyswong
+2  A: 
function changeCSSRule (stylesheetID, selectorName, replacementRules) {
    var i, theStylesheet = document.getElementById(stylesheetID).sheet,
    thecss = (theStylesheet.cssRules) ? theStylesheet.cssRules : theStylesheet.rules;
    for(i=0; i < thecss.length; i++){
     if(thecss[i].selectorText == selectorName) {
      thecss[i].style.cssText = replacementRules;
     }
    }
};