Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the only way to change a style to do it per-element in JavaScript?

I've been looking at a few different things I'd like to using JavaScript to tweak styles globally. I'd like to do this by changing the CSS rule that dictates the element's style (akin to doing this through the Inspector in Webkit), but after coming to https://developer.mozilla.org/en/DOM/CSSStyleRule I now don't know if this is even possible:

style

Returns the CSSStyleDeclaration object for the rule. Read only.

So, is there no way to change higher-level styles in JavaScript?

like image 641
Stuart P. Bentley Avatar asked Feb 23 '23 05:02

Stuart P. Bentley


2 Answers

To modify your existing styles, either find the stylesheet in document.styleSheets or from the the .sheet property of the <style> or <link> element you want to modify. Then modify the properties in whatever rule they're located in (see https://developer.mozilla.org/en/DOM/CSSRuleList). I'd advice against using the CSSOM to modify properties, as browser support for modifying CSS properties through the CSSOM is pitiful (no browsers whatsoever support it). Instead, just set a string value.

If all you want to do is insert a new rule, just get a stylesheet from the method above, or document.documentElement.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml","style")).sheet. Then use insertRule to add your rule.

like image 154
Eli Grey Avatar answered Feb 25 '23 20:02

Eli Grey


CSS Styles can be created/changed programmatically via javascript, but that is not usually the easiest way to solve a problem because different browsers do it differently so cross-browser support is a bit of a pain unless you already have a library that abstracts that. You can see generally how to do it here: http://www.quirksmode.org/dom/changess.html.

If the styles you want to switch between are known in advance, then the easiest way to change between them is to define both those styles in a stylesheet, and use different class designations to trigger one vs. the other.

If you are just trying to affect one object or a small number of objects, you can simply add or remove a class name via javascript on the affected objects.

If there are large numbers of objects, then something I've done is to add a class name on the body tag to trigger the alternate style to take effect for all affected objects. It works like this:

Lots of these in your HTML:

<div class="foo"></div>
<div class="foo"></div>
<div class="foo"></div>
<div class="foo"></div>

Then, have two pre-defined CSS rules like this in this order:

.foo {background-color: #777;}
.alternate .foo {background-color: #F00;}

Then, using Javascript, any time you want to change to the alternate style, you simply do this (using jQuery or any favorite class library):

$(document.body).addClass("alternate");

To go back to the original style, you can just remove that class:

$(document.body).removeClass("alternate");

This doesn't have to be added to the body tag - it can be added to any common parent of all the affected objects.

I personally find this a lot simpler than programmatically creating style rules and it keeps the actual style information out of the code (where designer people who aren't programmers can more easily access it).

You can see this technique in action here: http://jsfiddle.net/jfriend00/UXKvg/

like image 44
jfriend00 Avatar answered Feb 25 '23 19:02

jfriend00