My Little Corner of the Net

CSS Tricks: .noprint and .noscreen

Cascading style sheets (CSS) make it easy to target web pages to multiple output media. For example, using different CSS rule sets it is possible to design a single web page that looks visually different on screen, on a hand-held device, or when printed.

On way that I’ve extensively used different CSS media types is to provide printer friendly versions of a page. Since real estate on an 8.5″ x 11″ sheet of paper is limited, I like to remove any extraneous content from my pages when somebody prints them–content such as navigation, that has no meaning on the printed page. To do this I often use a “noprint” class definition in my print stylesheets:

.noprint {display: none;}

Then, in my (X)HTML markup I simply set the class attribute of tags I want to exclude from the printed page to no print. (Note that I often take advantage of the seemingly forgotten fact that an element can use multiple classes):


<ul id="navbar" class="nav noprint">
...
</ul>

Easy shmeasy…now when you print the page the navigation links aren’t there. Since the “screen” style sheet doesn’t define a “noprint” class the browser ignores the fact that it is present on some elements and displays those elements according to other rules.

Likewise, I occasionally want to include something on the printed page that isn’t visible on screen. For example, I’ll often use a background image as page header. Since backgrounds generally don’t print, I’ll often include a text and/or a lightweight image title inside the header div that I want to display only when the page is printed. For this, if you can’t guess already, I use a “noscreen” class in my screen-targeted stylesheet.


<div id="header"><span class="title noscreen">This is the site title</span></div>

Unlike the noprint definition, however, there are many reasons why I would like to still have the noscreen elements to be considered part of the page. For example, since background images have no alt text, users of screen readers won't hear the content if I use display:none to hide it, even if it is repeated in the background image. Instead, I use a variation on the Fahrner Image Replacement technique to move the "hidden" content off the edge of the screen. This has the effect of visually hiding the unwanted content while keeping it available in non-visual circumstances:

.noscreen {margin-left: -999em; height: 0; overflow:hidden;}

This shifts the element way off the edge of the screen (the actual value is arbitrary—any negative value should do, -999em is just the value used in an example I once saw somewhere) and forces it to a height of zero so that it won’t effect the layout of other elements. Since the element is still technically visible screen readers and text-based browsers will still acknowledge it.

I could extend this technique to other media, such as hand-held devices, as well, but at this point I rarely target anything except screens and (indirectly) printers. Further, if I was targeting hand-held devices I would probably use some other technique such as browser detection to determine the device and send out an alternate “light” view to save on bandwidth.

Leave a Reply

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

<