hasLayout.net

IE Conditional Comments

Overview

IE Conditional Comments (or condcom for short) are special comments that enable authors to use the instructions that only Internet Explorer 5.0 and above on Windows platform will see.

Various types of conditional comments

Regular comment:
<!--This is a comment-->
IE conditional comment:
<!--[if IE]> <![endif]-->
Reversed anti-IE comment:
<!--[if !IE]>--> non-IE HTML Code <!--<![endif]-->
Reversed IE conditional comment (rarely needed):
<!--[if ! lt IE 7]>
    <![IGNORE[--> <![IGNORE[]]>
        Code for browsers that match the if condition
<!--<![endif]-->

In a nutshell, any browser except Internet Explorer on a Windows platform will treat conditional comment as a regular HTML comment. You cannot use condcoms in the CSS code itself. IE conditional comments are useful for hiding or revealing the code to IE, which in turn allows authors to use CSS "hacks" in a more appropriate fashion.

IE-Only Code

<!--[if IE]><![endif]-->

As you can see this is pretty much a regular HTML comment. Any browser well see the part between the starting <!-- and ending --> as a comment and thus disregard it. However, Internet Explorer will also see the part [if IE]> which will tell it to parse the code following this part until it sees <![endif]. Therefore, the following code will produce an empty page for any browser except for IE.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" 
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head><title>Test page</title></head>
 <body>
    <!--[if IE]>You are using Internet Explorer, 
        bad choice I'd say!<![endif]-->
 </body>
</html>

In IE on Windows, versions 5.0 and above, this code will display text "You are using Internet Explorer, bad choice I'd say!"

Personally, I suggest you don't use plain <!--[if IE]>. Target the highest currently available IE version instead, you never know what awaits you in the future. I will show you how to accomplish that in the Getting More Specific - Version Match section. However, a different point of view exists. Apparently Microsoft will have an opt-in system in the next version of IE that will make it behave like older versions. You can find out more on WebDevout.

As I have noted before, IE conditional comments are useful for including IE specific CSS code, let's look at the next example.

Conditional Comments with <style> Elements

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" 
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head><title>Test page</title>
        <!-- THIS IS WRONG -->
        <style type="text/css">
            <!--[if IE]>
                body { background: #000; }
            <![endif]-->
        </style>
        <!-- THIS IS RIGHT -->
        <!--[if IE]>
            <style type="text/css">
                body { background: #000; }
            </style>
        <![endif]-->
    </head>
<body>
</body>
</html>

The code above demonstrates wrong and correct examples of using IE conditional comments for including embedded styles. The first example is wrong because IE conditional comments are based on a regular HTML comment which looks like this: <!-- This is a comment -->. In CSS comments are written as /* This is a comment */ and therefore IE conditional comment is ignored by the parser, i.e. the parser sees it as an error in the CSS code. However, the second example is perfectly correct, conditional comments surround the entire <style> element and yes we can have several <style> elements.

In practice it is often useful to create a separate style sheet with IE specific instructions, the following example demonstrates a way to include those files using IE condcoms.

IE-Only Style Sheet

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" 
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head><title>Test page</title>
        <link rel="stylesheet" type="text/css" href="all_of_my_css_code.css">
        <!--[if IE]>
            <link rel="stylesheet" type="text/css" href="ie_fixes.css">
        <![endif]-->
    </head>
<body>
</body>
</html>

In the code above, the CSS file "ie_fixes.css" will be included only if the viewer of the page is using any version of Internet Explorer. Make sure to include IE specific files containing IE hacks after all of your regular CSS files for the styles to cascade correctly.

As I've seen people do this before, I would like to mention that only IE will see the code in the file included with condcoms. Which means, that if, for example, you used * html p { display: inline; } to pass code to IE version 6 and below you would write it as p { display: inline; } (without the filter hack) inside conditional comments. Wait a minute, * html hack shows code only to IE version 6 and below and in the our code example "ie_fixes.css" file is visible to all IEs. That's where the version match comes into play.

Getting More Specific - Version Match

There is more control in IE condcoms, you may also specify the version of the browser, next example demonstrates that.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
     "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head><title>Test page</title></head>
 <body>
    <!--[if IE 5]>
        You are using Internet Explorer 5.X
    <![endif]-->
 </body>
</html>

All browsers except for IE 5 will see a blank page in this case. It is important to note that text "You are using Internet Explorer 5.X" will also be visible in IE 5.5, the reason for that is because we did not specify the decimal point of the version number and therefore this condcom will be true for any IE version that has 5 as it's major digit in the version number. If we wanted a condcom to apply to only IE version 5, we would write the conditional comment like this:

<!--[if IE 5.0]>
    You are using Internet Explorer 5.0
<![endif]-->

I would like to point out that the code above was still parsed in IE version 5.5 when I tested it in ies4linux. It may well be a bug in the implementation of those old browsers, though I cannot test it since I don't have natively installed IE 5.5 and IE 5.0 on a Windows platform. If you can confirm this fact, please contact me.

Further Control - Comparison Operators

Comparison operators allow us to make IE conditional comments even more flexible, matching several versions with one condcom. To modify the meaning of the condcom expression we can prefix the IE in the condcom declaration with the following:

List of Valid Comparison Operators

lt
less than
lte
less than or equal to
gt
greater than
gte
greater than or equal to

Let's see those in action:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" 
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head><title>Test page</title></head>
 <body>
    <!--[if lt IE 6]>
        You are using Internet Explorer 5.X
    <![endif]-->
    <!--[if gte IE 6]>
        You are using Internet Explorer 6 or above
    <![endif]-->
 </body>
</html>

When this example is viewed in IE with version number less than 6 the text "You are using Internet Explorer 5.X" will be visible and text "You are using Internet Explorer 6 or above" will be hidden. Keep in mind that IE below 5.0 does not support conditional comments and according to Microsoft no text from the example above will be visible. I do not possess such IE version and therefore cannot verify that statement. In turn, if our example would be viewed in IE version 6 and above, only the text "You are using Internet Explorer 6 or above" would be visible.

Reversed Anti-IE Comment

By "reversed" I mean that this type of condcom will hide the code from IE and reveal it to any other. Microsoft either considers IE to be the only browser in this world or doesn't care about validation, thus writes a reversed conditional comment as <![if !IE]> <![endif]>. However, it is an invalid code and should be avoided by any sane web developer. Instead consider the following valid workaround:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" 
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head><title>Test page</title></head>
<body>
    <!--[if !IE]>-->
        You are using a good browser
    <!--<![endif]-->
</body>
</html>

The text "You are using a good browser" will be visible in any browser other than IE. In the condition statement we have used an exclamation mark (!), which is called a negation operator, to reverse the boolean value of the operand. This version of the reversed condcom is not so much different from the invalid Microsoft's version but it does validate perfectly, thus there are way fewer chances that some browser will choke on it, and works just as good.

Important note: keep in mind, with this version of reversed condcoms any modificators, such as version match and comparison operators will either not work or will print "-->" on the page, if you need to use those consider using reversed condcoms which I will cover next.

Reversed IE Conditional Comments

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" 
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head><title>Test page</title></head>
<body>
    <!--[if !gt IE 6]><![IGNORE[--><![IGNORE[]]>
        Some will see and some will not!
    <!--<![endif]-->
</body>
</html>

The code above will hide the code in the conditional comment from any IE version above 6. The easy way to remember this is to take a look at the expression in the if part without the negation operator (!). In the example above it is gt IE 6, which means that the code in the conditional comment will be hidden from IE versions greater than IE version 6

Thanks to David Hammond for explaining me personally the way all this works.

When IE sees the [if !gt IE 6]>, if the negative condition matches (i.e. browser is not IE version above 6), then the immediate markup gets included on the page. It doesn't wait for the --> to close the comment. However, in this case, we also want to let non-IE browsers in. Therefore, we want to close the comment somehow. If we would just add a --> after the [if !gt IE 6]>, then IE would display --> on the page. So we set up a little IGNORE marked section to hide the closing part of the HTML comment (-->) from IE. Then we have to close the IGNORE section, but we run into the same issue for other browsers: the closing part would be shown on the page itself. So right after the --> (ignored by IE), we start a new IGNORE section for non-IE browsers. Then when we close it, it's closed for everyone. Complicated, but it's the only way to make it work for IE and other browsers.

David was kind enough to provide the following conditional case patterns that demonstrate what is visible depending on which browser is parsing the code:

Original code
<!--[if !condition]><![IGNORE[--><![IGNORE[]]> HTML <!--<![endif]-->
Non-IE user agents
<!--                          --><![IGNORE[]]> HTML <!--         -->
IE if !condition matches
<!--               ><![IGNORE[              ]> HTML <!--         -->
IE if !condition doesn't match
<!--                                                             -->

If you are having a hard time understanding this, don't worry much. I have never had a need for this kind of conditional comments, but if you ever do need them - they exist.

No Hacks, Please!

It may seem to the beginner that using conditional comments is more work, more code or (my favorite) people say that conditional comments are proprietary. Let me explain why you should favor condcoms over hacks.

Lies About Conditional Comments

Condcoms are more work

Even though it may seem so when you use condcoms for the first time, in actuality it is less work, especially when you are trying to debug your stylesheet.

Condcoms require more code

That is a complete lie. With condcoms you need to write CSS irrelevant code only once. When using hacks you have to write ugly and lengthy code for each rule, and it often includes fixing your fix in yet another browser.

For those who want to argue that this influences separation of content from presentation. I will say that you should be using condcoms in the external file and including your <link> elements with SSI or with any server side scripting language. Including two CSS files instead of one does not relate to separation of content from presentation in any way.

Conditional comments are proprietary

First of all, let me laugh deeply at people who use this excuse. Yes, they are proprietary, but:

  1. They appear as regular HTML comment to anything that doesn't support them, thus no harm is done.
  2. What makes your hacks less proprietary? Useless garbage code that is used to target specific browsers.
Conditional comments require extra files

Yes, they do! I don't see why this is such a matter. Sure, having extra HTTP requests might not be such a good idea, especially on sites with a lot of traffic, but personally I very rarely need more than one IE specific file.

Also, I find that having all of your IE specific code in a separate file eases up the coding process. If IE doesn't like your page, just switch to the IE file tab in your favorite editor and you have all your current fixes on one screen. Of course the amount depends on the size of the website, but properly coded sites won't need more than a few lines for hasLayout or improper unit calculations.

I agree that in some instances using hacks instead of conditional comments would be a better, if not the only choice. Moreover, in my opinion if you have only one or two IE specific fixes it is much saner to use hacks instead. It is all up to you. You have your options, you make your own choices. Just keep in mind that:

  1. Hacks rely on browser bugs which are likely to be fixed eventually.
  2. Conditional comments are vendor provided method for using IE specific code, thus are unlikely to be removed any time soon.
  3. Every browser sees your hacks. There is a possibility that a next version (or even the current one) of browser XYZ will choke on them.
  4. Only IE interprets code in conditional comments. With a separate IE file, other browsers will not even download it.
  5. Hacks are not verbose about their function. Yes you can put a bunch of comments and make it even more of a mess.
  6. Conditional comments provide version matching which enables author to easily target versions that need a specific code. Which means that with condcoms you can be sure the code will not be parsed in the next version of IE unless you want to. That is not true with hacks, since, as I have said, they rely on bugs and bugs may live longer than the next release of the browser.

Sources

  • Quirksmode
  • MSDN