CSS Negotiation and a Sanity Saving Shortcut

7 Oct 2004

Fight the Power Default

A big part of dealing with cross-browser differences is accounting for the default property values of elements in each browser; namely padding and margin. I use the following declaration in every new site I design; it has saved me many hours of nitpicking.


* {
    padding:0;
    margin:0;
}

It doesn’t seem like much at first, but wait till you look at your mildly styled form in 11 browsers to find the positioning identical in all of them; or your button-style lists are perfect the first time, every time.
EDIT: following the interest this technique has generated, I have posted a more detailed description of how this technique may be able to help you — Global White Space Reset.

Keep it all valid & legacy friendly?

Support for CSS across current common browsers is varying to say the least. It’s up to the needs of each site to draw the line in the sand in regards to support for legacy browsers. My general preference is to give Netscape 4 no CSS, allow some minor style differences for IE 5.0/PC and to damn IE 5/Mac to hell; sorry old school Mac users.

Inviting CSS to the party


<link rel="stylesheet" href="/style/main.css" type="text/css" media="screen,projection" />

This method has a couple of advantages:

  • it does not suffer from the FOUC phenomenon, unlike @import.
  • Using a comma-separated list for the media attribute locks out NN 4.7. Step one of CSS negotiation complete.
  • Adding projection to the media attribute will cause Opera to use the stylesheet in full screen mode (hat tip)
  • Our specification of a definite list of supported media will allow more flexibility if developing a handheld stylesheet in the future. (A future where all mobile UA‘s have at least Opera’s level of CSS support.)

Build for the Best, Test with the Rest

The title from a post on any web development forum – “My CSS only works in IE! ”; – and it only ever will while you’re building in Internet Explorer. We’ve all heard it shouted from the rooftops (blogtops?) about how important it is to test in the most standards-compliant browser available when designing with said standards. Well DERRR! That’s like baking a cake and trying to taste it with you nose – it would be a similar sensation, but it’ll still be horribly wrong.

Beating Sense into Internet Explorer

There are only two methods I consider when delivering IE specific declarations in CSS:
Star selector hack for a one off fix


* html foo {bar:none;}

Delivering an extra stylesheet to IE/PC via a conditional comment


<!--[if IE]>
<link rel="stylesheet" href=" IE.css" media="screen" />
<![endif]-->

While both methods are valid, using conditional comments is the method I prefer as it allows all hacks to be kept totally separate. Some people are of the opinion that the mixing of code and comments is inherently wrong. They are correct, but this is war, damn it! Use IE’s own weapons against them, I say.
Step two of CSS negotiation complete – IE provided for without harming the innocent.

The Final Touches

You’ve built your page, it looks great in Mozilla/Opera/Safari and you’ve added a bit of correction for IE6 in your IE only file. Things probably don’t look quite right in IE 5 or 5.5/PC and depending on the differences; you may wish to add extra alterations for either or both.
My favourite method is using Tantek’s IE5 and IE 5.5 band-pass filters in the IE only stylesheet to import a separate file for that browser only.
Here’s a quick example of both filters:


/* IE5 */
@media tty {
 i{content:"";/*" "*/}};
 @import 'ie5.css'; {;}/*";}
}/* */

/* IE 5.5 */
@media tty {
 i{content:"";/*" "*/}}@m;
 @import 'ie55.css'; /*";}
}/* */

Having so many style sheets may seem a little crazy to many, but doing it this way means only users of the browsers that need to be hacked have to suffer the extra bandwidth load – all the more reason for them to upgrade. Also, when the day comes that IE 5 gets put in the NN4.7 basket you can just edit/delete the extra files and go about your day.

Filed under: ,

