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.