Menu Search
Jump to the content X X

Today, too many websites are still inaccessible. In our new book Inclusive Design Patterns, we explore how to craft flexible front-end design patterns and make future-proof and accessible interfaces without extra effort. Hardcover, 312 pages. Get the book now →

The Principles Of Cross-Browser CSS Coding

It is arguable that there is no goal in web design more satisfying than getting a beautiful and intuitive design to look exactly the same in every currently-used browser. Unfortunately, that goal is generally agreed to be almost impossible to attain. Some have even gone on record1 as stating that perfect, cross-browser compatibility is not necessary.

While I agree that creating a consistent experience for every user in every browser (putting aside mobile platforms for the moment) is never going to happen for every project, I believe a near-exact cross-browser experience is attainable in many cases. As developers, our goal should not just be to get it working in every browser; our goal should be to get it working in every browser with a minimal amount of code, allowing future website maintenance to run smoothly.

In this article, I’ll be describing what I believe are some of the most important CSS principles and tips that can help both new and experienced front-end developers achieve as close to a consistent cross-browser experience as possible, with as little CSS code as possible.

Cross-Browser CSS

Understand the CSS Box Model Link

This is one of the first things you should be thoroughly familiar with if you want to be able to achieve cross-browser layouts with very few hacks and workarounds. Fortunately, the box model is not a difficult thing to grasp, and generally works the same in all browsers, except in circumstances related to certain versions of Internet Explorer (more on this later).

The CSS box model is responsible for calculating:

  • How much space a block-level element takes up
  • Whether or not borders and/or margins overlap, or collapse
  • A box’s dimensions
  • To some extent, a box’s position relative to other content on the page

The CSS box model has the following basic rules:

  • Block-level elements are essentially rectangular (as are all elements, really)
  • The dimensions of a block element are calculated by width, height, padding, borders, and margins
  • If no height is specified, a block element will be as high as the content it contains, plus padding (unless there are floats, for which see below)
  • If no width is specified, a non-floated box will expand to fit the width of its parent minus padding (more on this later)

Some important things to keep in mind for dealing with block-level elements:

  • If a box has its width set to “100%”, it shouldn’t have any margins, padding, or borders, otherwise it will overflow its parent
  • Vertically-adjacent margins can cause some complex collapsing issues2 that may cause layout problems
  • Elements positioned relatively or absolutely will behave differently, the details of which are extensive and beyond the scope of this article
  • The rules and principles above are stated under the assumption that the page holding the block-level elements is rendered in standards mode (this point was added later after review of the comments posted3)

The Box Model as shown in Firebug
The box model as its displayed using Firebug in Firefox

Understand the Difference Between Block and Inline Link

For experienced developers, this is another no-brainer. It is, however, another crucial area that, when fully understood, will cause the light bulb to appear4, many headaches will be avoided, and you’ll feel much more confident in creating cross-browser layouts.

The image below illustrates the difference between block and inline elements:

Block and Inline Elements

Here are some basic rules that differentiate block elements from inline:

  • Block elements will, by default, naturally expand horizontally to fill their parent container, so there’s no need to set a width of “100%”
  • Block elements will, by default, begin at the leftmost edge of the parent box, below any previous block elements (unless floats or positioned elements are utilized; see below)
  • Inline elements will ignore width and height settings
  • Inline elements flow with text, and are subject to typographical properties such as white-space, font-size, and letter-spacing
  • Inline elements can be aligned using the vertical-align property, but block elements cannot
  • Inline elements will have some natural space below them in order to accommodate text elements that drop below the line (like the letter “g”)
  • An inline element will become a block element if it is floated

Understand Floating and Clearing Link

For multi-column layouts that are relatively easy to maintain, the best method is to use floats5. Having a solid understanding of how floats work is, therefore, another important factor in achieving a cross-browser experience.

A floated element can be floated either left or right, with the result that the floated element will shift in the specified direction until it reaches the edge of its parent container, or the edge of another floated element. All non-floated, inline content that appears below the floated element will flow along the side of the element that is opposite to the float direction.

A Floated Element

Here are some important things to keep in mind when floating and clearing elements:

  • Floated elements are removed from the flow of other block-level, non-floated elements; so in other words, if you float a box left, a trailing paragraph (block level) that’s not floated will appear behind the float in the stack, and any text inside the paragraph (inline level) will flow around the float
  • To get content to flow around a floated element, it must be either inline or else floated in the same direction
  • A floated element without a declared width will shrink to the width of its content, so it’s generally best to have a set width on a float
  • If a block element contains floated children, it will “collapse”, requiring a fix6
  • An element that’s “cleared” will avoid flowing around floated elements above them in the document
  • An element that’s both cleared and floated will only clear itself of elements that come before, not after

