Friday 28 December 2007

Best Bets for Browser Bug Bashing

One of the most frustrating, time consuming and challenging aspects of managing cross-browser rendering of CSS is dealing with bugs along with incomplete implementations. Examining helpful resources such as position is everything and QuirksMode, it becomes profoundly clear that today’s front end web designer and developer must be pretty adept at dealing with this core problem.

I call it a core problem because of course, interoperability is a problem the Web was meant to solve! Yet, the disparities in Web browsers have in fact caused the greatest accessibility challenge to the Web we as its authors must face, and conquer.

Fortunately, there are some proven ways to deal with cross-browser challenges. We can use hacks, which of course are controversial in their own right due in large part to how difficult they are to maintain and how often they are based on invalid markup or parsing errors (* html anyone?).

We can use conditional comments for managing IE versions. CC’s are in my opinion the cleanest way to manage IE issues on a case by case basis, but they too are controversial. An HTML comment was never intended to contain a conditional statement, so a CC is essentially a hack. Furthermore, it’s an IE-specific solution, so that in and of itself smells a little funny to the purist nose.

Another approach involves using JavaScript to “correct” browser behaviors, such as we find with Dean Edwards’ IE7 Scripts.

What ends up happening, as we all know, is that we use a combination of these techniques where necessary to address our browser base.

So we have the techniques: Three primary ways we approach bug bashing and implementation problems. What’s missing isn’t our knowledge, but a conventional method. If we had a step-by-step procedural to walk ourselves through, that could be very helpful. Clearly, what works for one site isn’t necessarily going to apply to another, but some guidelines to help each other manage this very murky, very challenging problem would certainly be of benefit.

My intuition and experience suggest that the most effective way to manage bugs is to kill them where they live. That means having a clear workflow from the earliest stages of authoring to manage browser issues regarding CSS. Surely many folks will have created such workflows, perhaps even unaware that you’ve done so, as it’s just become part of your process.

Think about how you work and if you could take a moment to share your best bets for managing cross-browser CSS design, we can together examine the least time-consuming, most efficient and most solid method by which to bash those bad, bad bugs.

Filed under:   general
Posted by:   Molly | 12:26 | Comments (44)

