Supporting Legacy Browsers, or Not

Posted December 6th, 2006 by Mike Cherim

When I started using computers in the early 90s I used to complain every time Microsoft or some software manufacturer came up with a new version of whatever it was of theirs I was using. My gripe was that I had finally gotten a good handle on the old product and didn’t really want to upgrade and re-live an often painful learning curve. I was content. But, as support waned, I relented and did as was expected of me — what I was essentially forced to do: I upgraded. As software improved and I became more computer savvy these transitions got easier. Usually, after the fact, I was happy I stayed current. That was me as a user. Now, as a web developer, I find myself on the other side of that very situation.

Now I create things that are best delivered to those who stay current. To those who have the best connections, cutting edge hardware, and the latest software. But, unlike the software makers I used to grumble about, the ones who cut the support ties in what I considered too short a period of time, I find myself catering to the needs of those with old equipment. As an accessible web developer I find that this is a necessary evil. If you’re a web developer you may find yourself in the same situation. But it’s not necessarily something I want to do. If I had my way I’d stop supporting old browsers immediately. How many of you feel the same way? Stand up or raise your hand if you’re ready to stop supporting Internet Explorer (IE) version 6 right now? I know I am, but obviously the rest of the world isn’t ready for that. There are and will be a lot of IE 6 users for many years to come.

Does this mean we’re mired in the muck of legacy browser support forever? Well, as an accessible web developer I have sort of made a commitment to be in this situation. So what do I do? Do I say screw it and move on leaving those with older equipment in the dust? Send them a cold message of “Upgrade now or piss off” or something nasty like that (e.g. “Your browser doesn’t support frames” or “You need JavaScript to view this page”). No! I cannot do that. I will not do that; it flies in the face of web accessibility — plus it’s disrespectful to some web users.

So, I ask again, what do I do? I’ll be damned if I going to drive myself crazy trying to support IE version 5 forever for example? It’s a thorn in my side at best. IE 6 support is bad enough. Do I make a ton of style sheets and a bevy of conditional comments, often just for one user? And what about older versions of other browsers that don’t offer Microsoft’s clever conditional comment support. Do I offer the appropriate style sheets based on the needs of myriad browsers by way of using some scripting? Well, that is an option, but I still have to generate working styles for all those relics! There must be a simpler method.

I was recently discussing this with Mel Pedley, who also wonders where to draw the line. We’re not about to revert to using unwieldy tables for layout. We’re accessible web developers so we’re not going to give up either. I told Mel I was working on a usable solution, but first the goals needed to be identified. So what are the goals:

  1. The content itself must be accessible to all users.
  2. Styling support for older browsers isn’t necessary.

Wow, that’s a short list that simplifies matters somewhat. Now it boils down to how to make it happen and meet the goals. Mel and I both agree that it’s not that important to deliver styles to older equipment and that the users of such equipment probably only expect to get the content anyway — they should be satisfied with that. If they’re not satisfied with that and demand all the goodies that go into a pretty, modern web site, then the really need to upgrade their equipment. End of story. At this point I really have to say: It’s not my problem. I have to consign myself to content delivery. I’ll be damn if I’m going to add 80 hours to any given project to make it work in circa 1990s steam-powered browsers used by a number of people I can count on one hand. I refuse to go insane even trying. I also refuse to make such basic, boring designs that work in anything at the expense of good looks, my reputation as a designer, and the wants and needs of my clients. Let’s face it, boring designs don’t sell.

Enter server-side scripting. I will offer some PHP to make this so and save my sanity, but feel free to use whatever server-side language you like. All will support this solution, it’s just a matter of syntax and server support. The first thing that needs to be done is determine what I will stop supporting. What legacy browsers am I going to give content to yet not style? What browser need to be on the list? What browsers cause grief?

Here’s a short list:

  • Internet Explorer 5.5 and older including IE 5.23 for Mac (I’d love to add 6 but not yet).
  • Netscape 7.2 and older.
  • Opera 7.54ul/7.5 and older. (Note: See comments)

Now that I know what I’m not going to kill myself over, I can write a script.

Detecting the User’s Browser

In this first part the script will determine what browser the user has then extract the case-insensitive type and version info (regardless of platform) and mark selected versions as “legacy.” This should be in a separate file called, um, browser_list.php or whatever floats your boat.


<?php
  if( $ping != "pong" ) { // Ref: Secure the include
      exit( '<h2>You cannot access this file directly!</h2>' );
}
  $users_browser = $_SERVER['HTTP_USER_AGENT'];

  if( eregi( "mozilla/4.78", $users_browser ) ||
      eregi( "netscape6/6.2.3", $users_browser ) ||
      eregi( "netscape/7.2", $users_browser ) ||
      eregi( "msie 3", $users_browser ) ||
      eregi( "msie 4.01", $users_browser ) ||
      eregi( "msie 5.01", $users_browser ) ||
      eregi( "msie 5.23", $users_browser ) ||
      eregi( "msie 5.5", $users_browser ) ||
      eregi( "opera 7.23", $users_browser ) ||
      eregi( "opera 7.54", $users_browser ) ||
      eregi( "opera 7.54ul", $users_browser ) ) {

  $browser = "legacy";
}
?>

