Internet Explorer / IE ignoring certain CSS when printing

Is Internet Explorer 7 or 8 ignoring (some) CSS rules when printing or generating a print preview (but the page displays fine in the browser)? Are you using HTML5 by any chance? Are the rules being ignored those that use the new HTML5 tags in their selectors? Congratulations, you've found another bug in IE 7 & 8 (it looks to of been fixed in IE 9).

Yes, even if you've used the document.createElement('tagname'); JS fix to allow you to apply styles to the new HTML5 tags in IE, this is a different issue - which specifically affects printing or generating a print preview.

So, to fixes. There is the IE Print Protector for printing HTML5 pages in Internet Explorer (pre v9). This JS library replaces the new HTML5 tags with existing tags (such as divs) when the page is printed and applies the same styles to them.

This isn't the only solution however. The new HTML5 tags do not have to be replaced with other tags - they just have to have the CSS rules (re)applied directly to them through JS. You could hard-code these into a JS file - or you could write some JS which reads the CSS rules and (if their selectors use the new HTML5 tags) applies the same rules directly to the relevant elements.

Here is an example (that uses the Prototype 1.7 JS library) which handles the header, nav and footer tags (but could easily be expanded for other tags):

document.observe('dom:loaded', function() {
if (Prototype.Browser.IE && // oh how I loathe thee..
(navigator.userAgent.match(/MSIE 7/) || navigator.userAgent.match(/MSIE 8/))) {
/* this compensates for IE 7 & 8 not applying the styles of CSS selectors
which use the new HTML5 tags - but only when printing a page! */
var cssSelectorsAndRules = new Array();
for (var i = 0; i < document.styleSheets.length; i++) {
/* this is the IE 'processed' version of the original content (no comments, individually
separated-out selectors (and duplicated 'shared' rules), all rules on a single line for
a selector, etc.) */
var lines = document.styleSheets[i].cssText.split("\n");
var html5TagSelector = '';
var rulesStr = '';
for (var lineNum = 0; lineNum < lines.length; lineNum++) {
if (lines[lineNum].match(/\{/) &&
lines[lineNum].match(/(?:(?:header)|(?:nav)|(?:footer))/)) {
// HTML5 tag selector line
html5TagSelector = lines[lineNum].sub(/\{/, '').strip().toLowerCase();
} else if (!html5TagSelector.empty()) {
if (!lines[lineNum].match(/\}/)) rulesStr = lines[lineNum].strip().toLowerCase();
else { // end of rules for a HTML5 tag selector
cssSelectorsAndRules.push(new Array(html5TagSelector, rulesStr));
html5TagSelector = '';
}
}
}
}
/* because of a bug in Prototype 1.7 in IE 7 we can't rely on CSS selectors which
use the new HTML5 tags, so we add an id attribute to the tags of the same name */
if (navigator.userAgent.match(/MSIE 7/)) {
$$('body')[0].descendants().each(function(element) {
if (element.tagName == 'header') element.writeAttribute('id', 'header');
else if (element.tagName == 'nav') element.writeAttribute('id', 'nav');
else if (element.tagName == 'footer') element.writeAttribute('id', 'footer');
});
}
cssSelectorsAndRules.each(function(cssSelectorAndRules) {
var selector = cssSelectorAndRules[0];
// change to id instead of tag selector to match the altered markup
if (navigator.userAgent.match(/MSIE 7/)) {
selector = selector.replace(/((?:header)|(?:nav)|(?:footer))/, '#$1');
}
$$(selector).each(function(element) {
var styles = {};
var rulesArray = cssSelectorAndRules[1].split(';'); // index 1 is the rules
rulesArray.each(function(ruleStr) {
var ruleParts = ruleStr.split(':');
styles[ruleParts[0].strip().camelize()] = ruleParts[1].strip();
});
element.setStyle(styles);
});
});
}
});

Unfortunately, due to a bug in Prototype 1.7 in IE 7 (due to be fixed in v1.7.0.1 apparently), we have to employ an additional measure for IE 7 - adding an id to the HTML5 tags, that we then use to apply the CSS rules. In this example, it adds an id of "header" to the header tag, an id of "nav" to the nav tag, and so forth. Obviously this is not ideal and may potentially conflict - so this may need to be tweaked, depending on your setup. Prototype 1.7.0.1 doesn't seem to have an official release date has yet ("soon-ish" was mention back in July). Alternatively, if you're using a locally hosted copy of the Prototype 1.7 library, you can try patching your local version with this proposed fix.

Tagged , , and .

Dropping support for IE 6

Regarding phasing out support for IE 6 across all 37signals products.

When I made the latest set of cosmetic changes to the blog, I decided I would no longer test in IE 6. If you are using Windows then you really should be using Firefox (or if you're one of those people who don't like v3, perhaps Opera). If using Internet Explorer is "using the Internet" to you, then you should accept the default choices you are offered when accessing Windows Update (which will include IE 7).

When I first started working as a Web Developer I was still testing in Netscape Navigator 4 and Internet Explorer 4. IE 5 was painful to support and IE 6 followed in the footsteps of its parent. IE 7 isn't perfect, but at least there are less bugs for developers to deal with.

Now if only the rest of the world would follow suit, then I could stop supporting it when developing sites for others.

Tagged , , and .

Most used blog post tags

Blog entries by month

  1. January 2012 (1)
  2. August 2011 (2)
  3. March 2011 (1)
  4. February 2011 (1)
  5. November 2010 (1)
  6. October 2010 (1)
  7. August 2010 (2)
  8. January 2009 (1)
  9. December 2008 (1)
  10. November 2008 (1)
  11. October 2008 (2)
  12. September 2008 (3)