Friday, October 20, 2006 - Posts

Adventures in CSS: Authoring for Multiple Browsers

The CSS for Windows Marketplace 2.0 was written to target the three big marketshare browsers: IE6, IE7, and FireFox 1.5.  We've found it works pretty well in other browsers (like Opera) even though we didn't specifically target them.  That's probably due to compliance to standards for XHTML and CSS, go standards!

Rather than applying browser-specific styles via hacks or script, we used IE's conditional comment feature.  Alan blogged a little bit about the technique during the project, but I wanted to drill deeper into the Windows Marketplace implementation since it's such a powerful approach to cross browser support.  I like it a lot over the alternatives, since it's hack-free and javascript-free -- hats off again to Robert Biggs for setting us on this path.  Conditional comments also promote encapsulation which is a wonderful way to help the maintainability of the application.  Hacks, on the other hand, are horrible for maintainability: it's nearly impossible to find folks with the requisite encyclopedic knowledge of the arcane CSS hack-scape, let alone those with enough javascript and front end UI dev experience to debug whether a problem is code vs. script vs. CSS.

 

Approach

Of the three browsers we wanted to support, only IE6 and IE7 knew how to use conditional comments.  This fact, coupled with the fact that IE is less standards-compliant than FireFox, dictated our approach:

  • create the baseline CSS for FireFox first
  • use IE conditional comments to include "override" versions of style sheets for IE6 and IE7 as needed

We modularized this a bit further and broke the style sheets up by functionality.  So the style sheets for the frame -- frame.css, frame-ie6.css, and frame-ie7.css -- are included on all pages whereas the styles for wish list feature are included only on Wishlist.aspx.  The site has 40 or so style sheets altogether.  That may seem like a lot of different style sheets to manage but knowing which one to touch when you need to make a change is surprisingly intuitive.

 

Example

Here's a sample of the style sheet links from the search results page.  The first group (shown in blue) are the FireFox styles, many of which also work in IE.  The next sections are commented; FireFox ignores them completely.  The "lte IE 6" section is included by versions of IE "less than or equal to" version 6.  In practice this includes IE 5 (the first version to recognize conditional comments) plus IE 6.

The "gte IE 7" section is included by version of IE "greater than or equal to" version 7.  There's a tiny leap of faith here that versions of IE will become ever more standards compliant in the future; sure hope we're right!

In practice, we found that IE6 needed a lot of tweaks from the standard CSS from the site, whereas IE7 needed very few.

<link rel="stylesheet" href="/mapasset.aspx?file=css/frame.css" type="text/css" />
<link rel="stylesheet" href="/mapasset.aspx?file=css/layoutResults.css" type="text/css" />
<link rel="stylesheet" href="/mapasset.aspx?file=css/searchResults.css" type="text/css" />
<link rel="stylesheet" href="/mapasset.aspx?file=css/globalLayouts.css" type="text/css" />
<link rel="stylesheet" href="/mapasset.aspx?file=css/tooltip.css" type="text/css" />
<link rel="stylesheet" href="/mapasset.aspx?file=css/modules.css" type="text/css" />
<script type="text/javascript" src="/scripts/winmp.js"></script>

<!--[if lte IE 6]>
    <link rel="stylesheet" href="/mapasset.aspx?file=css/frame-ie6.css" type="text/css" />
    <link rel="stylesheet" href="/mapasset.aspx?file=css/tab-ie6.css" type="text/css" />
    <link rel="stylesheet" href="/mapasset.aspx?file=css/globalLayouts-ie6.css" type="text/css" />
    <link rel="stylesheet" href="/mapasset.aspx?file=css/searchResults-ie6.css" type="text/css" />
    <link rel="stylesheet" href="/mapasset.aspx?file=css/tooltip-ie6.css" type="text/css" />
    <link rel="stylesheet" href="/mapasset.aspx?file=css/modules-ie6.css" type="text/css" />
    <script src="/scripts/ie6submenu.js" type="text/javascript"></script>
<![endif]-->

<!--[if gte IE 7]>
    <link rel="stylesheet" href="/mapasset.aspx?file=css/frame-ie7.css" type="text/css" />
    <link rel="stylesheet" href="/mapasset.aspx?file=css/tab-ie7.css" type="text/css" />
    <link rel="stylesheet" href="/mapasset.aspx?file=css/globalLayouts-ie7.css" type="text/css" />
    <link rel="stylesheet" href="/mapasset.aspx?file=css/searchResults-ie7.css" type="text/css" />
    <link rel="stylesheet" href="/mapasset.aspx?file=css/tooltip-ie7.css" type="text/css" />
    <link rel="stylesheet" href="/mapasset.aspx?file=css/modules-ie7.css" type="text/css" />
<![endif]-->

 

You may have noticed the mapasset.aspx target of the style sheet link above; that was required to set the paths of CSS, script and image assets via configuration per deployment.  I'll blog about that in detail sometime.  What the browser sees is just a standard CSS file, and it caches it accordingly.