Thursday, August 30, 2012

The myth of the almighty inline style in HTML

To my shame, I've lived a long time with the impression that for an HTML element, a style attribute that is written inline always beats any of the CSS rules that apply to that element. That is a fallacy. Here is an example:
<style>
div {
   width:100px;
   height:100px;
   background-color:blue !important;
}
</style>
<div style="background-color:red;"></div>
What do you think the div's color will be? Based on my long standing illusion, the div should be red, as it has that color defined inline, in the style attribute. But that is wrong, the !important keyword forces the CSS rule over the inline styling. The square will actually be blue! And it is not some new implementation branch for non-Internet Explorer browsers, either. It works consistently on all browsers.

Now, you might think that this is some information you absorb, but doesn't really matter. Well, it does. Let me enhance that example and change the width of the div, using the same !important trick:
<style>
div {
   width:100px !important;
   height:100px;
   background-color:blue !important;
}
</style>
<div style="background-color:red;"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
$(function() {
//  $('div').width(200); // the width remains 100!
//  $('div').width('200px'); // the width remains 100!
//  $('div')[0].style.width='200px'; // the width remains 100!

//  $('div').width('200px !important'); //this is not a valid value for the width parameter! in IE it will even show an error
//  $('div').css('width','200px !important'); //this is not a valid value for the width parameter! in IE it will even show an error
//  $('div')[0].style.width='200px !important'; //this is not a valid value for the width parameter! in IE it will even show an error

var oldStyle=$('div').attr('style')||'';
$('div').attr('style',oldStyle+';width: 200px !important'); // this is the only thing I found to be working!

});
</script>
As you can notice, the might jQuery failed, setting the width property in style failed, the only solution was to add a string to the style tag and override the !important keyword from the CSS with an inline !important keyword!

Update (via Dan Popa): And here is why it happens: CSS Specificity

0 comments: