An easier Internet Explorer experience

ie-usage

If you didn’t already know, I’ve been a professional Front–End Web Developer for about 13 years now. In that time, I’ve seen a lot of horrible practices come and go — tables for layout, JavaScript image rollovers (for important navigation, no less), “This site looks best in Netscape 4 at 800×600”, abysmal Flash splash/loading pages with the omnipresent Skip Intro button, et cetera. One of those horrible practices, however, is still around today: Internet Explorer.

As someone who works in the real world, with real clients, I still have to build sites with IE in mind; often, from version 6 upwards. Despite the best efforts of everyone—Microsoft included—there are still some places where IE6 is the target browser. Try building a website for a China–based audience without making it IE6–proof and you’ve lost your target audience before you even launch the site. Hard to imagine in 2012, but there it is.

With that small bit of background, I’ll introduce Mark:

Mark Tweeted that just as I was glancing at my Twitter client, so I took him up on his offer. Without even seeing the site or any code, I helped him fix his problem. How? By applying a few Golden Rules.

  1. Does the HTML validate?
  2. Have you used the correct methods for cross–browser inline–block, clearing floats, etc?
  3. Are you using Conditional Comments rather than CSS hacks?

Always Validate

As soon as I asked the first question: *facepalm*. He saw a missing </div> was causing most of the problems. After fixing that, it was just a few minor fixes away from looking as it should. And this is why you should validate.

I come across this kind of thing a lot on Twitter, so I thought I’d write a few words on the process that I use, in the hope that it may help a few people have a few less sleepless nights over such stupidly basic problems. I’ll also briefly cover one of the newer things to arrive on my desk: CSS pre–processors.

Use the Available Resources

You can usually guess which areas of a site will be problematic in IE6 as you’re building it. They’ll be things like margin/padding issues, due to the browser not being able to count properly. Lots of these problems are well documented at the most excellent Position is Everything. Quite often, though, you’ll run into a whole load of float–related problems. A great way around this is to use inline–block. Yes, this isn’t natively respected by IE6, but there is a cross–browser fix that you can use:

display: -moz-inline-stack;
display: inline-block;
zoom: 1;
*display: inline;

from: http://foohack.com/2007/11/cross-browser-support-for-inline-block-styling/

That should help you get rid of some serious pain, but you may have to float some of those elements as well. First and foremost, give those floated elements a width, or IE6 will punch you in the face. Just adding a width isn’t the only step you need to take, though; that’s where the clear fix hack comes in. It’s been around for a while now, but here’s the latest version:

/* For modern browsers */
.cf:before,
.cf:after {
    content: "";
    display: table;
}

.cf:after { clear: both; }

/* For IE 6/7 (trigger hasLayout) */
.cf { zoom: 1; }

from: http://nicolasgallagher.com/micro-clearfix-hack/

If you’re already familiar with the clearfix hack, then you probably have that class littered throughout your markup. That’s pretty ugly. Almost on cue as I was thinking about writing this, Chris Stainthorpe hit me with this question:

As it’s 2012, you should be living in the now and using a CSS pre–processor, such as LESS or SASS. They’re both fairly similar, but I prefer LESS. To use the two hacks above in your LESS files, just create the following mixins:

.inline-block() {
    display: -moz-inline-stack;
    display: inline-block;
    zoom: 1;
    *display: inline;
}
.clearfix() {
    .cf:before,
    .cf:after {
        content: "";
        display: table;
    }
    .cf:after { clear: both; }
    .cf { zoom: 1; }
}

To use those mixins, it’s as simple as including them like so:

.element {
    .clearfix();
    .inline-block();
}

That will output the following in your CSS file:

.element {
    display: -moz-inline-stack;
    display: inline-block;
    zoom: 1;
    *display: inline;
}
.element:before, 
.element:after {
    display: table;
    content: "";
    zoom: 1;
    *display: inline;
}
.element:after {
    clear: both;
}

As you can see, it’s a lot nicer to just be able to add .clearfix(); into a style rule, than have to litter your markup with non–semantic .clearfix classes.

So, while using a CSS pre–processor isn’t a necessity for getting IE6 to behave nicely, I’m sure you can see it helps to make things a bit easier. The rest is just common sense: learn the basic bugs and how to write markup and CSS that eradicates them as much as possible, and then use resources like the CSS Tricks Snippets library to grab fixes such as clearfix and inline–block, amongst other things. Pretty much everything is already out there, so you don’t have to suffer IE6 in silence.

If you want to know more about using LESS, Anthony Killeen (@MrQwest) recently published this article on 12 Devs of Xmas: On the first day of Xmas, learn to use LESS. Well worth a read.

Conditional Comments

Finally, I mentioned Conditional Comments, but what are they? A bloody fantastic invention, is what they are. Rather than having to litter your CSS with all manner of ugly hacks (Tantek’s Box Model Hack, anyone?), Conditional Comments allow you to specify individual members of the IE family. Here’s how I go about that:

<!--[if lte IE 8]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<script src="/js/selectivzr.min.js"></script>
<script src="/js/jquery.pseudo.js"></script>
<![endif]-->
<link rel="stylesheet" href="/css/styles.css" />
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<link rel="apple-touch-icon" href="/apple-touch-icon-57x57.png"  />
<link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png" />
<!--[if IE]>
<link rel="stylesheet" href="/css/ie.css" media="screen" />
<![endif]-->
<!--[if IE 8]>
<link rel="stylesheet" href="/css/ie8.css" media="screen" />
<![endif]-->
<!--[if IE 7]>
<link rel="stylesheet" href="/css/ie7.css" media="screen" />
<![endif]-->
<!--[if IE 6]>
<link rel="stylesheet" href="/css/ie6.css" media="screen" />
<script src="/js/ie6.js"></script>
<![endif]-->

We’ll look at that in chunks.

The first chunk says “if less than or equal to IE 8, then do this”. IE8 downwards requires the HTML5 shim, plus a few other helping hands, so they get added here, before the main stylesheet.

Next up, regular styles and icons.

Following on, you’ll see rules for: all IEs, just IE8, just IE7, and then IE6, which gets its own JS file as well. If you’re using CSS3PIE, you’d include your pie.css file here, too.

And, relax…

Using these methods, you should have a lot less bother with cross–browser testing and sleep far easier at night.

Thanks to Edd Couchman (@redheat) for prodding me about Conditional Comments.

This article is copyright © 2014 Phil Sherry.

2 Responses to An easier Internet Explorer experience

  1. Nice article, bookmarked for future reference.

    However, (disclaimer, I don’t use LESS so I’m probably missing something):

    I see why LESS is handy for declaring colours etc. as variables you can use throughout your CSS file but, unless I’m missing something, using it for integrating classes is slightly redundant. Let me explain.

    You say you can define clearFix in your LESS script, and then put references to it throughout each class, which will in turn result in the definitions being added to your classes at runtime.

    The red flag for me is, once processed won’t that add tons of redundant code which will be a nightmare to maintain?

    Is there any reason why you couldn’t just define a class called clearFix in your CSS, and then reference it in the HTML using multiple classes? For example:

    CSS:
    .clearFix { clear: both; }

    HTML
    my stuff

    That way, you don’t have clearFix defined a million times in your CSS, and you can just add/remove it from the HTML without any faffing around with LESS.

    Of course, not using LESS means I know nothing about it so feel free to point and laugh if I’m barking up the wrong tree :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>