Firstly, I know that CSS expressions are defunct and wrong in so many ways, and also to avoid using !important
where possible. This is for a special case stylesheet.
My question is... Is there any way for a CSS expression to set the !important
flag?
E.g. this doesn't work:
a { color:expression('red !important'); }
[Edit: thanks to MarmaladeToday's comment below]. This also doesn't work:
a { color:expression('red') !important; }
Can this be done some other way?
What I'm actually trying to do is mimic the inherit
value in IE6 & 7. This works:
color:expression(
this.parentNode.currentStyle ?
this.parentNode.currentStyle.color: 'red'
);
But I also want to set the !important
flag, and this doesn't work:
color:expression(
(
this.parentNode.currentStyle ?
this.parentNode.currentStyle.color: 'red'
) + ' !important');
I'm aware that, in JavaScript, it isn't possible to set !important
via an element's style
object. E.g. this won't work:
element.style.color = 'red !important';
However, it is possible to set !important
via the element's style
attribute:
element.setAttribute('style', 'color:red !important;');
So... are CSS expressions limited to interacting with the style
object, and therefore, what I want to achieve is impossible - or is there any way for an expression to affect an element's attributes, or pass !important
in some other way?
No solid answers so far, so I'm starting a bounty.
Ideally, I'm looking for a CSS-based solution for mimicking inherit !important
in IE6 and IE7, either with or without CSS expressions. (Please do verify that your suggestions work before posting).
At least, a link to some authoritative reference telling me that this is impossible would mean I could lay this train of thought to rest - I've not seen anything mentioning the use of CSS expressions with the !important
rule.
The reason those CSS expressions don't work is because IE only evaluates the expression for the last property in the cascade.
E.g. if you have an HTML document with a link inside it and the following "CSS",
a {
color: expression(function(e){
alert('success');
e.runtimeStyle.color = 'blue';
}(this));
}
a { color: red; }
you will never see that alert (nevermind the style change), because the CSS expression is never evaluated. So no, you can't use an expression to set the !important
flag.
That is to say, not when you try to set it on the same property. You can cheat. But that does make the expression a bit more complicated:
a {
filter: expression(function(e){
e.runtimeStyle.color = 'blue';
alert('success');
e.style.filter = '';
}(this));
}
a { color: red; }
There are a few things to note here.
If you simply use another CSS property, you can be sure that the expression will be evaluated. Or at least, a little more sure, because if there's another rule further down the cascade that uses the same property already, you're still out of luck.
Secondly, you have to use runtimeStyle
instead of currentStyle
. If you used currentStyle
here, the second rule would still end up overwriting it. runtimeStyle
overrides all other CSS (except !important
declarations). So it's the JScript equivalent of !important
.
Also note that I'm resetting the filter
property itself as well. That prevents the expression from being continuously re-evaluated. But as much as that may reduce performance, I don't think it's super critical. The main reason I put it in here is because I added alert()
s in those expressions, and you definitely don't want to have those pop up forever.
It is in fact also possible to use any other property you make up. This works too:
a {
bogus: expression(function(e){
e.runtimeStyle.color = 'blue';
}(this));
}
However, since the bogus
property doesn't actually exist, you can't reset it using Javascript, so this will be re-evaluated continuously.