Cross browser CSS for your site
This article will go through some useful cross-browser CSS techniques I use to get my sites to look the same in several modern browsers. It’s fairly easy to send out different versions of your site to different browsers. This should be avoided though since it will end up with you having to maintain the site as if it was in fact several. That defeats the whole purpose with standards, why are they even needed if you are adapting to the browsers instead? My opinion is that good cross-browser coding is to find the set of standards that are supported and then use them.
Validate your site
Validation is a much debated area and many Level 2 bosses doubt that this procedure really helps. It does help though. It ensures that you didn’t do any simple spelling errors, things that could be incredibly hard to find manually. A validator also checks for nesting errors (did you put a <div> inside of an anchor?) and other strange things like your character encoding. Information about each of the errors is available as links when they appear, just click on one and you’re on your way to learn something new.
Validation is the simplest of my tricks to check. There are validators available for both (X)HTML and CSS. Use them! Any errors that show up on those lists could be a potential cross-browser breaker so if you decide to ignore any of them you should be really sure about what you are doing. There are reasons why each one of all of the errors on the validation page show up, so validate, fix, validate, fix, validate.
Stay in standards mode
The next trick is not as obvious. Modern browsers have two rendering modes they use to display websites with: Standards mode and Quirks mode. Standards mode is a rendering mode that is made to work according to the W3C specifications as closely as possible and Quirks mode is a bug ridden mode made for older sites. Why have a mode with bugs you ask? It’s a way for browser makers to keep their users happy. When you do big changes to your rendering engine a lot of old sites relying on browser bugs will break. Some might think that this is a good thing, why should sites still work when they are poorly coded? If you think like that you have forgot about who the web is for. It’s not a place for experts only, it’s made for regular users, that is, anyone with a browser. Those people need to see a working site if that’s possible.
So a new browser is released with a more standards compliant rendering mode and pages start to break. This is a bad thing for users so browser makers decided to first identify pages that tried to follow the standards, and if they did, switch to the new and improved rendering mode. You will probably see why I recommend standards mode now. All browsers are trying to render things as similar to the specs as possible when in standards mode, while in quirks mode they keep all their old bugs just to help regular users.
So how do the browsers identify who’s trying to follow standards and who’s not? They use the doctype. If you’re not familiar with doctypes, don’t worry, they are easy to learn. A doctype is a tag on first line of your site file telling the browser what markup language you will be using. There are basically two doctypes you should select among:
HTML 4.01 Strict (what I recommend)
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
XHTML 1.0 Strict (without <?xml ...> on the line before)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
Using any of these make sure the browser switches to standards mode and your design not fail because of that. Using a strict doctype means that you will do your best to separate structure from design and the validator will give you errors in those areas. It’s very useful. (Worth a small note is that the XHTML Transitional doctype also triggers standards mode, but while using transitional you don’t get as many good validation checks so don’t use that one anyways.)
There is one last catch one needs to talk about when dealing with doctypes and standards mode - the doctype needs to be the first tag in the document. If you put any HTML comments or strange characters before it IE will go crazy and switch to quirks mode. This has cause many developers countless hours of trying to fix things. Just don’t do it!
Remove default styling of elements
Another cause of many web developers screaming in the night is the default CSS that is applied to elements. If you don’t use any CSS at all on your page elements will still have a certain look. Headers will be larger than text paragraphs and blockquotes will have padding. Sizes of text is something that is pretty similar across browsers but something that’s not is padding and margins. Let me give you an example: With no styling an <ul> gets a padding in Firefox but a margin in IE. Solution? Set either the margin or padding to zero and set the other one to the indentation you want. You need to somehow remove the default browset styles.
These kinds of problems take up a lot of development time if not handled nicely. “Do definition lists in Opera have padding or margin?”. “What about second level headers in IE 6?”. Two schools of thought have evolved to handling this. The first one tells you to start by resetting all margins to their defaults at the top of you CSS file. This can easily be done by typing in * { margin: 0; padding: 0; }, * being a universal selector that applies the same rules to all elements.
Problem solved right? That’s where the second school of thought comes in. They argue that too many default margins are reset. Why should we mess with users form fields, rendering them hard to use unless they are set to good values again? Instead you could just reset those elements that have differences, and leave the rest untouched. This is quite a lot of work to get right so Faruk Ateş built a “starting css” template that you can easily include in your head. Personally I prefer the *-method, but try both and decide for yourself.
Browser bugs
This is the area where CSS gets hard. Even though browser makers work their asses off to follow standards they sometimes don’t reach their goals. This leaves us webmasters with bugs that when fixed triggers new bugs, either in the same or another browser. It can easily get real dirty.
One of the worst browsers (that is widely in use) is Microsoft’s Internet Explorer, version 6. Some claim they have about 80% of the browser market so it’s not a browser you can just ignore. IE was a good browser when it was first released but by today’s standards it’s certainly not. No other browser caused me more pain while building the design of this page. Its shortcomings get painfully clear when it comes to rendering complex CSS layouts.
How do you handle these bugs then? The easiest (and fastest) way is not solving it yourself but reading up on someone else’s solution. “Holly ‘n John” have gathered the most frequent bugs on their page Explorer Exposed!. They give you examples of how to detect the bug, how it works and why (sometimes) and most importantly how to solve it. Sometimes the solution is just setting position: relative; or display: inline; on some element and sometimes you have to resort to strange code. The point here is that if your bug is on that page; don’t waste time trying to figure it out yourself. Learn that list by heart.
So what do you do if your bug isn’t on the list? You start by googling for a solution of course. Googling takes a few minutes compared to the hour you probably need to hunt it down. Don’t underestimate this step.
If you don’t find it somewhere you need to hunt it down yourself. Do this by making a copy of your page and then removing as much code as you can while keeping the bug. Then find out exactly what line (or lines) of code that causes it and finally try to find another way of doing what triggers it. This is much better than just throwing in hacks, you keep your code maintainable and you learn a lot more useful stuff than if you were throwing in nonsense code from the beginning.
If you for some reason do not manage to solve the bug with the above technique you either rethink what you are doing (not likely) or you go get your arsenal of hacks. Make sure the hacks are valid code. The one I use for IE when nothing else works is the “* html” hack. You use it but writing like this: * html #element { code; }. That selector selects all tags that have the child html that have the child #element. But “html” is the topmost element in the hierarchy so nothing is selected, unless IE can choose of course. The code gets applied in IE only. Note that it is perfectly valid CSS, it just doesn’t select anything. Remember: hacks are your last resort when nothing else works.
[Update: 18 Jan] Richard in the comments point out that you can also use conditional comments to serve a certain <style> or <link> to different versions of IE. The “* html”-hack will not work in the comming IE7. Thanks Richard.
I hope you found something useful in this article that you can use when you get cross-browser CSS problems. I have now told you what steps I use, did I miss something? Do you do something differently?
zapada (6 comments) ( 13 Jan 2006 )
Finally, a nice way to fix all the padding/margin issues, while at the same time keeping the buttons functioning as buttons. Thanks!
jose (3 comments) ( 15 Jan 2006 )
Hi Emil, my name is Jose Cabana.
I’m a graphic designer from Venezuela, a tropical country in South America.
First of all, let me thank you and congratulate you for your excellent blog.
I’ve found it recently, and I must say that it has been very useful to me.
You’ve helped me to clarify some key concepts about standards development.
In my new weblog (in Spanish) I’m trying to write about these topics and I
wonder if it would be ok to translate some parts of your articles into Spanish.
Of course, I’d let people know that you are the original writer.
I hope this doesn’t bother you in any way, but, if so, please, let me know.
I’ll look forward for your answer.
Emil Stenström (487 comments) ( 15 Jan 2006 )
@jose: I have no problem with you translating my article as long as you say it’s mine and link to it. Good thing you liked it :)
david (7 comments) ( 15 Jan 2006 )
Hey Emil. saw you on stylegala, quick question
is this hack?
*{
margin:0;
padding:0;
}
I can’t get a definitive answer googling so I decided to start asking people.
BTW nice articles you have here
david (7 comments) ( 15 Jan 2006 )
what putz I am . I read the entire article and somehow missed the part about the question i just aksed. sorry Emil ;)
jose (3 comments) ( 15 Jan 2006 )
I’m glad that you agree.
Of course, a link to your site will be shown as well as your credits.
There is less information about web standards in Spanish than in English. For that reason I think that a translation of your articles would be very useful.
I mistyped my URL in my first comment, now it’s fine so that you can check the future posts.
Thanks a lot!
Emil Stenström (487 comments) ( 15 Jan 2006 )
@jose: very nice design you have going there, and well don’t with the multiple languages, I know that those require a lot of work. Did you submit it to any galleries?
@david: no worries :)
Henrik (2 comments) ( 15 Jan 2006 )
Me - margins: I’m second school of thought - let’s remove margins and paddings only when necessary!
Standards-mode: Also here am I the second school of thought - let’s use the XHTML definition. Furthermore, you don’t need the XML declaration on XHTML 1.0 Strict since it’s served as text/html when you do nothing more.
Emil Stenström (487 comments) ( 15 Jan 2006 )
@Henrik: About XHTML: exactly, you don’t need the XML prolog (that’s why it says so above the XHTML doctype in the article). If you add it there IE will go quirks mode on you, so whatever you do, don’t use it.
Richard (1 comments) ( 18 Jan 2006 )
Another option that’s becoming popular in light of IE 7 coming out soon is conditional comments. If something doesn’t work in IE, you can create a separate stylesheet and put the reference to it within conditional comments. This allows you to avoid CSS hacks altogether, and lets you apply stylesheets only to certain versions of IE.
David Duret (1 comments) ( 18 Jan 2006 )
Unfortunately, the conditional comments does not work with the standalone versions of Internet Explorer; it does not matter for people in general but it could be a problem for a web developer. A “good” solution could be to use the IE5.5/Windows Band Pass Filter (or it’s equivalent for IE5.0).
Uira (1 comments) ( 19 Jan 2006 )
Your blog isn\’t work with 800×600 resolution… so!
Emil Stenström (487 comments) ( 19 Jan 2006 )
@Uira: Yes one gets horizontal scrollers in 800×600. Looking at my statistics I see that 1.93% of my users have that resolution so I don’t think it’s that bad.
Sven (1 comments) ( 21 Jan 2006 )
Thanks for this nice article!
Can I translate this in german and use it on my site?
I would like to show this my classmates.
Emil Stenström (487 comments) ( 21 Jan 2006 )
@Sven: As long as you link back to me and don’t claim to be the author you are free to translate it. Nice to see you like it! :)
draco (6 comments) ( 31 Jan 2006 )
* htmlis still my friend till IE7 comes out. I have no idea why any other modern browsers can safely ignore this rule and yet IE7 won’t, so currently I have no qualms with using the tan hack.@Henrik: Use HTML strict DTD when it’s served as HTML. No point serving it as XHTML when what the users get is
text/html. Just my 2 cents.Emil Stenström (487 comments) ( 2 Feb 2006 )
@draco: IE7 will behave like other modern browsers and ignore lines like that. The reasoning behind that is the html is the topmost element and the rules selects all elements that are the parent of html.
Zach (1 comments) ( 3 Feb 2006 )
Thank god…
good article, was having a terrible time getting my layout to work in IE because I had placed above the doctype.
Thanks Again.
Odar W. (1 comments) ( 7 Feb 2006 )
Emil,
Your site isn’t displaying well in IE7-beta (background is missing).
I had the same problem with some of my sites.
Adam (3 comments) ( 7 Feb 2006 )
IE7 is just around the corner and the use of the star hack (* html) is really not a good idea in most circumstances. Think long and hard before using it as the use of IE7 will likely be very significant very soon.
David Owens (1 comments) ( 7 Feb 2006 )
@ David Duret
Hi, A lot of people have posted about conditional comments in IE standalones. There is a good article here http://www.positioniseverything.net/articles/multiIE.html
which explains how to get them working. I have IE5, 5.5, 6 and 7 beta 2, all running with conditional comments. Very useful!
Andyman3000 (1 comments) ( 7 Feb 2006 )
I kind of disagree on your advice when it comes to using XHTML transitional. I find using XHTML strict limits you in a lot of ways: e.g. pages won’t validate that use a taget=”_blank” which I sometimnes find very useful and customers often demand this. Overall I find that validating a page that uses XHTML 1.0 transitional usually gives you all the benefits you are referring to. What where you referring to when you said, that the validation information you get for transitional is not as useful?
Emil Stenström (487 comments) ( 7 Feb 2006 )
@Andyman3000: I was refering to this difference between strict and transitional. There are also good reasons that target got removed from strict.
@Odar W, Adam: I’ve had a look at IE7 and in the shape it’s in now it isn’t showing anything like it should. I’ll wait to fix my site until they have fixed their rendering engine.
matt (6 comments) ( 8 Feb 2006 )
your background of your website is a bit quirky in ie7.. any ideas what it is?
Velaluka (6 comments) ( 8 Feb 2006 )
http://www.quirksmode.org/js/doctypes.html
Noteworthy:
doctype switching also affects scripting!
quirksmode /standards mode affects browsers
http://hsivonen.iki.fi/doctype/
Maksim Rossomachin (1 comments) ( 11 Feb 2006 )
Hello, Emil. Look at this, please (some info about * selector):
«The other thing is the use of the “star-selector,” or * { } in CSS. The star selector selects every single element, which produces an overkill of style-nullifying. Sander pointed out that Mozilla (for one) has a great deal of default styling on form controls, which the star selector nullifies when applying margin:0 and padding:0 to it. As a result, buttons don’t behave like buttons anymore, and so forth. I never really noticed that, which only goes to show that I’m no longer used to buttons behaving like buttons. I did some research in this, and as it turned out, most of all the weblogs I frequently comment on have this same problem: buttons not behaving like buttons. In most cases, it was indeed the star selector being the culprit.»
Citation from http://kurafire.net/log/archive/2005/07/26/starting-css-revisited
Maksim Rossomachin, Russian Federation.
Emil Stenström (487 comments) ( 11 Feb 2006 )
@Maksim: I’m fully aware that there might be problems with using * {}. That’s why I link to the article you quote from in the article. All buttons on this site has had their margin/padding first nullified and then set to good value by me again and it works just fine, don’t you think?
Rob Worley (1 comments) ( 12 Feb 2006 )
Thanks for the insightful article. I’m a big CSS crybaby when it comes to browser quirks and you article put me within a few steps of the solution I needed. God bless!
Eric Chua (1 comments) ( 16 Feb 2006 )
Nice article. Very useful links stick in it.
ViB (1 comments) ( 2 Mar 2006 )
Just a quick note to let you that this article’s spanish transalation is done and up! Thank you very much for your kindness on allow me to translate it and make it available to the spanish parlor developers community. It can be found here
Once again, thx!
Cheers!
Kerry Pratt (1 comments) ( 24 Mar 2006 )
Emil,
I found your articles both interesting and useful. I think I’m a 4.8 striving to be a solid 5 (however, with my anal personality, I fear I might be headed for a low 6).
My current site is my first attempt at using (almost) exclusively. I am now in the midst of updating to strict XHTML and valid CSS.
Thanks for such an excellent site.
–kerry
Tom (5 comments) ( 1 Jun 2006 )
By the way, “Ateş built an “starting” on your /css/cross-browser-strategies-for-css/ page should actually be “Ateş built a “starting”.
Emil Stenström (487 comments) ( 2 Jun 2006 )
@Tom: Thanks, I fixed it.
Michael (5 comments) ( 9 Jun 2006 )
Hi Emil,
Good explanation of CSS.
How do you replace a framed site and still have a static group of elements like navigation and a masthead, footer etc. to make it more search engine friendly?
I’ve tried using layers but have difficulty undrsatnding how to target a layer with a new page and still make it cross browser compatible.
Mike
Emil Stenström (487 comments) ( 9 Jun 2006 )
@Michael: That is done with server-side scripting, ie. PHP, ASP or something like that. The usual way is to include some parameter in the URL that decides what page you include. In PHP it’s
<?php if ($_GET["page"] == “info”) include(”info.php”); ?>.Good luck!
Dave Everitt (1 comments) ( 19 Jun 2006 )
Michael: you can use CSS fixed positioning to make menu and header etc. stick while the rest scrolls. There’s an IE behaviours file that used JavaScript to make IE (which doesn’t do fixed positioning) errr.. behave. Eric Meyer’s two ‘on CSS’ books have the link… Emil: I think this is what Micheal intended, rather than the scripting you’ve mentioned. BTW, the quick uptake of PHP often ends up mixing logic and presentation, which is what we’re trying to avoid with markup and presentation in CSS and valid (X)HTML, and there also are also ways of dynamically showing and hiding content with CSS. Ruby on Rails (RoRis probably the way to go if you want to be more dynamic, but that’s more of a programmer’s art and a whole step sideways from CSS/(X)HTML still, to do a good job with RoR, valid CSS and (X)HTML skills are still a must. PS I tend to ‘flatten padding and margins with *{} but find it wierdly closes up line spacing (which only shows up in multiline headings) in IE - easy to fix, but anyone know why?
Emil Stenström (487 comments) ( 20 Jun 2006 )
@Michael: Ahh, I see now what you ment. I have a tutorial on replacing frames if you are interested.
@Dave Everitt: Agreed, that was just a quick fix to get him started. There are many steps between beginner and expert :) I’m afraid I don’t know a quickfix for what you ask about.
jenn.suz.hoy (4 comments) ( 27 Jun 2006 )
So grateful I have found this blog! I am in the middle of a dramatic redesign of my portfolio site (NOTE: in very early development stages, most links do not point to anything yet) incorporating CSS - a process I admit I am very new to.
Anyway, my links are proving to be a bit of a problem, with all the links in IE to appear to have my “nav” class applied to them. I’m glad to find your ideas on where to start when it comes to solving problems like this!
Jehangir Larry (1 comments) ( 22 Nov 2006 )
Re: Stay in standards mode
Why does this page not use ’strict’? Just curious.
Emil Stenström (487 comments) ( 23 Nov 2006 )
@Jehangir Larry: Strict is default so I’m just saving a couple of bytes :) Only downfall is that I put some version of IE5 in quirks mode by it. Luckily I don’t support that one. Good question.
Clay Jackson (1 comments) ( 9 Jul 2007 )
Hello, I was wondering what line of code I would use to have different versions of explorer reference the style I have applied. Maybe you could help in my search? Thanks.
Dudewtf? (1 comments) ( 11 Jan 2008 )
Hi, your article is very useful, thanks, I’ve got one question, is there a way to configure IE6 to view certain sites properly without having to upgrade to IE7? I viewed a site (torrentz.com) in IE6, and it looks like it has no CSS elements at all. Thanks.
Emil Stenström (487 comments) ( 14 Jan 2008 )
@Dudewtf: No, IE7 contains updates to the rendering engine that are needed to display some pages properly. Please update.
Farid (1 comments) ( 25 Mar 2008 )
A comment was made about your site not being compatible with 800 x 600 resolution. I had that same problem. Using percentages for the width fixed it. And if you position elements with the ‘left’, also try using percentages on that.
Thank you.
David Slade (1 comments) ( 23 Aug 2008 )
Hi Emil
I have a problem with my site. It appears that the site requires a firefox browser but when i use it with explorer some of the pages don’t align properly. Could you give me some suggestions. Hell i’ll even allow you to adjust the code for me, if thats what it takes. I know your the best from what ive read. Please email me as well. Its seems that the song page and the idiom pages have the biggest problem. Funny thing is, that i went to my friends house and had them download the firefox browser and guess what the same browser the firefox browser had an alignment problem. Is the firefox browser shit or what?
Emil Stenström (487 comments) ( 24 Aug 2008 )
@David Slade: Sorry, I don’t do consulting work. There’s lots of little differences between how IE6 and Firefox renders pages, and in 99% of the cases, it’s IE6 that is rendering things wrong. The baseline is the W3C specifications (CSS and HTML), and Firefox is the browser that follows that spec most closely. Is that shit? No, I don’t think so.