October 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.

Adventures in CSS: Stretchy Frame

One of the surprising CSS challenges for Windows Marketplace was stretching the spiffy "glass" frame to fit the content.  The visual design of the site is intended to suggest Windows Vista: a glassy frame in the center of the page around the content, yummy background gradients filling to the width of the browser, even the grassy texture behind the footer.   Despite the visual sophistication of such a design, it should be easy to layout, right?  I mean, with tables I could just slice those images up and make the pieces the background for various cells...

It sure seemed easier to do a table layout but doing so would have put a stake through the heart of the semantic web hopes for the website.  So we tapped CSS guru Robert Biggs for some help with this and other CSS challenges for the site.  Here's the technical breakdown of the stretchy frame problem, and how Robert solved it.

Requirements:

  • Vista-like glassy effects in IE6, IE7, FireFox 1.5+
  • Scales vertically to the content.  (Scaling horizontally was not a requirement)
  • Looks good on monitors with high resolution or wide aspect ratios.

Design:

The design called for two gradient background fills: one at the top and another at the bottom.  A fixed-width frame is centered on top of the gradients, which stretch for the width of the browser.  On high resolution monitors, instead of have the web content parked in the left side of the browser with a whole bunch of white space on the right, the browser frame is filled.  It looks really nice. 

As the frame stretches vertically, the white background between the two gradients increases.  The sides of the glass frame stretch over the white region as well, of course.

     

One constraint we needed to decide up front was the minimum height of the content region (the white region in the picture above): 700px.  This ensured the gradients would never collide.    Robert implemented the graphics to make both gradients blend to the center color.  In markup, he nested two <div> tags just inside the body.  He attached the top gradient image to the outer div as a background image, and the bottom gradient in the inner div as a background image.  This permitted the page to scale vertically as long as needed. 

Here's the CSS and markup -- it's pretty simple:

#bodyBackground { background-image: url(%img%/frame_elements/bkgd-gradient-top.gif); background-repeat: repeat-x; background-position: top left; }

#main { background-image: url(%img%/frame_elements/bkgd-gradient-bottom.gif); background-repeat: repeat-x; background-position: bottom left; }

#footerBackground { background-image: url(%img%/frame_elements/footer-bkgd.jpg); background-repeat: no-repeat; background-position: top left; }

</head>

<body>

<div id="bodyBackground"> 

    <div id="main">

        <div id="header">
          <!-- branding, menus, search -->
        </div>

        <div id="bframe">
          <!-- content region -->
        </div>

        <div id="footer">
          <!-- bottom search -->

          <div id="footerBackground">
              <!-- links -->
          </div>
        </div>

    </div>

</div>

</body>

 

The last challenge for the stretchy frame was the grassy texture behing the footer.   This texture is a background picture for the "footerBackground" div nested in the "footer" div (outlined in blue in the picture below).   Since the page sizes itself to the content, including footer content, this div is always at the bottom of the page.  The trick of pinning the bottom gradient to the bottom of the "main" div ensures that the gradient and image always line up perfectly.

 

 

Adventures in CSS: Windows Marketplace 2006

Often when you make the "sequel" to an existing application, several of the requirements boil down to fixing what didn't work well in V1.  For the original Windows Marketplace, one of the largest pain points was the lack of editorial control over just about everything: layout, style, content -- pretty much anything needed to keep the site fresh and compelling. 

So it's no surprise that one of the key requirements for the latest version of Windows Marketplace was lots of editorial control over just those things: layout, style, content, navigation, A/B testing, tracking, and all the other knobs the editorial staff needs to turn.  We made the call (some might say the leap of faith) to rely on CSS positioning for the core elements of the site, as well as CSS styles for much of the behavior of the site.  The content management system would emit only semantic markup; CSS would do the rest.

We had to learn quite a few CSS tricks to pull this off, but in the end using CSS has satisfied the editorial flexibility requirement with flying colors.

 

Home page with CSS:

Same page without CSS:

Source snippet (semantic menus):