Using Internet Explorer Conditional Comments with EnhanceJS
April 2020 note: Hi! Just a quick note to say that this post is pretty old, and might contain outdated advice or links. We're keeping it online, but recommend that you check newer posts to see if there's a better approach.
Recently we released an open-source script called EnhanceJS that lets you apply progressive enhancement to your projects in a practical way: it tests a browser’s capabilities before loading CSS or JavaScript enhancements onto a page, and ensures that it receives a usable experience based on those capabilities.
Though IE versions 6 through 8 pass EnhanceJS’s capabilities tests and render most enhancements correctly, they sometimes render CSS or JavaScript in quirky ways. Thankfully, Microsoft provided a relatively unobtrusive way for developers to work around these issues called “conditional comments.” We’ve added a feature to EnhanceJS that provides a way to deliver IE conditional comment-based markup enhancements so sites look and work as expected across all versions of IE.
When we first integrated conditional comment support into EnhanceJS, we used an approach that relied on browser sniffing—the script detected the User Agent string and evaluated to see if it matched IE. But browser sniffing is less than ideal for several reasons: browsers can be spoofed, or configured to report a different User Agent than the one actually employed; it required that we continually update all versions of IE; and it It also made it difficult to support the pseudo-standard IE conditional comment syntax that developers already know. Most importantly, it goes against the very principles of EnhanceJS: testing a browser’s capabilities to make informed UI decisions.
This is the key to the new approach: instead of testing for a User Agent, EnhanceJS directly tests the browser’s ability to support conditional comments. EnhanceJS creates and injects into the page a conditional comment containing an HTML element, and then attempts to find that element using a standard DOM lookup. If the browser can perceive the HTML element, we know it is a version of IE; otherwise it treats the conditional comment like standard comment tag, ignoring the HTML inside it, as all non-IE browsers do. (Details about the script are posted to a thread on github. Big thanks to Paul Irish and Ben Alman for their help in tightening up the approach).
A brief review of conditional comments
Permalink to 'A brief review of conditional comments'When rendering fixes are needed for IE, you can enclose CSS, JavaScript,
or HTML markup in conditional comment tags directed at one or more
versions of IE with an “if” statement; IE will then execute the code
specified within them, while all other browsers treat them as standard
comment tags and ignore them. The “if” statement must reference IE in
square brackets as shown below; in this example, the link
element will
render only in IE:
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="ie_fixes.css" />
<![endif]-->
Conditional comments can also be targeted to a particular version of IE,
or a subset of versions, like those released prior to IE7. We recommend
being as specific as possible so that the conditional code applies only
to the browsers that require it, and not to current or future versions
which don’t need the fix. Use lt
(less than) or lte
(less than or
equal to) to specify which version(s), for example, the following
conditional comment is read only by versions of IE released before
version 7:
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="ie_fixes.css" />
<![endif]-->
…and a brief review of using EnhanceJS
Permalink to '…and a brief review of using EnhanceJS'EnhanceJS runs as the page loads, and if the browser is capable, it
injects enhancements in the form of additional CSS and JavaScript files.
If the browser doesn’t support JavaScript at all, or if it fails any of
the capabilities tests, the page renders with plain, usable HTML when
coded correctly.
Quickly, use the following script block to call the enhance
function,
where you can specify options for the CSS and JavaScript files that
should be loaded in capable browsers:
<script type="text/javascript" src="enhance.js"></script>
<script type="text/javascript">
enhance({
loadStyles: [
'css/reset.css',
'css/enhancements.css'
],
loadScripts: [
'js/enhancements.js'
]
});
</script>
When referenced this way, EnhanceJS creates a link
or script
element
for each CSS and JavaScript file listed, and injects it into the head
of your page with default attributes (i.e.,
rel="stylesheet" type="text/css"
). But what if you’d like to specify
the value of a particular attribute, like media="print"
for a
print-only stylesheet? For these cases, EnhanceJS accepts an alternate
syntax (object notation) that allows you to set key/value pairs for
attributes. The following code demonstrates how you could load a second
CSS file, print.css
, and specify that it should have a media attribute
with a value of print
:
…
loadStyles: [
'css/enhancements.css',
{ href: 'css/print.css', media: 'print' }
],…
To keep it simple, EnhanceJS uses the same attribute syntax you’d write
into the page manually, for example, the href
attribute that defines
the CSS file’s location. This syntax can be used to set any attributes
you’d like, such as rel="alternate stylesheet"
, to link to an
alternate stylesheet.
Using conditional comments with EnhanceJS
Permalink to 'Using conditional comments with EnhanceJS'We created a custom attribute called iecondition
to specify files
only for particular versions of Internet Explorer. When the browser
passes EnhanceJS’s capabilities tests, if an iecondition
key/value
pair is listed in the enhance
function with a CSS or JavaScript file
reference, the resulting link or script element will be written to the
page within conditional comments. For example, to include a stylesheet
for all versions of IE prior to version 7:
…
loadStyles: [
'css/enhancements.css',
{ href: 'css/ie-fixes.css', iecondition: 'lt IE 7' }
],…
EnhanceJS accepts all of the conditions that regular conditional
comments support. Keep in mind that when using EnhanceJS, you do not
need to add the “if” portion of the condition, just the browser version
and any preceding qualifiers, like lte
. Possible values you could
specify with iecondition
include:
- iecondition: ‘lt IE 7’ - will load only in versions of Internet Explorer older than 7
- iecondition: ‘lte IE 7’ - will load only in versions of Internet Explorer less than or equal to 7
- iecondition: ‘6’ - will load only in IE 6. This is shorthand for “IE 6”, which also works.
- iecondition: ‘all’ - will apply to all versions of IE. You can also do this with the keyword “IE”.
All standard conditional comment value (operators) are supported; the complete list is documented at Microsoft’s developer network site: Syntax of Conditional Comments