2

Imagine a webpage which enables users to show an hidden element, using javascript to modify css a CSS style at runtime.

After his decision (which includes the modification of the stlyesheet) the user uses the printing functionality of his browser.

It seems that Internet Explorer does not respect the changes made in the stylesheet before during printing if the original css definition is located in an external file. In other Browsers everything works as expected.

Please have a look at the example below, which changes a style class from its initial definition display:none to display:inline at runtime hence the element will be displayed. But when printing this page, the element remains hidden in internet explorer (tested with IE 6,7,8).

Do you have a solution or workaround?

Minimalistic example (html file):

<html><head>
<LINK rel="stylesheet" type="text/css" href="minimal.css">
</head><body onload="displayCol();">
<script>
function displayCol()
{
     var myrules;
     if( document.styleSheets[0].cssRules ) {
              myrules = document.styleSheets[0].cssRules;

     } else {
        if ( document.styleSheets[0].rules ) {
            myrules = document.styleSheets[0].rules;
            }
        }
      myrules[0].style.display = "inline";  
}
</script>

<div class="col0" id="test">This is hidden by default.</div></body></html>

minimal.css

.col0 {
  display:none;
}

UPDATE:

Please note that the decision if the object should be displayed or not is made by the user - it's not known at runtime!

MRalwasser
  • 15,605
  • 15
  • 101
  • 147
  • it not work because the style is applied on visible screen and not for printing (when you click on print preview, web page is reloaded an prepare for printing using default css as value). I suggest you to use a css with media="print" and conditional if to use particular version for internet explorer. – Roberto Conte Rosito Feb 23 '11 at 17:18
  • @RoBYCoNTe I've updated the question - the decision if the object should be displayed is done by the user. if he decides to show the object displayCol() will be invoked - but it only shows the object on the screen but not on the printer. – MRalwasser Feb 23 '11 at 17:24
  • @MR: did you ever solve this problem? I am having the same issue. I use jquery's .toggle() method to toggle the visibility of a section post page load. that section does not print on FF/Chrome (as expected) but still prints on IE. Do you have a solution for this? (I hate IE) – lamarant Jun 23 '11 at 18:18

5 Answers5

3

Have you considered using the media=print way of getting the browser to use a stylesheet specifically for printing?

<link rel="stylesheet" href="print.css" media="print" />

If the css changes you are making are always the same, i.e. you can technically store them on a separate css file, then you can use this.

For non-static CSS, in IE (not sure about other browsers/later versions of IE), you could consider using the onbeforeprint event.

See here: http://www.javascriptkit.com/javatutors/ie5print.shtml

  • Yes. Unfortunately, introducing media="print" styles also doesn't help me. Please note that the decision if an object should be displayed or not is made by the user - it's not static! I am sorry that this was not clearly pointed out in the question. – MRalwasser Feb 23 '11 at 17:22
  • @MRal: Ah, I see. Did you try messing with the DOM? (Not that I recommend it). –  Feb 23 '11 at 17:26
  • @MRal: Apparently IE supports an onbeforeprint event. You could try using that (see the link in my answer). –  Feb 23 '11 at 17:36
  • @Moron: This doesn't help me, because I don't need to intercept printing. The css is already altered correctly, before the user decides to print. The problem is that IE seems not respect changes made to stylesheets for printing. – MRalwasser Feb 23 '11 at 17:51
  • @Mral: It is possible that any changes you make during this event will be respected by IE for printing. Of course I haven't tried it. After all, this event was specifically made for dynamically figuring out the content to be printed. If that does not work, you can probably alter the DOM during this event. Caveat: Again, I haven't tried it myself. –  Feb 23 '11 at 17:55
1

Instead of using javascript to change the stylesheet rules, use scripting to apply and remove classes to the elements that need to be displayed. Remember that an element can have more than one class applied to it.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Demo</title>
    <style type="text/css">
        .col0 {display:none;}
        div.showCol {display: inline;}
    </style>
    <script type="text/javascript">
        function displayCol() {
            document.getElementById("test").className += " showCol";
        }
    </script>
</head>
<body onload="displayCol();">
    <div class="col0" id="test">This is hidden by default.</div>
</body>
</html>

This answer to another question does a great job laying out different ways to do this with scripting: Change an element's class with JavaScript

Community
  • 1
  • 1
David Kolar
  • 3,475
  • 25
  • 34
  • Although this seems to work - this means I have to find and traverse all objects in the DOM tree and change their classes which might be resource intensive. Because of this I find it quite elegant to simple change the CSS defintion. – MRalwasser Feb 23 '11 at 18:09
  • @MRalwasser It would depend on your specifics, but find an element via its ID is really low impact. If you are changing many elements, perhaps they have a parent element in common to which a class could be applied? – David Kolar Feb 23 '11 at 18:19
0

You could try using a specific style sheet for printing, for example:

<link rel="stylesheet" type="text/css" href="print.css" media="print" />

EDIT - too slow :)

ihamlin
  • 180
  • 3
0

Javascript is not being evaluated when printing. It will look just like when Javascript is turned off. You need an extra media=print stylesheet and make any necessary changes there.

If that is not an option, you could create a link that will generate a static page that will look like it's supposed to for that particular user.

DanMan
  • 11,323
  • 4
  • 40
  • 61
  • I am not trying to evaluate JavaScript during printing but before. In Firefox, everyting works as expected so this is a browser problem. – MRalwasser Feb 23 '11 at 17:26
0

Based off your example scenario - in your style sheet add:

.col0 {
    display: none;
}

body.showColumn .col0 {
    display: inline;
}

Then simply toggle the .showColumn class on your body, and the column's visibility will be toggled accordingly.

Brian Mathews
  • 682
  • 4
  • 6