Returning the Appropriate Style Sheet

Now, in part 2 the script will check the variable of the first part and output the appropriate content. There are surely other ways of doing this such as preg_match, maybe strstr, or possibly using an array, and I don’t know if how I did this is best; I seriously doubt it. Hopefully some commenter will enlighten me. I knowingly suck at PHP — I admit it.

Anyway, Place this part of the script in the head where you would want to place the style sheet import or link string.


<?php
  $ping = "pong";
    include_once( "browser_list.php" );
  if( $browser == "legacy" ) {
    echo( '<link rel="stylesheet" href="basic.css" type="text/css" media="screen" />' );
  } else {
    echo( '<style type="text/css" media="screen"> @import "complex.css"; </style>' );
 }
?>

That’s it, I’m done. 10 minutes instead of hours. Even though no styles at all are needed if the page is built to standards, the “basic.css” referred to above might contain some super-simple universal styles, just to make the page a little neater, like these, but this is as far as I’m going to take it:


 body {
   background-color : #fff;
   color : #333;
   padding : 5px 50px 5px 50px;
 }

 a:hover, a:focus, a:active {
   text-decoration : none;
 }

 a:focus, a:active {
   background-color : yellow;
 }

 img, a img {
   border : 0;
 }

That’s it. Doing this facilitates the creation of accessible sites to the <1% with legacy browsers without the worry, frustration, and downright aggravation of trying to make the styles work in them as well. It may very well be a sensible, liberating experience.

Once developers can confidently add IE6 to the legacy list all will be right with the world.


