Is there a way to change an attribute of a CSS class using javascript?
<style type="text/css">
.fool select {
display: block;
}
</style>
<p class="fool">
<select id="a" onchange="changeCSS()"> ... </select>
<select id="b" > ... </select>
<select id="c" > ... </select>
</p>
I want to change display:block to display:none for ALL <select>
elements after a user call function changeCSS().
It looks simple but I can't find a way to do this...
8 Answers 8
You can modify style rules, but it's usually not the best design decision.
To access the style rules defined by style sheets, you access the document.styleSheets
collection. Each entry in that collection will have a property either called cssRules
or rules
depending on the browser. Each of those will be a CSSRule
instance. You can change the rule by changing its cssText
property.
But again, that's probably not the best way to solve the problem. But it is the literal answer to your question.
The best way to solve the problem is probably to have another class in your stylesheet that overrides the settings of the previous rule, and then to add that class either to the select
elements or to the container of them. So for instance, you could have the rules:
.fool select {
display: block;
}
.fool.bar select {
display: none;
}
...and when you want to hide the selects, add the "bar"
class to the container that has the "fool"
class.
Alternately, apply CSS style information directly to elements.
3 Comments
The key is to define extra rules for additional classes and add these classes to the elements rather than to rewrite the rules for a given style rule.
JS
function changeCSS() {
var selects = document.getElementsByTagName("select");
for(var i =0, il = selects.length;i<il;i++){
selects[i].className += " hidden";
}
}
CSS
.fool select.hidden, select.hidden {
display: none;
}
Or for a really efficient method (but which might need a few more specific style rules too)
JS
function changeCSS() {
document.getElementsByTagName("body")[0].className += " hideAllSelects"
}
CSS
body.hideAllSelects select {
display: none;
}
2 Comments
.className += " hidden"
you can use .classList.Add("hidden")
. It is a little bit more performant and better maintainable.I'm accessing CSS classes directly to adjust the height of a bunch of divs simultaneously. This is how I'm doing it:
function cssrules() {
var rules = {};
for (var i=0; i<document.styleSheets.length; ++i) {
var cssRules = document.styleSheets[i].cssRules;
for (var j=0; j<cssRules.length; ++j)
rules[cssRules[j].selectorText] = cssRules[j];
}
return rules;
}
function css_getclass(name) {
var rules = cssrules();
if (!rules.hasOwnProperty(name))
throw 'TODO: deal_with_notfound_case';
return rules[name];
}
and then you can do something like css_getclass('.classname').style.background="blue"
. I only tried this on chrome for windows, good luck with other browsers.
4 Comments
css_getclass('td:first-child a img').style.width=this.value+"em";
dsi=ds[i].cssRules
to dsi=ds[i].cssRules||ds[i].rules
and be aware that the funcion will overwritte rules if the same selectorText exists in a previous styleSheet.kbd.myclass
.You can edit the style sheets, but I would think you would just create a new class instead. If you really need to do it, try this.
ss=document.styleSheets[0]
cssRules Are the style sheet rules
ss.cssRules
ss.cssRules[0]
Selector for the first rule
ss.cssRules[0].selectorText
".channel > li"
Read the style of the first rule
ss.cssRules[0].style
CSS2Properties { "margin-left" → "0px"}
Change the style
ss.cssRules[0].style.marginLeft="15px"
ss.cssRules[0].style
CSS2Properties { "margin-left" → "15px" }
Comments
Here's how I'd do it:
//Broken up into multiple lines for your convenience
setTimeout
(
function()
{
document.getElementById('style').innerHTML = 'p.myclass{display: none}';
}, 5000
);
<!--Should this be separated into "<head>"?-->
<style id="style"></style>
<p>After 5 seconds:</p>
<p>This text won't be hidden,</p>
<p class="myclass">But this will,</p>
<p class="myclass">And so will this.</p>
<script>
style = document.getElementById('style');
setTimeout(function(){style.innerHTML = 'p.myclass{display: none}'}, 5000);
</script>
1 Comment
To get the same effect, you can make another style:
<style type="text/css">
.fool select {
display: block;
}
.foolnone select {
display: none;
}
</style>
and change the class of <p>
to foolnone
.
Otherwise, you'd have to go through each of the children of <p>
and change the class. If that's the way you want to go, probably probably best to use some library, such as jquery. With it, you can do something like:
<style>
.fool select.displaynone {
display: none
}
$('.fool>select').toggleClass('displaynone')
See this jsfiddle for a working example:
This shows both above approaches (i.e. hiding the whole <p>
and hiding each of the <select>
s.
2 Comments
displaynone
class for this. However that fits into your project is something you can ponder on, but this should be what you can use basically, details aside.I think it would work if instead put like this:
var elements = document.getElementsByTagName('select');
for(var i = 0; i < elements.length; i++){
elements[i].style.display = 'none';
}
1 Comment
for(var elements = document.getElementsByTagName('select'), i = elements.length; i--)
elements[i].style.display = "none";
inline-block
, notblock
. You are much better off to toggle betweennone
and''
(empty string) so that the element adopts its default display property when not set tonone
.