Can you print web page background colors? Yes, actually you can! Using an unobtrusive javascript it is possible to make background colors appear on paper – if you can accept a few limitations. This is achieved by adding a class to every element that has a background color to be printed. Those element will – with a little help of the Mootools framework – have a <div> added which will have a top and bottom border, that will emulate the background color.

Before we start looking at the code, let me emphasize the limitations:

  • The print command has to be invoked with a button. For IE you can use the onbeforeprint event, but it will not be working on other browsers, so don’t rely on it!
  • Background color on the body will not be printed.
  • Background images are not handled, they will be ignored.
  • Classes for elements with background color to be printed will have to be added.
  • Font color is a total different issue. Only use black text when printing, as the color are unpredictable across browser. See The woes of CSS color in print typography for more details. This means avoid using very dark background colors!
  • This might not work very well on complicated web applications, with lots of absolute positioned elements.
  • You need the Mootools Javascript framework. I’ve used version 1.2.2. Beware, differences between versions might affect the scripts.

Let’s see some code

In the example I use three files – a HTML, a JavaScript and a CSS file – all located in the same folder.

The HTML, called index.html:

<head>
	<!-- load css and javascripts -->
	<link rel="stylesheet" href="style.css" type="text/css" />
	<script type="text/javascript" src="mootools.js"></script>
	<script type="text/javascript" src="printBgColor.js"></script>
</head>
<body>
	<!-- Frame the content for good looks -->
	<div class="frame">
		<!-- the header has a red background,
		notice the printBg class -->
		<h1 class="myHeader printBg">This header has
		a background color we want to print</h1>

		<!-- the content has a green background,
		again notice the printBg class -->
		<p class="myParagraph printBg">
			<!-- Just some meaningless Lorem Ipsum here -->
			Aliquam et nisl vel ligula consectetuer
			suscipit. Morbi euismod enim eget neque.
			Donec sagittis massa. Vestibulum quis
			augue sit amet ipsum laoreet pretium.
			Nulla facilisi. Duis tincidunt, felis et
			luctus placerat, ipsum libero vestibulum sem,
			vitae elementum wisi ipsum a metus. Nulla a
			enim sed dui hendrerit lobortis.
			Donec lacinia vulputate magna. Vivamus
			suscipit lectus at quam.
		</p>
	</div>
	<br />

	<!-- Button to invoke the print -->
	<input type="button" value="Print" name="Print" onclick="printBg()" />
</body>

The JavaScript, called printBgColor.js:

function printBg() {
	// the script starts by iterating through all the elements
	// with the class "printBg"
	$$(".printBg").each(function(element) {
		// get the size, position and background color
		// of the element
		var size = element.getSize();
		var coord = element.getCoordinates();
		var elemBgColor = element.getStyle('background-color');

		// set the original background to nothing
		element.setStyles({'background': 'none'});

		// create a <div> that will have top and bottom
		// borders half the height of the parent element.
		// also position the element exacly as the parent
		// and place it behind
		var borderDiv = new Element('div', {
			'styles': {
				'position': 'absolute',
				'top': coord.top,
				'left': coord.left,
				'border-top': size.y/2+'px solid '+elemBgColor,
				'border-bottom': size.y/2+'px solid '+elemBgColor,
				'width': size.x,
				'height': '0',
				'z-index': '-1'
			}
		});

		// add the new <div> as a child under the parent element
		borderDiv.inject(element);

	});

	// start printing
	window.print();
}

The CSS, called style.css:

/* Nothing special about the stylesheet */
.frame {
	width			: 600px;
	padding			: 10px;
	border			: 1px solid #ccc;
}

.myHeader {
	font-size		: 1.5em;
	text-align		: center;
	height			: 30px;
	padding			: 3px;
	margin-bottom	: 20px;
	background		: #a00;
	color			: #000;
}

.myParagraph {
	background		: #0a0;
}

Finishing remarks

I do not reverse the process in the JavaScript, as the new document looks exactly as the original. This might be a problem if you want to print twice. But I was not too worried about that, because I wanted to use the script in conjuction with my special iFrame technique, see Print a specific DIV using an iFrame, CSS and JavaScript for more details.

Posted Friday, May 29th, 2009 at 8:34 pm
Filed Under Category: Ajax, CSS, JavaScript
You can leave a response, or trackback from your own site.

0

Leave a Reply