Use Internet Explorer First (Or Don’t) Link

Please note that Smashing Magazine’s team strongly advises against developing websites in Internet Explorer first. In our opinion, sites should be developed in “modern” web-browsers, with standards first and then be tweaked for buggy versions of Internet Explorer. The advice below does not reflect the opinion of the Smashing Editorial team. Agree or disagree? Comment on this article!

Most of what I’ve discussed so far has to do with CSS coding and layout principles. This principle is more related to habits and preferences of most designers. Although we might hate to use IE6 and IE7 in our everyday internet activities, when it comes time to build a client project from scratch, one of the best things you can do is test your layout in those browsers early in development. You might even want to open up a standalone version of IE6 or IE77 and just start your development in that browser.

Of course, you won’t have access to tools like Firebug, but generally for CSS (especially early in development) you won’t need Firebug. It’s much easier to get a layout working first in IE6 and IE7, then fix for other browsers, than to do it the other way around. Waiting until late in the development process to open up IE6 and/or IE7 will likely cause some, if not all, of the following problems:

  • Multiple hacks will be required, needing separate stylesheets for different versions of IE, making the code bloated and less maintainable and making the website slower
  • The layout in some spots may have to be reworked, multiplying development time
  • Testing time will increase, sometimes exponentially, leaving less time for more important tasks
  • The layout in other browsers will not be the same as in IE6 and IE7

I wouldn’t expect developers to use Internet Explorer this aggressively for personal projects, web apps, or other non-client work. But for corporate clients whose user base is primarily on Internet Explorer, this tip could prevent a lot of headaches while getting things to work properly, and will definitely make a cross-browser experience much more likely.

Sometimes viewing IE’s problems as “annoying bugs” can create unnecessary negativity, and can hinder development time and future maintenance. Dealing with IE is a fact of life for designers and developers, so just view its problems as you would any CSS issue — and build from there.

Understand Internet Explorer’s Most Common Problems Link

If you’re going to start with IE in your development, or at the very least check your layout in IE early on, then you should understand what things Internet Explorer (usually versions 6 & 7) has problems with, or what its limitations are.

A detailed discussion of every possible problem that can occur in Internet Explorer, and a list of all of its CSS compatibility issues8 is certainly beyond this article. But there are some fairly significant inconsistencies and issues that come up in relation to IE that all CSS developers should be aware of. Here is a rundown of the most common problems you’ll need to deal with:

  • IE6 will become problematic if floats are overused, causing (paradoxically) disappearing content or duplicate text9
  • IE6 will double the margin on floated elements on the side that is the same direction as the float; setting display: inline will often fix this
  • In IE6 and IE7, if an element doesn’t have layout10, it can cause a number of problems, including backgrounds not showing up, margins collapsing improperly, and more11
  • IE6 does not support min- and max-based CSS properties like min-height, or max-width
  • IE6 does not support fixed positioning of background images
  • IE6 and IE7 do not support many alternate values for the display property (e.g. inline-table, table-cell, table-row, etc.)
  • You cannot use the :hover pseudo-class on any element in IE6 except an anchor (<a>)
  • Certain versions of IE have little support for certain CSS selectors12 (e.g. attribute selectors, child selectors, etc.)
  • IE versions 6-8 have little support for CSS3, but there are some workarounds13

There are many more bugs, issues, and inconsistencies that can arise in Internet Explorer, but these are probably the most common and most important ones to keep in mind when trying to create a cross-browser experience. I encourage all developers to do further research on many of the issues I’ve mentioned above in order to have a more accurate understanding of what problems these issues can cause, and how to handle them.

Some Things Will Never Look the Same Link

As already mentioned, creating the exact same experience visually and functionally in every browser is possible, but unlikely. You can get the layout and positioning of elements close to pixel-perfect, but there are some things that are out of the developer’s control.

Forms Will Often Look Different Link

Discussing all the differences and quirks that occur with form elements across the different browsers and platforms could be an article in itself, so I won’t go into extensive details here. A simple visual demonstration, however, should suffice to get the point across.

Take a look at the image below, which displays the <select> elements on the Facebook14 home page, as shown in 5 different browser versions (screenshots taken from Adobe’s Browserlab15):

The Facebook sign-up form in different browsers
<select> elements appear differently in different browsers

