Programmatically change @media print css styles via javascript

Sometimes our customers ask us to be able to print the webpages we build for them with specific styles, and most of the times you can get away with it by adding a separate css file that targets the print media. Rather straightforward.

What if the customer asks you to change print styles at runtime?

Well, it seems that this cannot be easily done, at least there is no official way of doing it: javascript doesn’t allow you to change media specific styles, but only the global one.

This won’t stop us: after banging my head against the wall for a while I came up with a simple yet effective trick: what if we programmatically change the text of a style tag with media attribute set to print? Will the browser see the change and apply it? Well, it seems so.

So, let’s review a simple example that will allow us to choose the color of the printed page text according to the button we press.

Let’s start from the page head tag:


<head>
  <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.0.js"></script>
  <style type="text/css">
    @media print {
      button {
        display: none;
      }
    }
    @media screen {
      .red {
        color: red;
      }
      .green {
        color: green;
      }
    }
  </style>
</head>

Nothing fancy here, we’re just loading jquery and adding some styles that hide buttons on the printed page while coloring them on the screen.

Let’s see the page body content:


<body>
  <p>hello world!</p>
  <button class="red">print this page in red</button>
  <button class="green">print this page in green</button>
  <style type="text/css" media="print" id="print"></style>
</body>

Here we have the page content, the buttons and an empty style tag that specifically targets print media, which is left empty and will be populated with our custom styles at runtime.

Finally, the javascript:


$(function() {
  var buttons     = $('button');
  var printStyle  = $('#print');
  var style;

  buttons.click(function() {
    style = 'p { color: ' + $(this).attr('class') + '};';
    printStyle.text(style);
    window.print();
  });
});

What happens here? When we click one of the buttons the code finds the color we want, it fills the empty style tag with the custom styles and then will open the browser integrated print interface. Simple yet effective.

The complete code can be seen in action in this fiddle.