IE expressions ignore CSS media types

A client recently reported that there was a problem with their print stylesheet causing content to be cut off at the right margin. I had a look at it and couldn’t see a problem until I tried printing from Internet Explorer. There was a problem alright.

It was really puzzling since all the print CSS for that site does is basically hide parts that are irrelevant when printing. There shouldn’t be any conflicts with other style sheets either since the screen style sheets use a different media type. But I was wrong—in some cases IE will apply CSS that it shouldn’t.

The problem occurs when you use Microsoft’s proprietary CSS expressions. Any declarations that contain an expression will be applied when printing. Consider the following setup for loading the various CSS files:

<style type="text/css" media="screen,projection">
@import ’main.css’;
</style>
<!--[if IE]>
<link rel="stylesheet" href="ie.css" type="text/css" media="screen">
<![endif]-->
<link rel="stylesheet" href="print.css" media="print" type="text/css">

First, main.css is imported by all browsers and is used for the screen and projection media types. Next, conditional comments are used to send ie.css to Internet Explorer for Windows. Note the screen media type. Finally all browsers will load print.css when the media type matches print. All good so far.

Now, consider the common scenario of wanting to use max-width to make sure line length stays readable even in very wide browser windows. Since IE versions below 7 do not support that, a common workaround is to use an expression similar to this:

#content { width:expression((document.documentElement.clientWidth > 1080) ? "1050px" : "auto"); }

This will be applied when the page is printed even though it shouldn’t be, and leads to content being cut off if the element’s width as calculated by the expression exceeds the width of the selected paper size. The expression in my example will set the width of #content to 1050 pixels when the window is wider than 1080 pixels. That is wider than an A4 size paper and the page is cut off. If the window is narrow enough to make the expression set the width of #content to “auto”, printing works fine. Very odd. Besides, only the rules in print.css should be used when printing, and this is respected by all other browsers I have tested.

The workaround I found is to override any declarations that use expressions. I prefer putting this in a file called ie-print.css. In this case, that file would contain the following:

#content { width:auto !important; }

Note the use of !important. Just redeclaring the property in a stylesheet that loads after ie.css does not work. (Sidenote: This is the first time I’ve actually found a use for !important.)

I load the file by adding another link element inside the conditional comment:

<style type="text/css" media="screen,projection">
@import 'main.css';
</style>
<!--[if IE]>
<link rel="stylesheet" href="ie.css" type="text/css" media="screen">
<link rel="stylesheet" href="ie-print.css" type="text/css" media="print">
<![endif]-->
<link rel="stylesheet" href="print.css" media="print" type="text/css">

To sum it up: If you’re having problems with print style sheets in Internet Explorer for Windows, check your use of CSS expressions.

Posted on November 29, 2006 in CSS, Browsers