Some form elements can be controlled visually. For example, if the client requires that the submit button looks the same in every browser, that’s no problem, you can just use an image, instead of the default <input type="submit">, which, similar to <select> elements, will look different in different browsers.

But other form elements, like radio buttons, textarea fields, and the aforementioned <select> elements, are impossible to style in a cross-browser fashion without complicating matters using JavaScript plugins (which some developers feel harm the user experience).

Typography Will Always Look Different Link

Another area in which we can’t expect pixel-perfect designs is with regards to fonts, particularly fonts on body copy. Different methods16 have sprung up to help with custom fonts in headers, and the recently launched Google Font API17 will contribute to this. But body copy will probably always look different in different browsers.

With typography, we not only face the problem of font availability on different machines, but in some cases even when the font is available on two different machines, the type will look different. Windows ClearType18, for example, is available on IE7, but not on IE6, causing the same font to look different on two different versions of IE.

The graphic below displays screenshots from A List Apart19 on IE6 and IE7. The grainy text in IE6 is more evident on the heading than in the body copy, but all text displays a marked difference between the two browsers (unless of course the text is an image):

A List Apart's typography compared in IE6 and IE7
A List Apart’s typography compared in IE6 and IE7

Use a CSS Reset Link

Ever since I started using a CSS reset for my projects, my ability to create a cross-browser experience has greatly increased. It’s true that most resets will add unnecessary code to your CSS, but you can always go through and remove any selectors that you know will not be a factor (for example, if you don’t plan to use the <blockquote> tag, then you can remove reference to it, and repeat this for any other unused tags).

Many of the margin- and padding-related differences that occur across different browsers become more normalized (even in troublesome HTML forms) when a CSS reset is implemented. Because the reset causes all elements to start from a zero base, you gain more control over the spacing and alignment of elements because all browsers will begin from the same basic settings.

CSS Reset
A CSS reset as shown in Firefox’s developer toolbar

Besides the benefits of producing a cross-browser experience, a reset will also be beneficial because you won’t use as many hacks, your code will be less bloated, and you’ll be much more likely to create maintainable code. I recommend Eric Meyer’s CSS reset20, which I’ve been using for quite some time now.

Use SitePoint’s CSS Reference Link

If you’re having trouble getting a particular CSS property to display correctly across all browsers, look up the property in the SitePoint CSS Reference21 to see if it has any compatibility limitations. SitePoint’s reference (which is also available as a hard copy22, though not as up to date), includes a useful compatibility chart that displays browser support for every standard CSS property.

SitePoint's Compatibility Charts for CSS Properties
SitePoint’s Compatibility Charts for CSS Properties

Each compatibility chart is accompanied by a fairly detailed description of the bugs that occur in different browsers, and users are permitted to add comments to document new bugs that come up and to provide further explanations on complex CSS issues.

Using this as a guide, you can narrow down the possibilities, and can usually determine whether or not a CSS issue is due to a browser bug, or due to your own misapplication or misunderstanding of the CSS property in question.

Conclusion Link

While there is so much more that could be discussed on the topic of cross-browser CSS, the principles and guidelines I’ve introduced here should provide a foundation to assist CSS developers in creating as close to a consistent cross-browser experience as is currently possible. Cross-browser CSS is an attainable goal, within reasonable limits.

But, as an epilogue to this article, I also would like to concur with those promoting the use of CSS3 with progressive enhancement23, and encourage developers to push new CSS techniques to the limits, even doing so, where possible, on client projects.

The principles I’ve introduced here should help developers create a beautiful and intuitive experience in IE, while providing an extra-beautiful and super-intuitive experience in the more up-to-date browsers. That’s a cross-browser goal that is definitely worth striving for.

Footnotes Link

  1. 1
  2. 2
  3. 3 #comments
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23

↑ Back to top Tweet itShare on Facebook


