Minimizing HTTP requests is a very effective way for speeding up your website. In his book “High Performance Web Sites”, Steve Souders talks about this practice as the number one rule to front-end optimization.
Some well-known techniques to reduce HTTP requests include using CSS sprites and combining multiple scripts and stylesheets into single files. Ideally you should be using only one stylesheet. However, how many times have you seen the following two lines in the <head> of a HTML page?
<link rel="stylesheet" type="text/css" href="screen.css" media="screen" /> <link rel="stylesheet" type="text/css" href="print.css" media="print" />
Combining screen and print styles
I get the impression many people are unaware of the fact you can combine screen and print styles into a single stylesheet. Actually you can combine all media types, and it is easy to do.
Linking to your stylesheet
<link rel="stylesheet" type="text/css" href="styles.css" media="screen, print" />You may be wondering why I did not use media="all" or simply omitted the media attribute. By stating the media types the stylesheet applies to right there in the <link>, user agents may decide not to load the stylesheet at all if it does not apply to the current device. Another possible HTTP request less.
Splitting up your stylesheet
All that is left to do is telling the browser which parts of styles.css apply to screen and which parts apply to print. The example below is self-explanatory.
@media screen { body { font-size:14px; } } @media print { body { font-size:10pt; } h1, h2, h3 { page-break-after:avoid; } }
Styles that apply to both screen and print do not need not be wrapped in an @media rule in this case since the stylesheet itself applies to both media types already, as specified in the <link>. Just for the sake of completeness, though, note that you can specify multiple media types separated by commas.
@media screen, print { body { line-height:1.4; } }
To freshen up your knowledge about @media rules, I recommend you have a look at the CSS specification for media types.
Mathias Bynens —May 15, 2009 ∞
You’re right about the reduced amount of HTTP requests; obviously, when you merge two files into one, that’s one request less.
However, several browser vendors are working to implement functionality which only loads separate print stylesheets when they are required, i.e. when the page is actually being printed. (The same goes for any other media type. In other words, only stylesheets that were designed for the currently rendered media will be loaded.)
Therefore, placing screen and print styles in separate files might save a lot of bandwidth. After all, the internet is mostly a screen medium.
It might be interesting to consider this in the future.
Great post!
Geert De Deckere —June 11, 2009 ∞
Thanks for your comment, Mathias. Good to hear browsers are going in the direction of only downloading applicable style sheets initially. It is no more than a logical step forward.
The article about delay loading print css is interesting; however, requiring javascript to make print styles work is a considerable downside.
Federico Capoano —December 7, 2009 ∞
Hey, cool!
Didn’t know this.
Will it work on every browser?
Thanks
Infotech Systems —December 7, 2009 ∞
Is it possible to make a script that will unite all css styles in one file, and then to check for browser type and according to the type of browser select css code in the file?
Bramus! —December 15, 2009 ∞
And what about or good old pal IE? Yeah, even IE8 can’t deal with it well (see http://en.wikipedia.org/wiki/Comparison_of_layout_engines_%28Cascading_Style_Sheets%29#Grammar_and_rules)
Mathias Bynens —January 7, 2010 ∞
Bramus, and where on that page does it say
@media printdoesn’t work in IE?Here’s a news flash: it does work, and has worked since IE 5.5.
The reason it says “Incorrect” in the Trident column /
@mediasupport row on that Wikipedia page, is because IE doesn’t fully support all media types specified in CSS2 (onlyall,screenandprint).