How to get Cross Browser Compatibility Every Time
Cross-browser compatibility is one of the most time consuming tasks for any web designer. We’ve seen many different articles over the net describing common problems and fixes. I’ve collated all the information I could find to create some coding conventions for ensuring that your site will work first time in every browser. There are some things you should consider for Safari and Firefox also, and IE isn’t always the culprit for your CSS woes.
Update: I've made a few updates to the post to include the suggestions in the comments
I’ve conducted all this research so I have a better understanding of the bugs of IE6 for my Grid Plugin. I want people to be able to forget about browser bugs when creating layouts, and the plugin will remove all these problems - well, that’s the goal.
I’m only going to be concerned with the major browsers - Firefox 2+, Safari 3+ and Internet Explorer 6+. IE6 is slowly declining and my site only has 3%. I don’t actually even support it. This luxury isn’t an option on client sites however, and it needs to be catered for. If you know the IE6 bugs you can generally know if your site will break before you even check it in a browser. This isn't an article for the super-experienced web designer, but hopefully will give some insight to some people who don't understand the mysteries of IE6 and cross browser compatibility.
Summary
Here is a quick summary for those of you who don't want to read the whole article:
- Always use strict doctype and standards-compliant HTML/CSS
- Always use a reset at the start of your css
- Use -moz-opacity:0.99 on text elements to clean up rendering in Firefox, and text-shadow: #000 0 0 0 in Safari
- Never resize images in the CSS or HTML
- Check font rendering in every browser. Don't use Lucida
- Size text as a % in the body, and as em's throughout
- All layout divs that are floated should include display:inline and overflow:hidden
- Containers should have overflow:auto and trigger hasLayout via a width or height
- Don't use any fancy CSS3 selectors
- Don't use transparent PNG's unless you have loaded the alpha
Element Inconsistencies
Every browser renders particular elements differently - different amounts of padding, margins, borders etc. This means your site can look different in every browser if you use default styles.
Solution
The first thing you should do, which most people most likely know about, is to reset your styles. A reset is some css you place at the start of your styles that removes the padding, margin, border and other inconsistencies from elements, and rebuilds them in a standard way. I like to use Eric Meyers reset, as it is specific in the elements it is resetting. Some people would argue that reset styles aren’t needed - but thats another story.
Download the reset.css and place the code at the start of your styles. Bam! Clean, cross browser styles.
Image Rendering
IE6 and IE7 both render resized images extremely badly. You should ever resize an image smaller or larger, in either the CSS or HTML, as it will look ugly in the browser.
Font Rendering
I told you not all issues were with IE. Safari 3+ has an issue with the way it renders light type on a dark background. Some would argue whether this is good or bad, but there’s a way to make it appear lighter. Here’s an example of standard white on black text rendering in Safari 3.1:
Solution
Easy fix. You need to add this to your code.
p {
text-shadow: #000 0 0 0;
}
Where #000 is your background colour. You will probably have to be more specific with the elements you select. I wouldn’t suggest using this fix on the body tag. Other elements you might need to fix are the li, dt, dd, blockquote etc. Use this on any text element you want to appear ‘thinner’. (Thanks Leevi for the update)
Update: Some people have suggested that this isn't good for the typography in Safari and that it will look better with standard rendering. I agree. But I know some people don't. We also can't assume which is better when we need to consider background colour, font colour and font selection. It's really up to personal choice.
To make this fix in Firefox, you use the opacity fix:
p {
-moz-opacity: 0.99;
}
You need to be careful with this fix, as it will break any Flash element that it touches in Firefox. There appears to be no workaround for it. (Thanks Wayde)
The type will now be rendered like this:
Font Selection
There are common web fonts that we use - Arial, Georgia, Verdana etc. But there are some fonts that are common to both PC and Mac and can be used - Century Gothic, Arial Narrow etc. However, different browsers and OS’s render type different, and you need to be aware of these differences, as your site could look dam ugly if you use the wrong font.
Solution
The font you choose is ultimately up to you. As long as it’s a safe font you will be fine. However you should be aware of these rendering issues. One font you should probably not use is Lucida Grande/Sans. It renders awful in IE. Take a look at its rendering in Safari(Mac):
Looks nice doesn’t it? Too bad it looks like this in Internet Explorer(PC):
Update: Some people have stated that Lucida Sans will look fine in IE with ClearType, and others have said that it still looks bad. A smart alternative is to just not use Lucida Sans as your 'fallback font', and instead use Arial or another san-serif font. It's really up to personal choice.
Font Sizing
The ability to resize text differs amongst browsers and OS’s. IE won’t resize text thats set in pixels. If we set all text in em’s, IE will exaggerate the text sizes when resized.
Solution
The best reference for font sizing is the article How to Size Type in CSS by Richard Rutter. The results - You need to specify the size as a percentage in the body element, and then size it in em’s through the rest of the sheet. For line height, you need to define it in em’s, rather than pixels, for consistent rendering.
One thing to remember is that the default font size is 16px. So to resize our type to 12px we use:
body {
font-size: 75%;
line-height: 1.5em;
}
Now you can size your type in em’s like so:
h1 {
font-size: 3em;
}
Another suggested technique is to resize it down to 10px, which makes it easier to size upwards in em’s. For example.
body {
font-size: 62.5%;
line-height: 1.5em;
}
h1 {
font-size: 1.8em; /* 18px */
}
p {
font-size: 1.2em; /* 12px */
}
There is an issue with this however, if people use small font option in Internet Explorer, it could be so small that it’s unreadable. It’s only a small chance. But worth noting.
Double Margins on Floats
We create CSS layouts by floating div's up against each other, like some form of horizontal tetris. When it reaches the end of a row, it drops down to the next. The common method for creating a grid is this:
#content {
float:right;
width: 300px;
margin-right: 10px;
}
#sidebar {
float:right;
width: 100px;
}
This is what it should look like in a browser:
This is what IE does to it:
The margin width is doubled. Any margin that is on the same side as the float will be doubled (Thanks Leevi). Don’t ask why. It’s just IE. This means the element on the left will have that margin stretched out to 20px, which will probably break the layout.
Solution
To fix it, all you need to do is put display:inline on your layout divs.
#content {
float:right;
width: 300px;
margin-right: 10px;
display:inline;
}
#sidebar {
float:right;
width: 100px;
display:inline;
}
Now that margin bug is all fixed. Even though it only effects margins on the same side as the float, it can still be useful to include this fix. You never know when you might use a margin on the float side. It won't effect any other browser, so you can use it safely.
Expanding Box
The expanding box problem is a big issue with many css layouts. When you have a standard layout, with floats sitting next to each other, with set widths, but an image or long string of text is longer than this width, the layout will break in IE6. Take a look at this example:
#content {
float:left;
width: 300px;
margin-right: 10px;
display:inline;
}
#sidebar {
float:left;
width: 100px;
display:inline;
}
This will render like in this most browsers:
However, in IE6, it will break like so:
Solution
The solution is to use the overflow property. If you place overflow:hidden; into the layout divs, the layout won't break in IE6.
#content {
float:left;
width: 300px;
margin-right: 10px;
display:inline;
overflow:hidden;
}
#sidebar {
float:left;
width: 100px;
display:inline;
overflow:hidden;
}
This could, however, cause some issues with layouts depending on how complex they are. It also won't cause the text to wrap, and it will just remain hidden. It's unlikely you'll have a string long enough to break a layout, but it could happen. Another option is to use word-wrap: break-word; in an IE specific stylesheet. This won't effect images though, so you'll have to make a choice about with method is appropriate for your situation.
Clearing Floats
What we mean when we talk about clearing floats, is when a container or wrapper div doesn't correctly wrap around the containing divs. Take a look at this example:
See how the container is correctly containing the div's? This is what should happen. However, sometimes it does not clear correctly, like so:
The container isn't correctly wrapping around it. You probably won't notice this until you try and put a background on your container.
Solution
There are a few different solutions for clearing. The best solution however, is a simple overflow:auto or overflow:hidden in your container
#container {
width: 966px;
margin: 0 auto;
overflow:auto;
}
You need to keep in mind that overflow:auto might cause some issues in Firefox. If you do have any issues, use overflow:hidden instead. If this is still causing issues, take a look at some other forms of clearing floats. (Thanks Leevi) Apart from just adding this, you'll need to make sure hasLayout is triggered in IE6. You can do this by specifying a width or height. If you don't have a width in your container, you can use height:1% to trigger it, or zoom:1; if you can't afford to give it a height (Thanks Joshua Paine).
CSS Selectors
Although we would like to use all the brand spanking new CSS3 selectors, IE6 doesn't support all of the major ones. There are also still some CSS2 child and sibling selectors you simply shouldn't use if you want to support IE6:
- E > F
- E + F
- E ~ F
- :root
- :last-child
- :only-child
- :nth-child()
- :nth-last-child()
- :first-of-type
- :last-of-type
- :only-of-type
- :nth-of-type()
- :nth-last-of-type()
- :empty
- :not()
- :target
- :enable
- :disabled
- :checked
- Any of the E[attribute] Selectors
- :first-child
- :lang()
- :before
- ::before
- :after
- ::after
Of course, a lot of these selectors aren't supported by even Firefox 3. For a full list of supported selectors, check out evotech.net's post on browser css selector support
Solution
Stick to your standard selectors. Nothing fancy. Only use E + F, E > F, E ~ F when it won't make a huge difference in IE. If you really need to use these selectors, you should look at using IE8.js which gives IE6 better selector support. However this will slow down your site. But we don't really care about IE6 users do we? :)
PNG Transparency
IE6 doesn't support alpha transparency in PNG's. This is possibly the most annoying bug/issue with IE.
Solution
There are a few solutions for this problem. You can either use AlphaImageLoader in an IE specific stylesheet, link to a behaviour file in an IE specific stylesheet or use JS to fix the issue. Not matter which way you choose, there is no way to have transparent repeating background images.
To use AlphaImageLoader, it's a little bit tricky. Add these properties to any png image you want to have transparency. (You need to put this code in an IE specific stylesheet if you want your CSS to validate)
.trans {
background-image: none;
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/transparent.png', sizingMethod='image/scale/crop');
}
Let's say you've given all your png image tags a class "trans", you select them with your css and use the filter property. You need to create a 1x1 transparent png file and link to it in the src attribute. Drew McLellan wrote a great article over at 24ways last year.
An even better way to do this is via a behaviour. Olav Bjorkoy, creator of Blueprint CSS, wrote a good article on this method. It's similar to the AlphaImageLoader, except that you link to a behaviour script that triggers the transparency.
The third method is to use IE8.js which I mentioned earlier. It's even safer than the previous method, and you are very unlikely to run into any problems. Link to the script in your HTML, and it will make any png ending in -trans alpha-capable. eg. myimage-trans.png.
With all this methods, you need to be aware that you might still run into problems with transparent pngs. Make sure you test it in IE6 extensively
Further Reading
http://warpspire.com/tipsresources/web-production/css-column-tricks/
http://www.onyx-design.net/weblog2/css/css-coding-for-cross-browser-compatibility/
http://www.smashingmagazine.com/2008/02/21/powerful-css-techniques-for-effective-coding/
http://www.positioniseverything.net/
http://www.noupe.com/css/using-css-to-fix-anything-20-common-bugs-and-fixes.html
Leave a Comment
This form has simple XHTML enabled, so go for it. It also uses Akismet to prevent spam.
Your email will never be displayed, and is used for verification. This form is also Gravatar Enabled.