Louis Lazaris is a freelance web developer and author based in Toronto, Canada. He blogs about front-end code on Impressive Webs and curates Web Tools Weekly, a weekly newsletter for front-end developers.

  1. 1

    Ben MacGowan

    June 7, 2010 3:50 am

    Great article.

    I would disagree with the starting with Internet Explorer first. I always code in Firefox, so I am pretty much guaranteed that it will work in Firefox, Safari, Chrome and Opera. Then being to look at Internet Explorer to work out the kinks.

  2. 2

    I think, you should start with the browser most of your users will use. For different projects these are different browsers.

  3. 3

    I used to start with IE as you suggest here, since if it works in IE it’ll usually work in everything else. But eventually I grew so dependent on Firebug and the other developer add-ons for Firefox that it no longer made sense to test in any other browser. Plus, the more I worked with CSS, the more I knew how to avoid causing IE problems in the first place and deal with them relatively painlessly if they did pop up.

    One tip: If possible, sniff the browser and attach it as a class to your body tag. You can’t do it in all situations (for example, it’s usually bad practice in Drupal because of how the cache system works), but it’s easy to do in WordPress.

  4. 4

    Michael Ward

    June 7, 2010 4:01 am

    “You might even want to open up a standalone version of IE6 or IE7 and just start your development in that browser.”

    That way lies madness!!

    Develop in Firefox and test regularly in other browsers (after each major styling feature is in place) – that way you can catch bugs or differences before they accumulate in to balls of inter-dependant problems.

    Develop to standards (which tend to be predictable) and fix bugs in browsers as you encounter them. But do not leave IE6 testing until late on, you will severely regret it.

    Loved the rest of the artice :)

  5. 5

    James Moxley

    June 7, 2010 4:16 am

    Working in IE first is a terrible idea, work with a compliant based browser such as FireFox, Chrome, or Safari. Its good practice to test against a whole suite of browsers, but development will be easier starting with a compliant browser. Don’t use hacks within the CSS, instead use conditional comments to overcome the quirks within IE.

  6. 6


    June 7, 2010 4:20 am

    awesome article!!
    ithink as alexey said, and u can analyze it using any statistics as google analytics to know the most browsers used by your project visitors

  7. 7

    I agree with developing in the “best” browser you can first. Getting everything looking right across Firefox, Safari and Chrome is usually very simple. I’d go as far as to say if you run into more than a couple of minor layouts niggles between the latest versions of these three browsers you’re doing something wrong.

    I always leave IE testing until late on, using conditional comments to include IE-only stylesheets for version 6, 7 and 8 makes it quite a clean way to work.

  8. 8

    I disagree with you, if you mean it is better to start developing with IE. If you develop Websites or Webapps you need tools like Webdeveloper-Toolbar or Firebug for live-debugging or the Speed Tracer for optimzing the loading speed. If you do develop frist for or with IE, you don’t have those possibilities of live-debugging or -testing.
    First: Firefox, Safar, Chrome, Opera, ………, IE

  9. 9

    I have to agree with Ben. I used to code in IE first, and I’ve long since switched to coding in Opera/Firefox first (I check both as I go along). 99% of the time, doing this makes the site look the same in Chrome, Safari, Opera and Firefox. It also looks the same in IE8 the vast majority of the time, and IE7 and IE6 only need small tweaks by using conditional comments. I’ve found when I develop for IE first, I end up starting over because the stuff I put in place for IE is completely messed up for Firefox/Opera/Chrome/Safari.

    I believe understanding the other key points he’s mentioned up there helps a LOT with this, because as I’m coding for the standards browsers, I’m thinking of what could/would happen in IE. Stuff like “disappearing text” is fixed by giving elements hasLayout. Duplicate text is *dead* easy to fix – the only time I’ve ever seen that is when I put a comment *outside* of a closing div – put it just before the closing div tag, problem solved. The rendering of min-height and max-width can be set with a conditional comment by setting width and height – IE6 will expand to that, but it won’t go over it.

    All in all, it’s really in how you work. Perhaps a lot of people work more efficiently doing IE6 first. Great for you. I think you’re nuts – because if *I* do it that way, it takes me 2-3 times as long to get something finished. But if it’s more efficient for you to do it that way, I salute you, and continue on. It’s more efficient for *me* to make IE the *very last* thing I check. I can have IE 7 and 6 fixed in 30 minutes or less – so to me it makes no sense to code for the worst thing and “fix” everything that’s working fine.

    So although I, personally, do not agree with coding for IE first, I don’t think I should tell everyone they are wrong if they do. If it’s efficient for you to do that, wonderful. For me, it’s not. Neither of us are wrong. But the other points made are excellent, and very useful. Good article :)

  10. 10

    Very good article, but I have to disagree with the “start with IE, them go for the rest” strategy. That way, the not-so-good (to put it politely) browsers will never go away.
    I always design and code for standards first, test with Firefox, Chrome, Safari and Opera, leaving IE for last. And it it doesn’t look too ugly and works ok, I leave it as is.

  11. 11

    Start with the bad and then make it good? That doesn’t make any sense.

    You should start by making your code as correct as possible, then provide exceptions for those that need it.

    I personally have found that using this technique has resulted in designs working in all modern browsers from the start. The only browser I am left to tweak for is IE6, which I do using conditionals. I check my code in Firefox and IE7 as I go, with checks in Safari and Chrome at major milestones. I rarely have to do any adjustments to get things working properly in those four.

    If you are having that many problems getting a design to work in IE7 the same as Firefox or Chrome, then you are either using code that isn’t fully supported yet, or you are coding wrong.

    And yes, I know that they have different rendering engines. But all of these engines are rendering to the same spec. If you are coding within finalized standards, then you shouldn’t be having problems.

  12. 12

    I also disagree with using IE first. I find that using IE as a base means spending more time to get it to sit correctly in other browsers. Where as if I use Firefox I only have to do small changes to make it fit into IE with conditional css

  13. 13

    I’ve got to agree with everyone who’s pointed out that starting development in IE and checking in FF/Safari etc as you go is terrible advice.

    This used to be the way i built web sites when i was learning my trade (as did many other people i’m sure) but as soon as i switched my workflow round life became soooo much easier.

    You know that if something works in FF it will just as likely work in every other non-IE browser, and you then have the luxury of conditional CSS to target any IE problems. If you do it the other way round there’s no way of writing specific rules for non-IE browsers to fix a rule that works in IE because of a quirk of implementation, but doesn’t work in any other browser.

    There’s some great nuggets of info in this article, but making IE your development browser is not one of them :-(

  14. 14

    Nice article with some good understanding of the basics. I’d like to add that using a CSS Reset should be used with caution. Always re-pattern the reset so that you don’t end up ‘fixing’ basic selectors over and over again. Normalise instead of zeroing.
    Personally I’d never advise starting with IE. In my experience it usually leads to more CSS bloat. Working in Firefox or similar compliant browser results in a leaner HTML and CSS. Having said that, you should routinely check your front-end code in IE to make sure you find things working or failing as expected.

  15. 15

    There are a few basics you can learn that will help you with IE, but I’d never start with IE when it comes to coding. You can always go back in and tweak the code for IE anyway.

    Also, I stopped supporting IE6 a few weeks ago, officially. With only 5% of the population now using it, I think we can all safely stop supporting it.

  16. 16

    “You should start by making your code as correct as possible, then provide exceptions for those that need it.”

    Spot on.

  17. 17

    Nice Article :)

    Some time I found cross browser issue due to bad html markup write by designer. If you write correct markup you never found any cross browser issue.

  18. 18

    Vitaly Friedman (Smashing Magazine)

    June 7, 2010 5:01 am

    To be honest, I don’t believe this is true. I have seen many corporate environments in which IE6 is dominating with over 40% of usage. It depends on the setting in which your website will be used. I don’t think we can trust “global” statistics, it doesn’t really help us, unless we are talking about a global project that is tartgeted at global audience.

  19. 19

    I agree with some points made above; you should code to standards, not for browsers.

    Starting with IE6 and then working up is stupid in my opinion. I work in a corporate environment and at least 70% of our users are still on IE6, but I still design in modern browsers and work back. Even in this corporate environment, I still use cutting edge CSS and HTML5; it’s presentable in IE, but much nicer in a modern browser.

    This still gives you cross-browser compatibility, but also futureproofs your website.

    Browsers like Firefox, Safari, Chrome and Opera (and IE9) are getting more and more similar in the way they render sites. Why ignore this fact and code for the outliers? It just doesn’t make sense to me.

  20. 20

    With Firebug Lite you can use Firebug in IE browsers.

    I totally agree with:
    a near-exact cross-browser experience is attainable in many cases

    It’s absolutely true that when you know where to look for, many if not all designs can be made presentable by IE6.

    IE5, now that was hell. People have been making beautiful websites for years, even when IE6 was a modern browser. If webdesigns change so older browsers can’t present them, the problem is not the older browser, it’s in the new designs.

    Much hatred and dropped support for IE6 stems not from technological impossibilities, browser market shifts and quirks. It stems from inaptitude at designing and developing solid webpages.

    Starting with IE6 on positioning the main page structures saves me time. If a page works in IE6 and not in modern browsers, you are still doing it wrong.

    Progressive enhancement is the prettier cousin of graceful degredation. Progressive enhance your designs from IE6, don’t degrade your designs to work with IE6. An IE exception is rarely neccessary when enhancing designs. When degrading designs there is too much reliance on IE exceptions.

    Yes, you should still code properly and semantically, and not code for browsers. But when you are adding IE exceptions you are essentially doing exactly that!

    An IE6 template doesn’t automatically mean an unsemantical document rife with exceptions and browser specific code. Only if you have many troubles producing a solid IE6 template, will you associate an IE6 template with browser dependant code.


↑ Back to top