Applying conditional classnames to the html
element is a popular way to help target specific versions of IE with CSS fixes. It was first described by Paul Irish and is a feature of the HTML5 Boilerplate. Despite all its benefits, there are still a couple of niggling issues. Here are some hacky variants that side-step those issues.
An article by Paul Irish, Conditional stylesheets vs CSS hacks? Answer: Neither!, first proposed that conditional comments be used on the openinghtml
tag to help target legacy versions of IE with CSS fixes. Since its inclusion in the HTML5 Boilerplate project, contributors have further refined the technique.
However, there are still some niggling issues with the “classic” conditional comments approach, which Mathias Bynens summarized in a recent article on safe CSS hacks.
- The Compatibility View icon is displayed in IE8 and IE9 if you are not setting the
X-UA-Compatible
header in a server config. - The character encoding declaration might not be fully contained within the first 1024 bytes of the HTML document if you need to include several attributes on each version of the opening
html
tag (e.g. Facebook xmlns junk)
You can read more about the related discussions in issue #286 and issue #378 at the HTML5 Boilerplate GitHub repository.
The “bubble up” conditional comments method
Although not necessarily recommended, it looks like both of these issues can be avoided with a bit of trickery. You can create an uncommented opening html
tag upon which any shared attributes (so no class
attribute) can be set. The conditional classes are then assigned in a second html
tag that appears after the <meta http-equiv="X-UA-Compatible">
tag in the document. The classes will “bubble up” to the uncommented tag.
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible"
content="IE=edge,chrome=1">
<meta charset="utf-8">
<!--[if lt IE 7]><html class="no-js ie6"><![endif]-->
<!--[if IE 7]><html class="no-js ie7"><![endif]-->
<!--[if IE 8]><html class="no-js ie8"><![endif]-->
<!--[if gt IE 8]><!--><html class="no-js"><!--<![endif]-->
<title>Document</title>
</head>
<body>
</body>
</html>
The result is that IE8 and IE9 won’t ignore the <meta http-equiv="X-UA-Compatible">
tag, the Compatibility View icon will not be displayed, and the amount of repeated code is reduced. Obviously, including a secondhtml
tag in the head
isn’t pretty or valid HTML.
If you’re using a server-side config to set the X-UA-Compatible
header (instead of the meta
tag), then you can still benefit from the DRYer nature of using two opening html
tags and it isn’t necessary to include the conditional comments in the head
of the document. However, you might still want to do so if you risk not containing the character encoding declaration within the first 1024 bytes of the document.
<!DOCTYPE html>
<html lang="en">
<!--[if lt IE 7]><html class="no-js ie6"><![endif]-->
<!--[if IE 7]><html class="no-js ie7"><![endif]-->
<!--[if IE 8]><html class="no-js ie8"><![endif]-->
<!--[if gt IE 8]><!--><html class="no-js"><!--<![endif]-->
<head>
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
</body>
</html>
The “preemptive” conditional comments method
Another method to prevent the Compatibility View icon from showing was found by Julien Wajsberg. It relies on including a conditional comment before the DOCTYPE. Doing this seems to help IE recognise the <meta http-equiv="X-UA-Compatible">
tag. This method isn’t as DRY and doesn’t have the character encoding declaration as high up in the document, but it also doesn’t use 2 opening html
elements.
<!--[if IE]><![endif]-->
<!DOCTYPE html>
<!--[if lt IE 7]><html class="no-js ie6"><![endif]-->
<!--[if IE 7]><html class="no-js ie7"><![endif]-->
<!--[if IE 8]><html class="no-js ie8"><![endif]-->
<!--[if gt IE 8]><!--><html class="no-js"><!--<![endif]-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
</body>
</html>
While it’s interesting to explore these possibilities, the “classic” method is still generally the cleanest. It doesn’t create invalid HTML, doesn’t risk throwing IE into quirks mode, and you won’t have a problem with the Compatibility View icon if you use a server-side config.
If you find any other approaches, or problems with those posted here, please leave a comment but also consider adding what you’ve found to the relevant issues in the HTML5 Boilerplate GitHub repository.
Thanks to Paul Irish for feedback and suggestions.