64 Comments
Alfred
good read. didn’t know about the height: 1% trick. thanks
Niall Doherty
Website
Lots of useful stuff in there. Thanks for doing the research and putting it all together.
Loving your h2 styling, btw.
Dariusz Siedlecki
Website
I swear, this is one of the best articles I ever saw regarding cross browser compatibility, huge thumbs up!
Sandi Gauder
Website
Brilliant! Great tips. Your writing style deserves awards for clarity and brevity - thanks!
Elvis Tam
Website
AMAZING! I used to use clear:both to clear floats, but this is even cleaner!!! You rock thanks so much!!!
Janko
Website
Fantastic tips! Thanks!
Nik
Website
Excellent summary - thanks.
clark
Website
excellent list
clear explanations
great read
Benjamin J Doherty
Website
This article is really about accommodating IE6’s limitations. I don’t really understand the Safari quirk you’ve identified where text appears “too bright.” The alternative shows text that appears shimmery and multicolored.
Child and sibling selectors are part of CSS2, not CSS3. IE’s rendering of Lucida Sans is not worse than its rendering of Verdana, and Lucida Sans renders fine in IE if you ask me.
The YUI CSS is a great way to achieve cross-browser consistency, and it actually employs some of these tactics.
eyn
Website
What’s the problem with Lucida Grande? If a user uses IE, it is almost certain that the user will not have Lucida Grande installed on his computer, thus the alternative font, say Arial, will be used for rendering in IE. (font-family: Lucida Grande, Arial, sans-serif;) I don’t see the deal of not using Lucida Grande for cross browser compatibility, what you should have said is “use font family wisely, don’t expect user to come from the same OS by relying on a single, OS dependent font”.
eppsilon
Besides, Lucida Grande looks fine when rendered in IE - your screenshot makes it look far worse than normal because ClearType (font smoothing and hinting) is turned off.
Anthony Short
Lots of Lucida fans here I see :) In regards to falling back on Arial, I was mainly talking about the Lucida Sans alternative that is generally used. I probably should have stated that.
The Safari text rendering is really up to opinion. I personally like the way it renders text on its own, but I know a lot of people don’t, so I included it in there anyway.
Thanks to everyone who commented, I’ll take your feedback on board and update the article when I get a chance :)
Leevi Graham
Website
Gotta pull you up on a couple of things :)
“Use opacity:0.99 on text elements to clean up rendering in Safari”
To create ‘thin’ text on Safari you will need to use:
text-shadow: #000 0 0 0;For firefox you can use:
-moz-opacity:.99however this will cause issues with Flash & Firefox 2 on Mac.Double Margins on Floats
I’m pretty sure you need to float the element left and have the margin on the left to see this bug in action. Floating right with a margin right will also trigger this bug.
Clearing Floats
Using
overflow:autosometimes causes issues with Firefox and the dotted border on active links. These dotted borders can trigger scrollbars on some elements.There are a couple of better ways ofclearing floats.
I know this post was about achieving cross browser compatibility which is an admirable goal, however I personally think that building for obsolete browsers is more time consuming than its worth. A final word.
Anthony Short
Good work Leevi, I’ll have to make some more changes.
You were correct with the Double Margin bug, I double checked it. It only effects margins that are on the same side as the float. Doesn’t hurt to put it on your layout divs anyway I suppose, just in case.
I didn’t know about the dotted border issue with Firefox and cleared floats. I wouldn’t recommend the :after and content: ‘.’ method, as it can leave a gap at the bottom of your page. I can’t seem to find the article that described it, but the ‘.’ will leave a ~50px un-removable margin at the bottom of the container.
Thanks for the suggestions, I didn’t think I’d get it all right first time :) And yes, death to IE6!
Wayde Christie
Website
Just following on from Leevi’s comment that -moz-opacity causes issues with Flash in Firefox…
I’ve come to the conclusion that using this hack for Firefox is completely unmanageable if you plan to have any Flash in the page.
The bug comes about when a Flash element touches another element with any amount of opacity applied to it. This causes the Flash to disappear, and there appears to be no solution for this.
My advice: don’t use the Firefox opacity hack if you plan to use Flash elements also.
PS. Your button elements are doing crazy stuff on hover ;)
Ric
Website
Thanks - very useful. :-)
Jackie
Fantastic tips..thanks!
kl
“Use opacity:0.99 on text elements to clean up rendering in Safari”
Noooo! Please don’t! It disables pretty font smoothing in Safari and makes them look blurry. I absolutely hate that.
And Opera 9.5 makes such fonts bolder. Pretty annoying too.
Jem
Website
The irony of this being you have a bit of an overlap problem in IE - the Font Sizing title is overlapping the image above it in IE6.
eppsilon correctly identified the fact that Lucida looks like that because whichever PC you took that screenshot on has ClearType disabled.
Apart from those two picky bits, this was a very comprehensive article. Kudos! :)
Andrew
Website
Wow this is one of the most well-written articles on cross browser compatibility I’ve ever come across. Very helpful!
danbee
Website
Great article, bookmarked!
Nikki
This is a great article, and I would love to share it with my co-workers!
However your choice of font for your content text is extremely hard to read. Since your article specifically focuses on this issue, don’t you think your site should comply as well? I don’t believe Helvetica Neue is the best choice for readability.
(Ps.. I am using Win XP, FF3, Cleartype enabled, and I do have Helvetica Neue on my system. It doesn’t look pretty! I can send a screenshot if you’d like.)
André Medeiros
Website
Thanks for all the useful tips. I’m sure they’ll save me a lot of time in the near future.
Stanley
Website
In my experience the height: 1% hack is the #1 lifesaver when working with IE6.
Here’s another tip: use line-height if you’re having problems assigning height/padding to your display: block links.
Neil MacLean
Website
Brilliant. Really helpful.
And you just know I am looking forward to seeing how you use this in the grid plugin :-)
Joshua Paine
Website
zoom:1; is the best property for turning on hasLayout. You can safely use it in a general-purpose stylesheet since no other browser does anything with it.
Lucida Grande at many sizes looks friggin’ awful on anything that isn’t a Mac (or Safari running on PC). Font smoothing makes it worse, not better. And lots of PC users have it--it’s just not safe to use on the web, unfortunately.
IE7 and up does a page resize now instead of a text resize. I propose stop worrying about setting font sizes in px--it’s the easiest thing to do, and it works fine with page zoom in Firefox 3 an IE 7.
overflow:auto for clearing does indeed do weird things in Firefox at times. overflow:hidden is the better choice.
in my experience many fonts render more bold on Mac regardless of whether they’re light on dark or what. For the most part I think they look better, but at any rate they look like what Mac users expect them to look like, so it’s probably unwise to force a change.
Rupak Ganguly
Website
Great post. I not only like the information you shared but I like the way you presented the problem and the solution with screenshots. Thanks for putting so much time into the post to make it extremely useful. Keep it up.
Philip Arthur Moore
Website
Your Safari opacity code alone deserves a comment and a kudos. Thanks a ton for this information.
Chandoo
Website
very nice list, have implemented few of them and know what, my blog is looking better in IE now… thanks :)
TraffiK
Website
wow, this is a great ressource, Thanks for sharing
Anthony Short
Thanks for all the suggestions. I’ve updated the article to include most of the suggestions. I realise the font ‘rules’ are really optional and up to personal opinion. I’ve tried to include everything possible to cater for everyone.
Just remember, these aren’t set in stone. It’s just a guideline :)
@Nikki, I’ll have a look into the font rendering. Thanks for picking that up.
@Jem - I don’t bother supporting IE6 on this site. But yes I can see the irony ;)
Matt
Website
Just a little FYI:
You’re not going to want to use opacity: 0.999; because it makes the text look jagged in Safari. Instead, apply text-shadow: #FFF 0 0 0; to the body. This will fix the Safari rendering issue while still allowing the fonts to be nice and smooth.
Ivan Nikolic
Nice article…
paul
Website
Good to know about CSS.
Hope to find some article like that about JS ;)
Anthea
Great article, really appreciate it.
I am familiar with a few of those bugs, but always misplace the fixes. Thank you
Charlie
Website
As most people say, great article! Thank you.
barbamodder
Website
I recently finished a big multi browser project....never having dealt with css.....I think I bumped into 80-90% of the problems mentioned in this article!!!!!!!!!!!!!!!!
GREAT STORIE!!!!
Steve Daly
Great article! Excellent job explaining all the issues and their solutions.
I appreciate the editing of the article to include some of the comments that have been made.
Mario Garcia
Website
Great Job.
Excellent people.
Thank’s for share knowledge.
MIchael
Website
Hi Anthony,
Another great article. You’ve definitely given me some tips and some things that never really crossed my mind. I am going to try some out.
Thanks.
Wayde Christie
Website
Just noticed you’re suggesting opacity for your Firefox font rendering fix.
Applying opacity makes the text look spindly and horrible in Safari (and in Firefox 3 too I just noticed), so even though it’s a proprietary bit of CSS, I use -moz-opacity instead. This sorts the text in FF but leaves it alone in Safari.
Add in the text-shadow trick and you’ve got all your bases covered ;)
alexisr
tnks men nice post
chris
You don’t have to use any of those nasty hacks or files to make alpha transparency PNGs look decent in IE. You just have to compress it differently:
http://www.kevinfreitas.net/pro/articles/png-magic/
Yes, you lose a little something this way (IE users may not notice the difference anyway, since the ugly grey fill is gone), but you can usually get smaller image sizes this way since Photoshop only allows alpha transparency on 24 bit PNGs when saved for the web.
Now you can use them as tiling background images.
Andrea Hill
Website
A good practice I’ve adopted is also never to specify a width to an element, as well as padding. I use a container set to the width I desire, and then use margin on the elements within. That way you don’t have to worry about box model funkiness..
Anthony Short
@Andrea - You shouldn’t have box model problems in IE6+ if you’re using the Strict Doctype.
“In Explorer, the rendering mode decides which box model it follows. In quirks mode it uses the traditional model, in strict mode the W3C model.” - Quirksmode
Sangesh
Website
Thanks a ton for this very useful article. I’ve put it in my del.icio.us also.
kjmoran
really nicely written. thank you.
NOW can we figure out why FF3 and Opera9.5 won’t render SOME pages that’ve been fine for 2 years?
from what i can see of the page code, this seems to be completely arbitrary, although javascripts are more frequently involved.
DanK
Website
Thanks for the info! This’ll save me a tonne of time trouble shooting by doing things right in the first place :)
Gilbert
Website
Some nice stuff in there. Great resource.
Mathieu Beausoleil
Website
It may be a good idea to explain in the article that having “hack” (like display inline to correct the double margin bug on ie6<) must be in a ie6.css or loaded via a * html element {}.
Browser respecting the standard, in 2 or 3 years, must have problem to render. Every unlogical fix must focus only to the specific browser.
felipe.lv
Website
You should note that, as Lucida (which, by the way, works fine for me even in MSIE), Calibri also has some issues; in particular, it renders horribly on Ubuntu/Linux.
The thing is, there are (at least) two versions of Calibri: the 1.0 version it’s included in the MS Office Compatibility Pack; Office 2007 includes a 1.02 version. The latter is the version that presents problems on Ubuntu/Linux, version 1.0 works perfectly.
There’s more info here: Ubuntu forums: font rendering problem
ben
Website
Nice one
will come in very handy
http://www.duivesteyn.com.au
suresh
Website
Great article and really time saver.....so i,m going to use and test the tips......By the way which reset you prefer.... yahoo , mayer or any others.
Mark Abucayon
Website
This is very nice I enjoyed reading the article, I learned new techniques here, Great Job, really nice ...
Daryn St. Pierre
Website
Man, this is a great article. I learned quite a bit. Nice work!
Janko
Website
Great article, mate!
szako
Website
Excellent article, thanks
srinivas
Absolutely brilliant article. Great resource.
norm
Website
the hint for font rendering in firefox can cause problems with floated layers..
dersleri
Website
CSS “Cascading Style Sheets” Lessons
css list style Properties and examples—http://css-lessons.ucoz.com/list-css-examples.htm
Odul Kaya
Website
Excellent article, thank you…
shaiby
thanx dude
i realy much comfortable with these solutions.
i will bring down overhead of IE 6 & 7.
n0ta
Excelent article buddy! Great compilation for a quick reference. Really nice.
Rod
Website
I found this article from NetTuts’ weak article on CSS and I’m blown away. This is awesome!
The only caveat here from my point of view is that your suggestions for font sizing are a little short sighted. I’m maintaining a large site now which uses exactly what you specify (body { font-size: 62.5% }) and it’s hell for integrating third party and legacy content.