Comments (44)

  1. “the most effective way to manage bugs is to kill them where they live”

    I couldn’t have said it better myself. Since the bugs clearly live in the browsers, the workflow should be something like this:

    1) Recognize bug.
    2) Create a testcase that shows the bug and is as small as possible (1-20 lines of code).
    3) Report the bug along with the testcase to the browser manufacturer.
    4) Work around the bug and comment the workaround with the latest known browsers in which the bug exists and in which it has been fixed.
    5) Phase the workaround out as the buggy browsers become less used.

    Unfortunately with some browsers this workflow hits a dead end at #3.

  2. If I encounter a bug it means I have already tried several other ways to solve the same puzzle. To me it is a bug when no alternative route involving ‘valid’ CSS proves fruitful.

    To counter the bug I move the ‘targeted’ CSS to a separate stylesheet that I always import at the very end. I make sure the fix is only and exclusively valid in that one particular browser, otherwise I won’t apply it (it might hurt with the upgrade of whatever other browser at whatever moment in the future, and we don’t like that.)

    Some browsers I just don’t fix, like older versions of Opera. I’m pretty sure that Opera users do upgrade. Trying to make it right in every conceivable browser is not worth the effort. The bug must just not be so bad that the paeg becomes unusable, otherwise I would try if I can serve up just plain HTML.

  3. I think the IF IE method is the best way to attack the problem. Usually 90% of the time it’s IE that we have to work around. I use IE specific stylesheets wrapped in the IF IE statments. Then in my main stylesheet I place a CSS comment next to any rules or selectors that have a IF IE statment so I can reference back to the seperate stylesheets if I make changes.

    The #IERoot method mentioned on “position is everything” sounds interesting to me rather than using the seperate stylesheets, all IF IE code could be kept in one stylesheet. The only reason I don’t use that method is because it just seems uglier to me in the markup and all non-ie browser end up downloading the bloated stylesheet with code written for both browsers when my method only does for IE browsers.

    The star hack was a horrible approach back in the day. The IF IE approach is at least advocated by Microsoft. It’s sort of funny that it even exists. It sort of says, we don’t have enough time to fix all the bugs so we’re just going to give you a work around to the problem until we do. Regardless they have obviously listened to all the MS bashers on the blogs with IE8 and are fixing most of the rendering problems.

  4. 1. Level the playing field, e.g. the Meyer CSS Reset or equivalent.

    2. Keep it simple and stupid, e.g. browser delivered content is more about communication rather than design.

    3. Don’t sweat the small stuff, e.g. minor design/css inconsistencies between major browsers, who cares and who notices.

    4. Support only modern browsers, e.g. this does not include support for IE6 and below and includes support for the most current version of the Flash player. Security supersedes temporary user inconvenience for an upgrade/update.

  5. I think that thacker is on the right track. Here’s a few extensions to his list that I follow:

    1. Write clean, semantic markup. Many issues that appear to be CSS can be fixed with better markup.

    2. Try avoid any branching. I almost never uses hacks or conditionals. It’s better to make a few design concessions to keep a more maintainable site or app.

    3. Create designs that don’t need to be pixel perfect. This makes it more likely that your layouts will degrade more elegantly. Also, if you get into a state where every element has to be pixel perfect any change is going to be a hassle.

    4. Don’t be afraid of dropping legacy support. IE7 and Firefox are free, don’t be afraid to “encourage” your users to upgrade.

  6. @Ian and @thacker – I’d love to upgrade to the ‘free’ IE7. It will only cost me about $750 to upgrade to Windows Server 2003 from Win2k Advanced Server.

    I do agree supporting old browsers is a waste of time. But until the percentage of IE6 users drops below 10% (it is currently about 50%) or so its not practical to ignore it completely. I will ignore IE 5.x and below, Firefox 1.x and below, Opera 8 and below, etc.

    As to bug bashing, I am beginning to lean toward using conditional comments and separate style sheets for IE versions. It seems to me to be a cleaner, easier way to manage, maintain and upgrade any necessary IE specific CSS.

  7. Oh, workflow!!!

    I build a page using clean semantic HTML and CSS that works in FireFox 2 and Opera 9. I then check to see the carnage wrought by IE6/7 and add fixes where necessary.

  8. Agreed with Rick that IE6, while it sucks, is still ‘modern’ by the definition of most of the agency QA departments I’ve worked with: current release version and one version back.

    Also agreed that with a well structured reset (mine is a combination of Meyer’s, YUI, and some of my own injections), semantic/clean markup, and thoughtful organization, browser bugs can be kept to a minimum.

    I can’t remember the last *bug*, or even visual inconsistency (save the fact that PC browsers render text like garbage) that hassled me. I suppose that over time you start to anticipate the problems and, as Ian suggested, design for them and/or work with them.

    As such, my most-favorite’d tweet ever:
    “internet explorer and I are like dancing partners, I can totally anticipate that fickle bitch’s moves”

  9. Good timing! I’m currently working on an update to my IE7 scripts. The aim with the new version is that the script will upgrade IE5/6 to be compatible with the actual IE7 browser. When I first wrote the scripts there was no IE7 browser so I was shooting at an imaginary target.

  10. I’ve come to the perspective that conditional comments are the cleanest and easiest ways. But that being said they really don’t contain much. The worst thing someone could do is just hit the conditional IE CSS file every time they need a little extra padding. I tend to only use that file as a last resort as it should be.

    To someone learning CSS I can see the temptation of making huge IE specific stylesheets… just my 2 cents. πŸ™‚

  11. 1: find the right bugs – and make sure they are real browser-bugs and not some of the more ordinary “designer-bugs”, and kill them on sight.

    2: not bother about minor differences as long as it works and looks ok, and the client don’t complain.

    I use the ‘@import media bug’ hack to feed IE/win (all present versions) an extra stylesheet – when necessary. This hack is also a safe way to feed non-IE browsers with styles IE/win should rather not see.

    It is also important to play around with bug-finding and bug-killing in a controlled environment – preferably ones own site, so there are no unknown bugs and solutions that can hamper and delay work on sites for paying clients. Time is money.

  12. My approach…

    1) Write valid XHTML, or as near as your system can produce since not all of us have 100% control over output. I’ve seen a lot of people trying to “bugfix CSS” when actually they have markup problems. Similarly, for “really weird bugs” run the CSS validator over your work before getting too deeply involved, to make sure it’s not a syntax mistake.

    2) Build in Opera, also checking in Firefox, IE7 and Safari as you go. If you can get Opera and Firefox to agree you’re generally on the right track.

    3) When you’re happy, or periodically through big builds, add IE6 and IE7 hacks to fix the problems.

    I am one of those purists that does not use conditional comments and probably won’t until the proprietary hack gets moved into the CSS (ie. never). There is just no way a large team is going to consistently remember to go check rules in a separate stylesheet during maintenance. The hack needs to be next to the proper CSS.

    4) In thankfully few cases, you will also hit a bug in Opera, Firefox or Safari. They can actually be just as frustrating to fix since there aren’t any reliable hacks to target them. Usually you have to track down a workaround or weed out an obscure error you’ve made somewhere along the line. But, as I said, these cases are rare compared with IE6/7 where you know you’ll get at least one bug basically 99.9% of the time.

    As for support levels… Basic rule: current version of Opera, FF, IE; plus IE-1 (currently that means IE6; although I wonder if we’ll end up supporting 6, 7 and 8 all at once); plus whatever version of Safari happens to be on whatever Mac I can access (bundled versions? thanks for nothing, Apple).

  13. My approach is to build or find a single base template that works in all major browsers, and recycle it for every new website I create. As soon as I encounter a new bug I can apply the workaround to my base template and I’ll never have to worry again.

    In my experience, the most effective way to diagnose a bug is to create a test case and play with it using Firebug or IE’s [frustrating] Developer Toolbar. Once you have a better understanding of the cause you can search the net for a solution and see if it works in your template. If not, then you may have to change the HTML structure and CSS to avoid the bug all together.

    Otherwise if you’re short on time there’s always conditional comments, but the more you target one browser the harder it gets to remain consistent.

  14. Here’s what I tell everyone on the various forums I frequent (SitePoint, Digital Point, IWDN,, ScriptingSite, WebsitePublisher, and so forth).

    Write clean, minimal, semantic and valid markup, and make sure the DOCTYPE you choose matches the syntax of the code you’re writing. Lists are not just for menus. Any time you have a list of content, including links, use a list. I cannot believe how many times I’ll see a list used for the main menu, only to see a DIV container holding link after link after link elsewhere in the page (usually in the footer). I can also say the same thing about form controls as well. Is that input a paragraph? Then don’t mark it up as such.

    Always separate your structural components of the Web page. Does that menu belong inside the masthead DIV? No, of course not. So get it out of there! Use what I consider to be the proper source code order for pages: header/masthead, menu(s), content, sidebar(s), footer. Using a non-semantic DIV inside the content area as a “wrapper” for that DIV’s contents works wonders as a CSS hook, and makes floating columns a breeze, especially when adding negative margins to the mix.

    Reset all your margins and padding on non-form control elements. Set the font size of the entire page to a percentage, and then set the leading (line-height) accordingly. Surprisingly, 85%/1.4 (or 1.5) works wonders, especially for those with larger .dpi settings on their computers. Then set the containers’ widths to use the EM measurement unit, and set the font used for the text to “Lucida Console” to (practically) ensure that whatever font your user has (as long as it’s not one of those freaky fonts that was downloaded from some obscure font gallery site) will fit if it gets used instead of the preset defaults without breaking the layout.

    Remember what I said about placing a wrapper DIV inside the content DIV? Float that content DIV, give it a width of 100%, and set negative left and right margins equal to the widths of the columns that will be alongside it. Then set the wrapper DIV’s margins to be equal to the negative margins used. It still surprises me to this day how many bugs are avoided by doing this. If you use a container DIV around the entire page (with the DIV given an ID), you can even emulate equal height columns without background images – if you know how to set it up properly.

    When writing your stylesheet, code to the standards, but check against the rendering engines. Note I said rendering engines, not browsers. IE 6/7, Firefox, Opera, and Safari are pretty much all you need, though I’d also throw in Kmeleon 1.0 and/or Netscape 8 to cater to Linux users who are stuck with Gecko based browsers using the Firefox 1.0.3 build as their baseline. And then, check incrementally as you go along. Don’t wait until you’re done. Style the header, validate and then check against all the engines. Menu? Same thing. Content block? Ditto. Sidebars? You guessed it. And so on and so on and so forth.

    Build the overall layout, then work your way in. And don’t forget to keep checking against the four major rendering engines as you go along either. What you’re doing is debugging as you go along, rather than waiting until the very end. And if you do find something, don’t dive for a hack. Just see if there’s something you can do to get that browser back in shape. IE double margin bug? Just add display: inline; to the rule. Firefox not letting you click onl links? Position: relative; usually takes care of that (and can sometimes get Opera to tow the party line as well). Speaking of Opera. Is it failing to clear a float? Just replace clear: (direction); with float: none.

    And when you do make such a change, be sure to revalidate your CSS and re-check in each browser you use (the list I gave earlier is what I use).

    Oh, and use a Strict DOCTYPE. It really forces you to abandon the use of the deprecated (read: obsolete) HTML attributes that one shouldn’t be using in the first place.

    Last but not least, if you truely get stuck, don’t dive for the hacks just yet. Ask for help instead. Sometimes all it takes is a fresh set of eyeballs to spot the root cause of the problem.

    PS: Molly, you probably have no idea how much flak I catch for even speaking such heresy in a public venu as what I typed out here. πŸ˜‰

  15. Timely post Molly – I was just thinking the other day, with the advent of another version of IE looming on the horizon, what a nuisance it is to need so many hacks to cater for the growing diversity of browser versions and browser bugs out there.

    Keeping up with all of it can seem like a full-time challenge that can distract from the actual art of designing something good in the first place. I’m afraid my workflow for handling such bugs is a bit varied, and is only on a need-to-know (or need-use-with-that-design/situation) basis. The more elaborate a design becomes, the more likely it will hit bugs across those various browsers/browser versions – so I think it’s important to master the bug-fixing for simple, more graceful layouts first, establishing how to resolve bugs at that stage before moving on to the elaborate stuff later on.

    I agree though – it’s the diversity of solutions that can seem so awkward, and some ‘unified’ method for bug-fixing across multiple browsers is sorely needed.

  16. @all: good ideas so far. I agree that reset is important, but I’m not convinced that there’s a “one-size fits all” solution to reset. Every company/situation is going to be different. The same is true with managing CC’s.

    This is why I’m examining method beyond technique. It’s not a quest to figure out what to apply, but how to apply it and in what scenarios.

    @dean: Ohhh. IE7 scripts changes? This is big/interesting news. Care to share more about what you’ll be doing? I shudder to think that you’ll probably be breaking stuff just to match IE7. Yikes! πŸ™‚

  17. @Molly:

    I just started the rewrite a few days ago. The idea with the new version is that the script brings IE5/6 in line with the “real” IE7. That means that I will have to remove a lot of the fixes that were in the original version. I’m going to move all of the surplus fixes to another script: “IE8”. The new version will be smaller, faster and centrally hosted on googlecode (cached and gzipped). The overall experience I hope will be more seamless than the original incantation. I’ll blog about it sometime soon because I want some feedback before I set this in stone.

  18. @dean:

    I don’t know what inspired the rewrite, but woah very timely. And good on you for wanting feedback. Are you going to work on it on your own or open via wiki, etc?

    I’m reviewing a boatload of tests for the public, for Microsoft, for the W3C about how to manage IE6 > 7 > IE8.

    My interest is particularly in error handling and figuring out baseline behaviors. I imagine anything you have found between IE7 as you imagined it via specs versus the way it was implemented is golden info.

    I want to start a wiki where tests for CSS can be posted along with JS.

    It’s the one shot I believe in.


  19. Dan Schulz stated:

    […]have no idea how much flak I catch for even speaking such heresy in a public venu as what I typed out here.


    Why do you catch grief for such a thing? More importantly, what type of specific objections do you receive?

    Thank you.

    Molly Holzschlag stated:

    I want to start a wiki where tests for CSS can be posted along with JS.


    Is this being done as a joint venture with Microsoft and using some of their resources, e.g. funding, staff and servers? Will it be incorporated and/or used as a prelude to their intended bug reporting system?

    Thank you.

  20. thacker, I tend to get the “holier than thou” attitude from people who’s knowledge is at least 10 years out of date (at best) and/or who think that HTML and CSS are simple toys rather than actual structural and presentational markup languages with rules (such as semantics) that have to be obeyed. Especially from the SEO con artists and frauds who think that they’re God’s gift to #1 rankings in the various SERPs.

    Right now I’m fighting with someone at SitePoint over proper source code order who’s demanding I provide outside 3rd party verification that a “content first SEO” approach will not only potentially neuter his search engine ranking, but also inhibit the usability and acceessibility of his Web sites as well.

    Sometimes on ICQ and AIM I’ll get chewed out for telling people to use actual images for their logos (using CSS to serve header backgrounds when approrpriate) rather than H1 headings, since the H1 element is the topmost heading of the page (which I tell people mans it’s “page” not “site” centric – and is best used as a page title).

    Usually though the response to my rebuttals tends to be “but I learned it from ________ so it must be true.”

    Oh, and Molly, you might be interested to know that SitePoint has a HTML, CSS and JavaScript reference under development. Currently, the CSS reference is available to SitePoint forum members who registered before 1 December 2007, though that won’t matter much in a day or so. πŸ˜‰

    But if you want to go ahead with it, I have a site under development which could be used to host the wiki for you if you’re interested. You have my email address should you want to talk about this further in private.

  21. No problem. And please, just call me Dan. πŸ™‚

  22. I think that when following a standard you incur in a lot of problems, then you should not call that a standard and use something else until a standard shows up.

  23. Michele, the problem isn’t that the standard doens’t work, it’s that a lot of people either don’t know, don’t know better, or just don’t care, and write broken code anyway. HTML and CSS are forgiving, but they’re not so forgiving that they’ll bend over backwards to let you do whatever you want to do, rather than what they were designed to do. Browsers on the other hand…

  24. @dan I have bookmarked this page and will try your suggestions.
    I have struggled a lot with page generation in XML/XSL and what I came up with was a framework of sorts with unit tests and everything a programmer (Java or C++ I mean) would expect.
    I managed to keep the content, the html, the scripts and the style for each page component in a single place. I had a structure for unit testing each transformation to check the result of each rectangle separately. It was also xhtml 1.1 Strict.
    All in all I think it was too much work for the expected result.
    I think that people using a text editor for web creation are like those who program in Assembler: too much detail, too much flexibility no defaults, no components that just work and behave.
    I had to make a layout for a customer lately even if my main job is programming applications. I studied carefully the layouts on position is everything, but I found out that there is too much code based on bugs in some other code. I hate making my code uglier to be fair to buggy code elsewere.
    The second point I found was that it does not “just work” you can still break a layout with code you add. This means that there is no sensible delegation of responsibility at each layer of code and every piece tries to do too much rediscussing everything from the start each tim.
    All in all I think we need some good practice to html design, like isolation, delegation, unit tests. We also need more powerful tools.
    When I had a phone call asking me to change completely a layout half an hour before a meeting I used tables with no regrets and had the right grid in no time. Ok, I will rewrite it before going in production, but any meeting breaks the layout anyway,

  25. Pingback: JBVoices » How was it for you?

  26. Milo is totally correct with the list of 5 steps to fix bugs.

    But the final comment about “some browsers” is inaccurate because only one vendor refuses to play fair.

    Microsoft Internet Explorer

    MS used to have a bug tracker called IE Feedback. It wasn’t the best system by far, but at least it existed. Now, there is nothing.

    Web Bug Track (see here)

    Is now one of the premier resources for tracking bugs in IE, and getting a handle on the workarounds if there are any.

    What is wrong, is that the need for a site like this even exists. If MS got their stuff together, we would have full bug tracking on a Microsoft site.

  27. @Rick – The upgrade to Firefox is always free! – Only upgrading IE costs money based on your O.S.

    Not only is it free, it will improve your Web Browsing experience 10 fold.

    You couldn’t pay me to use IE6. Seriously, I wouldn’t even accept a Job offer where the company didn’t allow Firefox. Period.

  28. We develop a solid base with valid XHTML on a reliable browser (Firefox), then we take a look at Internet Explorer and other browsers from Yahoo’s Graded Browser Support matrix to fix the bugs. We fix bugs early in small iteration loops so that they do not pile up to larger inconsistencies.

  29. I have a dumb idea… How about instead of working around IE’s stupidity, everyone completely abandons IE and forces Microsoft to build a browser that actually works correctly. Saves everyone time.

    Preload a browser sniffer page, and if it comes up with IE, you’re forced to click on a big Firefox button and download it instead.

  30. IE6 lurks like a mugger in a back alley as I make my way into each new project. If you let it, you will lose your wallet, your watch, and your carefully crafted markup. The way I deal with IE6 is to invite it to the party right from the get-go. Each step of the way the page and associated markup is tested against Safari, Firefox (windows & mac,) IE7, and IE6. If something doesn’t work, it’s fixed then and there before I move on. For certain, the skeleton of the site (navigation, basic layout, etc.) is going to be bulletproof in all browsers before adding any real page content.

    My preferred method of dealing with IE6 issues, and some IE7, is to put them in separate stylesheets using conditional statements tucked in the head of each page. If I’m really lucky, when I get to the end of the project, those extra stylesheets will be blank, or at least real short because of the testing that was done along the way.

    Anyway, that’s my way of handling the problem of IE6 incompatibilities. I really just wish it would go away. Oh, and I don’t worry at all about anything less than version 6. Period. You’ve got to draw the line somewhere.

  31. I have a feeling that trying to implement meta tags in the of an webpage to try and make it compliant with IE7 XHTML standards can sometimes confuse the pre-load of any subsequent CSS files, so they do not get a chance to load even with a stock standard installation of IE7. Now I have no strong evidence of this, but I have seen this happened to me while I was developing my website. By placing a line such as stopped the load of the CSS file. Reverting to just plain resolved it. Now this probably doesn’t make sense but I reckon those sites that have a lot of meta tags or try to enforce XHTML are always the sites that “SOMETIMES” don’t load the CSS properly and you need to Refresh the page (F5), sometimes a couple of times before IE7 decides its going to load the CSS. Sadly Molly, your site is currently one site that behaves like this.

    Admittedly I probably have a rubbishy computer (2.8 gig Presscot with 1 Gig DDR) and hasn’t had its Internet cache purged or its O/S revamped (XP SP2). And my Registry is cluttered with useless data. A rebuild could do the trick but I not going to do this simply to test that theory.

  32. The (html) were deleted in my last post. It was the (html xmlns=”” lang=”en”) that caused the problem. Just using (html) solved it. Yes that does seem ODD?

  33. You may ignore my previous post, more or less as another website that doesn’t load the CSS files the first time is using the more standard form of (html) [except the

  34. very nice. thanks molly.

Upcoming Travels