56 Comments

  1. Chris Gwynne:

    Nice :) I’ve amended my CSS and pages with the first couple of tips.

    Oh by the way, you’re homepage is messed up… the blog posts aren’t spaced out, subsequently elements are overlapping.

  2. Geoffrey Sneddon:

    Is it just me, or am I the only one wanting to nuke Redmond?

    Anyhow, I think Apple shouldn’t ship IE 5.2 with OS 10.4

  3. Andrew:

    Chris: Can you please email me which browser that is in… Cheers mate.

  4. Seth Thomas Rasmussen:

    I like your default declaration. I’ve been doing something similar, but rather than blanket every element and set all elements values to 0, I’d do something like this:

    h1,h2,h3,h4,h5,h6,ul,ol,dl,table,form,etc… {margin: 0 0 1em 0}

    I found, similar to what you found, that defaulting everything to this “top-down” behavior made dealing with margin collapsing MUCH easier in the long run. And it makes sense anyway, as a page runs from top to bottom, more often than not. Elements should only push off elements that follow them. Then, if something needs a specific top margin, I’ll add that, or not bottom margin, etc.

    Nice succinct little piece there, though! :)

  5. Geoffrey Sneddon:

    10,000! Wow! Well done ;)

  6. Kevin:

    I also prefer using conditional comments when dealing with IE issues, in fact it was pretty much the only way to get around certain CSS issues on my blog.

    I don’t really feel that there is anything wrong with using them, I mean I’d always like not too of course but I’m just thankful the IE developers up at M$ put them in, it was probably one of the only good features they have since they won’t update the rendering engine.

  7. Chris Gwynne:

    You’ve also taken off the comments variable from the front page again. I have to keep clicking to check now, damn you. ;)

  8. Geoffrey Sneddon:

    That’s my opinion to…

    and how come your names are bold…

  9. Andrew:

    @Chris & Geoff: Sorry guys! I’m in the process of redoing the front page and the interem solution that’s up there obviously isn’t up to your strict requirements :-p
    I’ll stick it back in there just for you two.

    @Geoffrey: Your name isn’t bold for you because you have visited your own site. That’s why my name’s never bold.

  10. Geoffrey Sneddon:

    Thanks Andrew…
    So, as well as getting the comment count back, I can never be in bold… well, at least for myself :p

  11. Andi:

    Thanks for the tips,

    * {
    padding:0;
    margin:0;
    }

    really makes things easier!

  12. Seth Thomas Rasmussen:

    Congrats on 10,000! I had a bunk stats program setup for a bit… then deleted it. Just setup ShortStat tonite. It’s already been fun to see where people are coming from. Three or four people hit the site via searches for the lyrics to “End of the Movie” by cake. I posted them in an entry just last week, I think! Small web…

  13. Andrew:

    Shortstat rocks Seth, I recommend it to everyone. There are other packages with more data, but shortstat displays all the good stuff so simply that it makes it hard to beat. Not to mention how easy it is to skin it ;-)

  14. Matthew Buchanan:

    I found that Tantek’s band-pass filters for IE5 and 5.5 didn’t validate when using check/referrer with the CSS validator scripts. I ended up putting the filters in the <head> of my page and then validating my external file instead, but it would have been nicer to be able to validate all of my CSS via the referrer option.

  15. Christian Watson:

    A very useful post, and a nice insight into a good way of working. Thanks for the “setting everything to zero” tip – now why hadn’t I thought of that?!

  16. bemson:

    Regarding IE specific rules, what about the underscore hack? I can’t remember where I first found it, but it’s my perfect solution to avoiding multiple stylesheets. IE 4-6 recognize css properties beginning with an underscore, while SafariMoz don’t. I don’t worry about Opera compatability (the latest Mac version uses the built-in Konfabulator-like engine anyway, I think). Nevertheless, has it not been mentioned because of something I don’t know? Like, it doesn’t work in Opera, or a rule with a prefix IS recognized in certain circumstances?

    The only drawback to using the underscore hack within a rule is having to overwrite prior properties. For example, for those who don’t know, using this hack, if I set a png image via the background property, I then have to overwrite this in IE with “_background: 0;”, and then follow that up with IE’s propreitary filter property.

    I’d like to hear what others think of and know about the underscore hack?

  17. Gabriel Mihalache:

    Very beautiful! Your post made me weep with hope!

  18. steve:

    If you’re using the IC conditional comments, then you can use them to discriminate on IE version (e.g. [if IE lt 5.5]) to import the specific IE version style sheet. Then you only need to have CSS hacks (the normal comment-backslash hack) to feed the 5.0 version stylesheet differently to IE/Mac.

  19. Mike P.:

    Awsome advice, a few more cool ideas to clean up stylesheets…

  20. Joe Spunkz:

    Congrats on the Hits – and thank you for the article. For those of us who are just starting to jump into the CSS cookiejar – it’s a blessing. :)

  21. Marilyn Langfed:

    Thanks so much. Your * margin, padding 0 trick just saved me from giving up on a form problem I’d been having. I’d received some very good information, but it still left me with a background problem in Safari. Adding your code fixed it!

    As a css beginner, I agree wholeheartedly that it’s a godsend to be presented with a whole solution, not just fragments.

    I still haven’t managed to get horizontal navigation to work on my site (I’ve also been advised of several other fixes I need to make), so it’s still a table. I think that when I tried it as an unordered list I was running into problems since I had a div inside a div inside a div, but don’t know enough yet to figure out what the problem was. That’s the hardest thing for me. I’ll go back to try it again soon.

  22. Joseph Lindsay:

    Also, when the day comes that IE 5 gets put in the NN4.7 basket you can just edit/delete the extra files and go about your day.

    That day is already here. If they are unable to upgrade to 3 year old browser IE<6 users have bigger problems than how a website looks. Serve them unstyled content or let the design break.

  23. Andrew:

    Thanks all! I’m glad others find that simple line as helpful as I do. Also, a big thanks to Roger, Scrivs and the 50+ people who linked to this post on del.icio.us overnight…I certainly didn’t expect to wake to see this sort of traffic on an old post :-)

    Matt : You’re right, the filters don’t validate — that’s why I put them within the IE only stylesheet and import that via conditional comments.

    Bemson: I’ve never heard of the underscore hack… It’s still a messy way to go though, as your hacks would be sprinkled through your CSS and you would no longer save bandwidth by only serving the hacks to IE. Personal choice in the end ;-)

    Steve: Good thinking! I’ve been cautious of specifying version numbers in the conditional comment as it is very picky when using exact numbers. The addition of ‘less-than’would circumvent that issue well. I’ll probably stick with my current method, purely to save from having extra markup in the html. (This site’s pages are already bloated enough!)

  24. Kevin Navia:

    Thanks Andrew for the tip!

    The star’red margins and paddings rule helped me a lot!

    I use the tan hack to feed rules for IE5x+, it works nicely here. So no IE only conditions here for me.

    One question:
    Using the star rule, select/option boxes were squished by Firefox (alone). So if have single digit numbers in that select box, Firefox users won’t see the number.

    Anyone know the default paddings used for select boxes in Firefox?

  25. Rick:

    Why diss MacIE5 when it essentially was the starter for mainstream standards-based browsers?

  26. Jacobus:

    I have been using the
    * {
    padding:0;
    margin:0;
    }
    for sometime now. It does make things easier, but please not the following.

    1. I add this directly afterwards.
    p {
    margin: 0 0 1em 0;
    }

    2. * does effect form -> select -> option elements. The dropdown arrow seems to cover some of the text. To help fix this I would just add a bit of right padding to the option element.

    Something like:
    form select option {
    padding: 0 0.5em 0 0;
    }

    Thats my 2c’s worth.

    Regards
    Jacobus

  27. Klaus Hartl:

    Nice article! Just wanted to mention that i as well add a border: 0 to the first statement (think of images and fieldsets):

    * {
    margin: 0;
    border: 0;
    padding: 0;
    }

  28. Andrew:

    Excellent! First bug found: breaks select boxes. Now if there was only a ‘not’ operator for CSS, eg *&&!select
    Klaus: although that may work fine, border:0; doesn’t make much sense… Border is a shorthand property, so to my thinking it would be border:none; or border-width:0;. I’m not so sure on that though ;-) .

    It would appear that the focus of this post really should have been the tiny addition I threw in at the last minute. Bleh, you live and learn.

    Why diss MacIE5 when it essentially was the starter for mainstream standards-based browsers?

    Because it has been written off by its developer and succeeded by the developer of the platform on which it operates. It has been heavily squashed and has no chance of a comeback.

  29. Small Paul:

    I think to turn off borders you’d want border-style: none;.

    Interesting to see someone else’s approach and justifications, for their base position: I’ve been trying to figure mine out for ages.

    Personally, I don’t go for the “turn off all margins and padding” thingy, as I prefer to leave the default browser styles where they are unless I’ve specifically come up with something I think is better.

    I’m pretty impressed at how well your design works in WinIE4. I’m with Geoffrey on leaving IE out of Tiger, but I’m (in a general sense) against Joseph on abandoning WinIE5. Obviously, it all depends on your user base, but I know that there are going to be a very large number of IE5-6 installs out there for several years to come. Not everyone is sitting on their machine at home, idly flicking through blogs instead of upgrading IE or downloading Mozilla. Many people are at work on machines they can’t control. Some people are in school or libraries with slow upgrade cycles libraries, some are in developing countries with donated hardware, and many don’t care/have no idea what a browser is, or that they can upgrade it. They bought the computer, they were told it would work. It should work.

    As I said, it depends on your user base. But generally, you will never get the entire world on a decent browser.

  30. Klaus Hartl:

    First bug found: breaks select boxes.

    Oh, it seems that wasn’t a good advice of mine. Just came across that idea recently and hadn’t tested it enough. Lessons learned :-)

    border:0; doesn’t make much sense… Border is a shorthand property, so to my thinking it would be border:none; or border-width:0;. I’m not so sure on that though

    Me either. But I think, the reason why border: 0; works fine, is because it is a shorthand. The missing border-style (and border-color) will fall back to default values, or in other words the browser adds the missing values. Therefore border: 0; is the same as border: 0 solid black. Somebody correct me please, if I’m wrong. The only reason to use it that way was for me, that it is the shortest declaration of all. The result of course should be the same as if I were using border-style: none; or border-width: 0;.

  31. Klaus Hartl:

    And removing borders from input elements isn’t always, what you would (and should) intend.

    After all better forget about border: 0; in conjunction with the universal selector. Adding img { border: 0; } won’t make your file much larger… :-)

  32. Rob L.:

    Great article. One request for clarification:

    Adding projection to the media attribute will cause Opera to use the stylesheet in full screen mode

    Can you explain why I’d want to do that? Hooked on Firefox; don’t know much about Opera features.

  33. Mike:

    Very nice article. The other “hack” I had typically used was usually only needed for a few main elements on the page when trying to get positions correctly for pixel-perfect stuff. In those cases, I typically put the declaration in correctly, then use direct decendant selector for non-IE browsers…

    .myNav {margin-left: 8px;}
    body>.myNav {margin-left: 10px;}

  34. Tiffany:

    Another option for serving hacks to IE is to use server-side browser detection. I feel a little scuzzy plugging my own on this one, but here’s an example of server-side detection using PHP.

  35. Andrew:

    Rob – Opera has a full-screen mode which people often use for presentations etc. If your media type is set as screen, Opera will display unstyled markup while in full-screen mode. At least it used to… 7.5 may have fixed this. None the less, I’ll leave projection in there just to lock out NN4.

    Klaus – You’re right to take back the idea of adding border:0; to a global statment. I had a think about that one last night and the damage it would do to form widgets is a bit over the top ;-)

  36. dclal:

    Opera will display unstyled markup while in full-screen mode. At least it used to… 7.5 may have fixed this.

    Opera still does it. At least on the Mac, v7.54.

  37. Derek Featherstone:

    Hey Andrew, nice stuff in this post. Makes perfect sense — with the number of times we declare margin: 0; padding: 0; on selectors, I’m surprised this solution didn’t come up before… so simple and so useful!

  38. Shaun Inman:

    I’m curious as to why you use the bandpass filters when you advocate conditional comments (something I agree with). Conditional comments allow you to specify the specific version of IE that the comment is revealed to.

    The only thing I can think of is that multiple installs of IE all think that they are whatever the latest version installed is and ignore the additional conditional comments in your testing environment.

    (I know, I know, I just answered my own question ;D)

  39. Kris Khaira:

    * { margin:0; padding:0; }

    I find this one most useful amongst the lot. I don’t really like browser-specific hacks although I know they’re necessary at times.

    thanks, Andrew.

  40. Andrew:

    I’m curious as to why you use the bandpass filters when you advocate conditional comments (something I agree with).

    That’s so I only have to add one conditional comment for all IE PC, instead of the minute amount of extra markup required to seperate the three guilty parties. Using the filters from within an IE only stylesheet means that each html page is ever so slightly lighter in weight while the IE only stylesheet (which gets cached anyway) is heavier. Strange trade off, but as a non-IE user I appreciate it :-D

  41. will:

    Excellent article – this is one for the Bookmarks. It is also a good reference for people just getting into CSS, and I will probably send quite a few folks this way.

  42. Jeremy Flint:

    Great tips. I had never thought of setting the margin and padding to 0 for all elements.

    I have used the bandpass filters a few times recently. I also like using the IE5/Mac filter that doug and tantek released a while back.

    Being able to apply browser only styles for the ones that get it wrong is probably one of the best tools in the arensal of a CSS designer.

    BTW Andrew, in Firefox on OS X, the checkbox next to “Do Not Save My Info” is the same width as the text fields above it. Didn’t know of that was intentional or not.

    Great Site.

  43. menty:

    hi there,

    thank you for providing those usefull tipps.
    i use this * margin and padding trick only and have no probs with cross browser development. the only damn thing is the double margin bug in IE when using float in the same direction as margin for the first float element.

    therefor i’ll try your css import method for diverent browsers, maybe it help to get rid of this IE bug.

    btw: i’m using firefox for css development, for me it’s the browser with the most compatibility towards css :)

    greetins
    menty

  44. Andrew:

    Menty — display:inline; will get rid of your double margin.

  45. me:

    nice article

  46. Aegir:

    There are conditional selectors for each version of IE. I’ve found it useful as the @import rule has a habit of crashing IE6 on WinXP Pro SP2. Basically it means you can’t use the mid-pass filter reliably any more.

    Oh, and this comment preview thing is a nightmare, I type, and have to wait for my poor old computer to catch up.

  47. Nathan:

    In this connection, it’s worth mentioning Eric Meyer’s discussion of Gecko browser default style:

    Really Undoing CSS

    In it, he describes that ‘unstyled’ really means ‘default style’, and that you can find a file called ‘html.css’ in your app’s folder (in mine it’s /firefox/res) that contains all these values. You can use it to establish defaults without having to use the star rule each time.

  48. Charles:

    The underscore hack is detailed here http://www.wellstyled.com/css-underscore-hack.html

  49. eijikel:

    yo Andrew.
    I used the conditionnal trick to address only to IE. However, the opening line of the conditionnal seems to be displayed in wap browsers. Have you tested your stuff right here?

    http://www.gelon.net/

    I might be the one making a mistake, but it’s worth a check I guess.

    cheers

    Alex

  50. ben scott:

    Think it is good when writing about a catch all css article to mention something about fonts set up.

    From what I heard from someone else a good trick is to set the font size to 100% and then make sure all other font sizes dont go under 0.7 ems. As long as inheritance problems aren’t coming from a conatiner DIV tag giving 0.7ems and the 0.7ems of that for the P tage you shouldn’t ever get any problems.

    also it might be nice to set a page default font in the body tag.

  51. Brian Davidson:

    I suppose in this age of hack usage to try to serve different css to dodgy (and in some cases, not-so dodgy) browsers, it may seem almost blasphemous to say this, but I don’t use hacks.
    Of any kind.
    At all.

    I (accidently) prevent NN4 from using my CSS by linking to the CSS file with a comma-separated media list but that is not really a hack, just CSS-compliant, and reduces the number of lines in my HTML file.

    As a result I don’t need to worry about which hack goes with which browser, or inventing new hacks as other, more-compliant, browsers become available. Also, if you have NN4 or IE5.0 hacks, will you remove them as these browsers become less popular? At what level will you do so? When their usage drops below 10%? 5%? Or will your site always have the box model hack because there might just be one user in 10 million still using this browser in 2015?

    I let the web be the web. I design according to recommendations in the knowledge that a compliant browser won’t break my site (and this browser is coming. Soon. Maybe…)

  52. Roland H.:

    Conditional comments can in fact be used to detect any specific version of MSIE. This technique, I believe, can be used to replace the more ugly CSS hack you suggest for differentiating between MSIE 5 and MSIE 5.5:
    http://www.javascriptkit.com/howto/cc2.shtml

  53. Tom:

    One more big thanks for the padding: 0 margin: 0 suggestion. I have spent countless hours trying to get elements to align correctly across the major browsers — which is akin to hearding a bunch of cats. This simple trick will make life so much easier!

    As far as browser support goes — I know two estremely wealthy people who use ancient hardware and never bother to upgrade their browsers. They are too busy making money to bother with upgrading anything, but they have the cash to buy almost anything and they do shop online. They may be only one in a million, but do you want to turn away a deep pocket customer like that?

  54. fambizzari:

    * { padding:0; margin:0; }

    Should the star be included as well?

  55. Andrew:

    Yes, the star is the ‘universal selector’ — it’s a wildcard which selects all elements :)