15 Responses to: “Supporting Legacy Browsers, or Not”

  1. John Faulds responds:
    Posted: December 7th, 2006 at 7:02 am

    I don’t test in Opera 7+ but surely it’s not that old? It’s newer than IE6 anyway.

    As for IE5, well funnily enough, it was an episode involving Accessites that has made me put more than a passing effort into IE5.x Windows & Mac since then. And I guess the plus side is that now I rarely spend more than an hour troubleshooting bugs in those browsers for most of my designs.

  2. David Zemens responds:
    Posted: December 7th, 2006 at 7:44 am

    You underestimate your PHP skills, Mike. What a terrific idea you have here.

    I must admit, being only a beginner web developer, that I have previously only tested for IE 6.0 >, FF and Opera 9.0 when designing my sites. I have no idea how they appear in the other browsers. Now I *will* know how the sites look - very basic, almost like a simple print style sheet.

    Thanks for another great article with real world implications.

  3. Martin Neczypor responds:
    Posted: December 7th, 2006 at 8:44 am

    With Internet Explorer especially, I’d say one browser version is enough of a backwards compatability (otherwise just give out an unstyled page), especially when it comes to things like CSS. With the sheer amount of windows updates that happen daily, and Internet Explorer 7 being of, I think, critical download status, it won’t be long before basically everyone has either 6 or 7. You can’t be at fault for someone using a version of a browser that was released in 1999 That’s a 7 year lag–and not worth the pain to support unless absolutely necessary (and then I think it should be a part of development fees).

  4. Kravvitz responds:
    Posted: December 8th, 2006 at 12:23 am

    I consider this to be a very bad idea. I wish I could remember where the forum thread is in which this was discussed several months ago — my Google search didn’t seem to turn locate it.

    What happens if the user-agent string is not sent, is blocked, or if someone is sending a spoofed user agent string?

    This isn’t quite as bad as the old days when sites would block access to browsers that didn’t send the right user agent string. IE still claims to be Mozilla.

    I much prefer using @import to hide CSS from older browsers.

  5. Mel Pedley responds:
    Posted: December 8th, 2006 at 7:01 am

    With regard to Kravvitz’s comments on using @import, I also wondered if it were possible to use import to hide CSS instead. The most comprehensive list I’ve found is at http://imfo.ru/csstest/css_hacks/import.php but most of the methods described are hacks that will invalidate your CSS. Of those that the CSS validator will accept (about 10), there simply isn’t the fine-tuning there to specifically target certain browsers. The best appears to be Number 8:

    @import/**/”style.css”;

    but I’m uncomfortable with using that . If it looks like a hack and smells like a hack, then despite the fact that it doesn’t trip a dumb validator, I feel it is a hack and hacks have a habit of biting back.

    The script can be easily modified to cope with situations where the user agent is blocked or not sent so that these users get the fully styled version (I’m currently looking at tweaking it to use an array with strpos on the basis that it will be faster and easier to modify).

    If the headers are spoofed, I think it would be:

    a) safe to assume that the user is doing this for good reason
    b) they’ll be happy to be sent the appropriate style sheet.

    The worst that could happen is that they’ll get a very basic page.

  6. Mel Pedley responds:
    Posted: December 8th, 2006 at 11:03 am

    How about this?

    
    <?php
      if( $ping != "pong" ) {
          exit( '<h2>You cannot access this file directly!</h2>' );
    }
    // the array to hold our list of legacy browsers
    // all entries need to be lowercase otherwise we'll have to incorporate another strtolower() call
    $oldbrowsers = array(
      "mozilla/4.78",
      "netscape6/6.2.3",
      "netscape/7.2",
      "msie 3",
      "msie 4.01",
      "msie 5.01",
      "msie 5.23",
      "msie 5.5",
      "opera 7.23",
      "opera 7.54",
      "opera 7.54ul"
    );
    
    // set up the browser variables
      $users_browser = "Unknown";
      $browser = "current";
    
    // Account for blocked or unsent headers
    if(!empty($_SERVER['HTTP_USER_AGENT'])) $users_browser = strtolower($_SERVER['HTTP_USER_AGENT']);
    
    // Test to see if the user's browser is in the legacy browsers array
    foreach($oldbrowsers as $entry) { if(strpos($users_browser,$entry) !== false)
       $browser = "legacy";
    }
    ?>
    
    

    strpos gives the fastest possible ‘needle in haystack’ check and, even with the strtolower() call on the user agent variable, should still (in theory) be faster than either eregi or preg_match.

    If you’re lucky enough to have access to PHP5, strpos can be replaced with stripos for a case-insensitive match. So:


    if(!empty($_SERVER['HTTP_USER_AGENT']))
    $users_browser = strtolower($_SERVER['HTTP_USER_AGENT']);

    will become


    if(!empty($_SERVER['HTTP_USER_AGENT']))
    $users_browser = $_SERVER['HTTP_USER_AGENT'];

    and


    foreach($oldbrowsers as $entry) {
    if(strpos($users_browser,$entry) !== false)
    $browser = "legacy";
    }

    can be amended to:


    foreach($oldbrowsers as $entry) {
    if(stripos($users_browser,$entry) !== false)
    $browser = "legacy";
    }

    Should be even faster.

    If a user agent header isn’t received, the fallback position is that the browser is ‘non-legacy’ and the user will receive fully-styled content. My concern here was whether the original script would throw up warnings on some servers if $_SERVER['HTTP_USER_AGENT'] wasn’t available.

    Right - I’m off to play with this!

  7. Spider Trax » Supporting Legacy Browsers, or Not responds:
    Posted: December 8th, 2006 at 12:40 pm

    […] Following a conversation about the problems of supplying accessible content to old (legacy) browsers Mike Cherim came up with a PHP solution that would allow developers to serve very plain content to legacy browsers but rich content to everyone else. […]

  8. Mel Pedley responds:
    Posted: December 8th, 2006 at 12:59 pm

    Re: Missing curly braces:
    Presumably because I didn’t have access to the pre tag, the script has line-wrapped! If you pull line 27 up to line 26 and line 31 to line 30, you don’t need the curly braces. Years ago, I used to programme in MUMPS (of all things) in an environment where every script/module had to be less than 2k and you learnt, very quickly, to avoid any extraneous characters. It’s a habit I still have - although I’ve learnt to ease off in order to increase readability.

    I’ve just posted a version on Spider Trax, if that helps.

  9. John Faulds responds:
    Posted: December 8th, 2006 at 7:33 pm

    Prompted by something I read on 24ways.org yesterday (they’re doing their Web Dev advent calendar again), I was thinking that even though as Kravvitz points out browser sniffing’s not necessarily that reliable a practice, you could do something similar if you were really keen to try out some of the cool CSS3 features, like multiple bg-images, that are currently only available in limited browsers.

    For instance, if you wanted to use rounded corners and if your browser’s Safari, you get a link to a different stylesheet with the multiple bg-images CSS. Of course, it would need to be a bit more complicated than that, cos ideally you’d want to replace whatever unnecessary markup or javascript that you currently use to achieve rounded corners in other browsers.

    There’s probably very few situations where you’d want to do something like that and it would probably only be something for the purists, but I can’t help thinking that there’s got to be some way to get these new CSS3 features into use if they’re ever to be widely adopted.

    Sorry if this has strayed a bit off topic.

  10. John Faulds responds:
    Posted: December 8th, 2006 at 7:34 pm

    Oops, forgot to mention that if the browser sniffing fails, then your browser still gets the default un-CSS3ed styles and markup anyway.

  11. Beast-Blog.com - The Best of the Beast in 2006 by Mike Cherim responds:
    Posted: December 29th, 2006 at 7:34 pm

    […] 2006/12: Supporting Legacy Browsers, or Not […]

Sorry. Comments are closed.




Note: This is the end of the usable page. The image(s) below are preloaded for performance only.