I am trying to make a jQuery plug-in that injects CSS rules onto the page. I am using addRule and insertRule. For some reason, addRule strips out !important from any rules you pass to it. Is there a way I can prevent it from doing so or a flag I can send to the function to mark the rule as important? I looked at the documentation for addRule but there was no mention of !important declarations.
document.getElementsByTagName('head')[0].appendChild(document.createElement('style'));
var sheet = document.styleSheets[document.styleSheets.length-1];
sheet.addRule('body','color: green !important');
h1 {
color: yellow;
}
<h1>Test text</h1>
By the way, I am only using addRule for compatability with older versions of Internet Explorer. I am aware that insertRule is a more robust function.
I don't believe !important bubbles like you're expecting. !important lets rules take precedence over other rules with the same selector. Consider this example:
<style>
#me { color:blue !important; }
</style>
<p id='me'>Hello, World</p>
<script>
sheet.addRule('#me','color: green !important;');
</script>
You'll notice that #me should be blue by the stylesheet, but it's being overriden by the addRule.
In your example, you're saying you want body color to percolate down to paragraphs, but !important is about choosing between rules with the same selector, not hierarchy. CSS Tricks has some words on this.
Related
<!doctype html>
<html>
<head>
<style>
#sample{
width:100px;
height:100px;
background-color:red;
}
.green {
background-color:green;
}
</style>
</head>
<body>
<div id="sample" ></div>
</body>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
window.setTimeout(function(){
$('#sample').addClass("green");
}, 2000);
</script>
<html>
I want to change the background color of the div with id="sample" from red to green in 2 seconds.I added the javasript to add a class with a green background to the div after 2 seconds.But the added class fails to replace the background color of the div element.So is there any solution which can be applied here to change the background color in two seconds.Also i know it is possible,if we add an another class to toggle between the background colors.An another solution will be appreciated.
It's fails because the weight of ID more than the weight of CLASS:
id = 100
class, pseudo-class = 10
element, pseudo-element = 1
You can use id with class:
<body>
<div id="sample" class="red"></div>
</body>
And then toggle from red to green. No need to use !important.
Moreover, if you want to change it with animation, you can use jQuery animate backgroundColor
<!doctype html>
<html>
<head>
<style>
#sample{
width:100px;
height:100px;
/*Remove this from here*/
/*background-color:red;*/
}
.green{
background-color:green;
}
.red{
/*Create a class for red alone*/
background-color:red;
}
</style>
</head>
<body>
<div id="sample" class="red" ></div>
</body>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
window.setTimeout(function(){
// Calling removeClass with no parameters will remove all of the items's classes.
$('#sample').removeClass();
// Now add the class of green
$('#sample').addClass("green");
}, 2000);
</script>
<html>
Cause
The problem is that an id-style is more important (has more 'weight') than a class style, so #sample has higher precedence than .green and the div remains red. There are many rules that dictate which CSS rules have precedence over others. Make sure to read about CSS rule Precedence, so whichever solution you choose, you know why you chose it and what are the consequences.
Fix
There are many ways to fix this, but they all boil down to making sure that the green rule overrules (is equally or more important than) the default red rule.
Solution (Best): Style on classes, not on IDs.
Add a class to the div that indicates what kind of box it is:
<div id="sample" class="samplecontainer"></div>
Now, in the CSS you can easily apply a default style to such elements, and overrule them too:
.samplecontainer {
background-color: red;
}
.samplecontainer.valid,
/* Or just */
.valid
{
background-color: green;
}
Now the CSS doesn't rely on specific elements, but on element definitions. You can say that containers are by default red, and are made green when they become 'valid' (whatever that may mean in this example). This way, you don't rely on ids in the CSS, which prevents very bulky CSS and the undesirable overrule you bumped into.
Note I renamed 'green' to 'valid' to make it more semantic. What if you want to change the border too, or make them blue instead of green? Then you would still need to dig into the JavaScript code, and also change the class names in CSS and possibly fixed style names in HTML and PHP. Or you can just leave the class name 'green' for the blue element, which is very confusing too. So a name describing the type or state (like valid, active, or whatever suits you best) is easier to read and to maintain.
Solution (Sub-optimal): Add Id to the green rule too
Try do change the css like this, so indicate that an element that has id 'sample' and class 'valid' should be green. I think this is quick fix and less optimal compared to the previous one, and your CSS may become bulky if you have many elements that can become green.
#sample.valid{
background-color: green;
}
Solution (Poor): Adding inline style though JavaScript
Instead of adding a class through JavaScript, you can also add inline style. Inline styles (the style attribute), has higher precedence, so adding style="background-color: green" will overrule the color defined in CSS.
$('#sample').css('background-color', 'green');
I wouldn't much prefer this method, since you would have to dig in your JavaScript to change the styling, end it will get really clunkcy when you want to change other properties as well. Each of the solutions above are preferable over this one.
Solution (Poor and risky): Add !important
From CSSTricks: When Using !important is The Right Choice
The unfortunate typical use case goes like this:
WHY IS MY FRAGGLE ROCKING CSS NOT WORKING INTERROBANG
(use !important rule)
OK, now it's working
Then the next guy comes along and tries to
make new changes. He tries to alter some existing CSS rules, but now
his changes aren't behaving how they should....
There are some cases when !important might be the right choice, but it should never be the quick fix for a problem like this, because in the end you'll and up with a CSS that is very hard to maintain, and various !importants will bite each other. Only use it when you have really thought it through.
Change CSS to
.green{
background-color:green !important;
}
DEMO
Please try this one and remove #simple style css
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
window.setTimeout(function(){
$('#sample').css({'background-color':'green'});
}, 2000);
</script>
in the JavaScript you can use just like that
you may find demo
var a;
function function_name() {
a = 1;
setInterval(new_function, 1000);
}
function new_function() {
if (a === 1) {
color = "requred_color";
a = 2;
} else {
color = "another_color";
a = 1;
}
document.body.style.background = color;
}
.green{
background-color:green !important;
}
change your green class like following
.green{
background-color:green !important;
}
Or try
$('#sample').css({background-color:"green"});
I have a reference to a server side JS file that dynamically creates divs on my page. I am trying to override the css that is inline for the divs that are created but I have not been able to do so.
I have tried !important and the style that is created by the JS still trumps everything I do.
When i look at the style in the developer console of chrome it shows element.style as being the style that "won" over my style
I do not have access to edit the JS file on the server.
I place this in my page and it dynamically creates the divs and styles them.
<head>
<style>
#id
{
background-color: blue; !important;
display:block; !important;
}
.class
{
background-color: blue; !important;
}
</style>
</head>
<script src="http://xxx/xxx/xxxxx/xxxx.ashx?blank=xxxx" type="text/javascript" charset="utf-8"></script>
You can create your own javascript to restyle the divs created by the server javascript.
The CSS !important tag does sound like your answer here but sometimes you need to ensure your CSS declaration is specific enough to the element, i.e.:
<div>
<a style="color:#F00;">A Link</a>
</div>
If I apply the below CSS the inline style or #F00 will still win:
div {color:#fff !important;}
But if I am specific with my CSS declaration i.e:
div a {color:#000 !important;} <--Notice the 'a' tag
Then my link will be #000. This does not matter if the link was loaded in with JavaScript or not.
See my JSFiddle Example: http://jsfiddle.net/zqpy0r6c/
More technical info can be found at
When does CSS's !important declaration not work?
The CSS given in the style attribute on an element always wins over the stylesheets. The best option to override this CSS is to edit the style attribute using some JS:
<script>
function clearInlineStyling(element){
element.style= null;
}
</script>
Next you have to watch the html for your script to add new elements, find them and remove their styling. I would suggest JQuery for this.
I'd like to apply a CSS to some linkbuttons on page load but one of them <a id="lb1">logoff</a> must keep its style, no hover nor other event must change its style.
The linkbuttons have no class and the css applied to all of them is done to tags, this way:
a
{
//style
}
a:hover
{
// style
}
Is it possible?
No, you can't.
You can use more specific selectors (or even inline CSS with the style attribute) so that they are less likely to be overridden accidentally.
You can use the (eugh) sledgehammer of !important so they will only be overridden by another !important rule.
There is no way to prevent them being overridden though.
Please please please please please avoid using !important whenever possible. You will run into SO many annoying problems and issues from using this. I consider it a very lazy hack.
What you want to do is append a class to the link that you don't want overwritten. Classes are given a higher priority than general selectors (such a, p, b). So if you append this class to the link, the CSS will override the default CSS you have set for a.
CSS:
a {
color: red;
}
a:hover {
color: blue;
}
.derp:hover { /*you can add everything you want to preserve here, essentially make it the same as the link css. you can also change it to #lbl:hover, although there's no good reason to be using an ID as a CSS selector*/
color: red;
}
HTML:
this will turn blue on hover
<a class="derp" href="#">this will stay red on hover</a>
Here's a fiddle to show you. The second link has a class appended that preserves the original style: http://jsfiddle.net/p6QWq/
Why not add a class to all the link buttons you want to change, and not add it to the one you don't want to change.
Then you can call:
$(".myClass").css("backgound-color", "blue");
This would change the background color for every element with a class of myClass to a blue background.
Or you could add a whole new class to the link buttons that have a class of myClass:
$(".myClass").addClass("myExtraClass");
This would then make the class attribute of your link button class="myclass myExtraClass"
Seeing your code posted makes it a little more clear on what you want to do. Try this:
a {
text-decoration: none;
color: orange;
}
a:hover {
text-decoration: underline;
color: blue;
}
This would apply a default style to all <a> elements. Now you could overwrite this default style by providing a specific style for the anchor with the id you gave above:
#lb1 {
color: black;
text-decoration: none;
}
#lb1:hover {
color: black;
text-decoration: none;
}
I mocked this up in a quick and dirty jsFiddle. See if this gives you the desired result. IDs take precedence over classes and default element styling. So if you have one that you want to keep the same, apply and ID and style the particular element accordingly. This would also help you by preventing you from having to apply a class to several elements. It's less coding to apply one ID than to apply twelve classes. (Just an exaggerated example. I don't know how many links you have.)
Hope this helps.
css is cascading by definition, so any style you apply to a tags will apply to this specific one, except if you overwrite it.
You'll have to either assign a class to all the other buttons or overwrite all the default properties for this specific button.
Also, do not forget the pseudo-classes :visited and :active.
You should use !important in your css like :
a {
/* style */
background: #FFF !important;
}
a:hover {
/* style */
background: #FFF !important;
}
You could always overwrite your css by simply creating another stylesheet and place it at the END of your stylesheet links in the head of your html.
<head>
<link rel="stylesheet" href="location/location/first_stylesheet.css">
<link rel="stylesheet" href="location/location/revised_stylesheet.css">
</head>
This is not the most productive method of overwriting your css however; one would be well advised to eliminate the necessity for this separate stylesheet by simply appending elements with a class attribute. The class attr will allow you to modify basic html elements, tags and overlay a final layer to "rule them all". Enjoy!
Lately I wondered about editing elements styles not by switching their classes on dom, but by changing the actual ruleset for the css class or selector.
So instead of something like
$('.some').hide()
or
$('.some').addClass('hidden')
Why not alter a rule directly with document.styleSheets and stuff?
Wouldn't this approach be generally more performant, at least with many elements, as we'd let the browser handle the ruleset changes natively?
You could for example add an style to .some, like display: none; and all .some elements would be immedeatly be hidden. There is no need to iterate over all those elements in js and hide them manually(like the example above).
Changing rulesets directly would more likely encourage classes that are context aware(or however you would call this..), as you'd hide all #persons > .item or something.
I still don't know best practices regarding classes that are named with context in mind, like for example control names like .calendar .ticket .item, versus single functionality classes like .hidden .left .green, as I usually need both types of conventions.
I am just asking what you think about this and what are benefits and drawbacks of the modifiying stylesheet approach versus how libraries like jquery handle changing styles?
Also, what do you think is good practice, what do you regard more as a hack?
cough javascript and hacking cough
Manipulating document.styleSheets is tricky due to differing implementations and the lack of a rule selector API. Currently if you want to manipulate a rule in a stylesheet you have to go through this process:
iterate over document.styleSheets
iterate over rules within current styleSheet object
if rule matches our class, edit the rule styles
Then there's the cascading issue. How do you know that a particular style on the rule you've matched won't be overridden by a different rule somewhere in the pages stylesheets? If you just bail out after changing the first matching rule you find, you can't be sure that the styles you set will actually be applied to the element, unless you stick an !important on each one, which will leave you with a whole different set of problems.
Even when you've manipulated the style sheet rules, the browser still has the same job to do — it has to recalculate all the styles by applying the cascade.
So, manipulating styleSheets doesn't look too appealing now, does it? Stick to class switching, trust me. Using jQuery and modern APIs like querySelectorAll make it plenty fast and the browser still does all the hard work like recomputing the style values.
Such a tricky question :(
But if you take boilerplate for instance, it has a some standard classes to use like:
/* Hide from both screenreaders and browsers: h5bp.com/u */
.hidden { display: none !important; visibility: hidden; }
/* Hide only visually, but have it available for screenreaders: h5bp.com/v */
.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: ; position: absolute; width: 1px; }
/* Hide visually and from screenreaders, but maintain layout */
.invisible { visibility: hidden; }
Where it gets tricky is, IF it is something you need to hide because of JS, then you should ONLY hide it with JS. Then it will function if JS is disabled.
If it is something that is not JS dependent, then you hide it in the HTML.
So JS function = hide with JS (either by using JS or adding hide classes)
Basic HTML hide = hide with HTML class
Styleswitching vs JS switching
Basicly JS switching gives you the oppertunity to add effect etc, just using predefined classes limits that somewhat. But would love to see some ressource comparisons :)
I have some JavaScript which is changing an image correctly but once it has been called, my a:hover CSS code no longer works.
Looking with firebug the following JavaScript creates this css rule:
element.style {
background-image:url(/content/images/side_partnershipsOver.png);
}
document.getElementById('partnerships').style.backgroundImage = "url(/content/images/side_partnershipsOver.png)";
How can I apply the JavaScript and not have the a:hover code overriden by the element.style rule?
As far as I know setting the element.style.backgroundImage is essentially the same as using an inline style.
<style type="text/css">
a { background: blue; }
a:hover { background:green; }
</style>
<a href="#" style="background:red;">link<a>
Unfortunately the inline style always wins. In the above sample the link will always be red. As Daniel White said jQuery would be very useful here. Although you may be able to get around this issue in two ways.
One, Generate the style using javascript to write a style tag
document.write("<style type='text/css'>#partnerships { background-image:url(/content/images/side_partnershipsOver.png);}</style>");
or two, Manually setup mouseenter/mouseleave events to handle your hover style
Update
or three, as pointed out by KevinUK, use the !important css tag to override the inline style set.
<style type="text/css">
a { background: blue; }
a:hover { background:green !important; }
</style>
<a href="#" style="background:red;">link<a>
I was also frustrated about this CSS js style gap so I build
methods to apply style from js with a CSS string
elm.jCSS(cssText);elm.jCSSPseudo(cssText,pseudoElt)