47

If I specify a CSS link with an unsupported media type ("bork") it still gets downloaded by every browser I've tried (including both desktop and several mobile browsers).

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

And it gets worse...

If the file bork.css @imports an other CSS file (also with an unsupported media type) that second CSS file also gets downloaded.

/* Inside "bork.css" */
@import url("bork2.css") bork, bork;

Why!?

My first assumption was that some browsers might be searching for nested @imports or @media blocks with media types that they supported - and then apply the styling rules contained within those files...

/* Inside "bork2.css" */
@import url("all.css");
@media all {
  /* rules */
}

...but as far s I can tell, not a single browser does that. (Fortunately, as that would be a bug.)

So all this downloading seems wholly redundant - unless there's some explanation that I've missed all along.

EDIT: What I'm trying to understand is that motivates browser makers to go:
"Hey! We're trying to make our browser crazy fast! Let's download a bunch of CSS files that we have no intention of applying, and halt the loading of other resources meanwhile!"

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Már Örlygsson
  • 14,176
  • 3
  • 42
  • 53

7 Answers7

13

I think the answer is this:

Browsers are allowed and encouraged to parse media descriptors - no matter what the descriptor - as a way to make them future friendly

Future versions of HTML may introduce new values and may allow parameterized values.

*From: http://www.w3.org/TR/html4/types.html#h-6.13

In this way, media may one day include 3d-glasses or other descriptors, including bork ;-)

EDIT:

The latest CSS3 spec on media queries says this, which supports the above, to a certain degree:

Unknown media types evaluate to false. Effectively, they are treated identically to known media types that do not match the media type of the device.

*From: http://dev.w3.org/csswg/css3-mediaqueries/#error-handling

So they are treated as known and downloaded to be used, just not at that time/for that device.

Jason Gennaro
  • 34,535
  • 8
  • 65
  • 86
  • 4
    Future introductions of new media values won't automatically make them apply in today's browsers. Why download those CSS files today? – Már Örlygsson Jun 10 '11 at 20:04
  • I would guess that the browsers want to be backwards compliant, in the event that new descriptors are developed. – Jason Gennaro Jun 10 '11 at 20:08
  • 5
    This document describes parsing the value of the media attribute, but mentions nothing about browsers actually downloading the file if the value does not apply to the current media. – Wesley Murch Jun 10 '11 at 20:11
  • 2
    You mean backwards compatible with future changes? That seems very, ehm, backwards. ;-) – Már Örlygsson Jun 10 '11 at 20:12
  • @Wesley. Yes, agreed, but that would also explain why browsers would dowload... because there are no set values. @Már Örlygsson Agreed ;-) – Jason Gennaro Jun 10 '11 at 20:17
  • @Már Örlygsson Added some more info above re the CSS3 spec. – Jason Gennaro Jun 10 '11 at 21:01
  • @Jason that doesn't really address the question of *why* browsers download CSS for media types that don't apply – Jeff Jun 10 '11 at 21:06
  • @JasonGennaro: Then what would explain why my print styles don't appear on screen? If the browser can tell the difference, why download the contents of the file? – Wesley Murch Jun 10 '11 at 21:28
  • @Wesley. `Print` is a known value and is not mixed with `screen` or other values and is applied when needed (at print). However, as the spec says, unknown media types are evaluated as known but not matched to the device. – Jason Gennaro Jun 10 '11 at 21:33
  • "not matched to the device" to me implies that `bork` media (an unknown type) would not be applied to screen - only downloaded and "discarded". OP was not particularly clear on whether or not the CSS was being applied (I assume it wasn't), so that makes sense. Now I'm thinking about moving all media specific CSS (including print) into a file with `all` as the media type, and using media queries within the file (rather than separate files), since it seems to all download anyways. This seems like not-that-great of an idea, but from what we've learned so far, I can't see a reason not to. Can you? – Wesley Murch Jun 10 '11 at 21:46
  • this behavior is also present in older browsers, that don't know about CSS3 – Már Örlygsson Jun 10 '11 at 22:22
  • @Már Örlygsson CSS3 is just reiterating the CSS2 spec, afaik. And that first para I quoted is from the HTML4 spec... way back! – Jason Gennaro Jun 10 '11 at 22:34
  • This doesn't explain why browsers apparently download stylesheets with already W3C specified, but currently non-applying media types. Like downloading a print stylesheet when you're not printing. – DanMan Jun 10 '11 at 22:39
  • that first HTML4 quote seems irrelevant. CSS2.1 has no similar clauses. And even then this still seems like a stretch, why slow the page-load with HTTP requests that any sensible person would agree are redundant? – Már Örlygsson Jun 10 '11 at 22:48
  • @Már Örlygsson I don't think the HTML spec is irrelevant. It shows there are no set values for the media type in a style link, ergo anything can be allowed. – Jason Gennaro Jun 10 '11 at 23:11
9

Thinking that the real reason that they load all media queries is because many devices CHANGE their responses to these queries after load.

Imaging an iPhone5 that is in portrait on page load (reporting 'width' as 640px, but not 'portrait, unfortunately the iSeries do not support those queries)... you then decide to turn the iPhone sideways, and the browser now activates the pseudo landscape mode (again, triggered from width @ 1126 rather than 'landscape').

Most likely, a responsive web design has been designed to feed different stylesheets to a browser displaying at 640 (rather narrow, probably a phone/tablet) than it does to a browser displaying at 1126 (more likely a laptop).

If it hadn't bothered to load the additional media query sheets, then it would suddenly have to stop, shoot an http request out, wait for the sheet to load, and then parse it to display. This could result in a rather ugly delay.

As most browsers follow a pattern of code reuse, and the core chunks of Webkit or Gecko, for example, may not be aware whether they are on a laptop or a tablet (as if those lines aren't beginning to blur anyway), it simply loads each media query regardless of whether or not they choose to display it.

While this saves each browser from looking bad, overall it breaks a good chunk of the utility behind media queries.

A cell phone or a cheap android tablet shouldn't have to download the additional files (especially on limited data plans) that it will simply never need.

At the moment, my designs DO use media queries, but I use them sparingly. Much of the media queryishness on my sites is implemented through javascript loading of required files to eliminate this waste. The remaining queries are used in cases of javascript being shut off, or for sheets that need to be loaded 'just in case' (my 640px layout, for example, is usually always loaded, as most devices might display it in one situation or another).

If anyone out there has a better, cleaner, method of handling this, please let me know.

In the meantime, if you can think of a simply to implement functionality that might circumvent this (maybe android-style manifests built into browsers?), you might want to drop a line to the Mozilla or Chromium teams... seem like they could use a hand on this one.

Steve
  • 91
  • 1
  • 1
  • Surely a browser knows its window size and can thus safely ignore stylesheets marked for larger windows only. Additionally, the browser has already reached the "mobilefriendly" `` declaration before it sees the CSS ``s which further obviates the need for loading CSS for unsupported screen media. – Már Örlygsson Oct 22 '12 at 12:19
  • ...also note that browsers always load `media="bork"` stylesheets even though they have no intention of ever using those styles (because `bork` is not a supported media type) – Már Örlygsson Oct 22 '12 at 12:20
4

After thinking about this more, I formed the theory that there might be a general "rule" at work - that any stylesheet, image or script would be downloaded, no questions asked, regardless of the specified mime-type or media attribute.

However, after a quick test, the results are a bit ambigious...

  1. <script src="bork.js" type="bork/bork"></script>
  2. <script src="bork2.js" type="text/bork"></script>

Chrome 12 downloads neither.
IE8 downloads #2.
Firefox 4 downloads both.
Opera 11 downloads both.
Safari 5 Win downlads both.

Still no parsing or running takes place in any of the browsers. A javascript alert(); inside either file does not run. And this is slightly different from the CSS loading case, because there the browsers parse the bork-media CSS code for @include directives and downloads those resources recursively.

Már Örlygsson
  • 14,176
  • 3
  • 42
  • 53
2

The answer may come down to media queries. Consider these for example:

<link rel="stylesheet" media="(min-width: 300px)" href="example1.css" />
<link rel="stylesheet" media="(min-width: 1000px)" href="example2.css" />

If a browser with a window size of 600px is used, the example1.css stylesheet will be applied. If the window is resized to 1200px then the stylesheet example2.css can be immediately applied without waiting for it to download first.

Its worth noting that even though the non-matching media query stylesheet is still downloaded, it does not block rendering while it is downloading (normally all CSS files need to be downloaded before rendering will begin).

Richard Rutter
  • 131
  • 1
  • 2
  • 2
    _"Its worth noting that even though the non-matching media query stylesheet is still downloaded, it does not block rendering while it is downloading"_ - In other terms, the non-matching stylesheets are loaded asynchronously. Good catch. Could you cite a source? – John Weisz Aug 05 '15 at 15:00
1

So if you really do not want to download the CSS file until something happens, the you can try to validate when the page loads if certain conditions are meet and if so, then you can do a "lazy load" and store the commented code (type 8 element, that would be in this case your style tag) inside a newly created style tag child, and that will make the browser to validate the newly created content and will download the CSS file for the style to work.

Any question you may face trying to implement it, do not hesitate in asking some clarification, maybe i can help you with your problem. It works for almost anything (images, js, css, etc..) you do not want to be downloaded or processed until something occurs or some restrictions are meet.

I already tested it and IT WORKS :D, so you can use this code to start, hope it helps

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>TEST CODE</title>
<script type="text/javascript"> 

    function test(){
        var elems = document.body.childNodes;
        alert(elems);
        for (var i = 0, il = elems.length; i < il; i++) {
           var el = elems[i];
           alert(el.nodeType);
           if (el.nodeType == 8) {
           var style = document.createElement('style');
           style.innerHTML = el.nodeValue;
           document.getElementById("css").appendChild(style);
           break;
           }
        }
    }
 </script >

 <style id="css">
 </style>
 </head>
 <body onload="test()">
 <!--@import url(red.css) (min-width:400px) and (max-width:599px);-->
 </body>
 </html>
Jorge Aguilar
  • 3,442
  • 30
  • 34
1

Sometimes, it's necessary to consider the prosaic answer. It's possible that all stylesheets are downloaded by browsers simply because the authors of each browser only really consider the case where there is a single (master) stylesheet when optimizing for speed, and the practice of a lot of sites of having a single stylesheet encourages this behavior. If nobody is testing for it, it's almost certainly not a case that's being optimized, as people prefer to work on results that are visible (or at least measurable). Maybe your question will encourage someone to change the testing regime…

Also, I'd venture that the overwhelming majority of sites' stylesheets are static documents, and so capable of being very highly cached (and delivered by CDN too, if the site owners choose to pay).

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • 1
    +1 Interesting theory, but it begs the question why *not one* browser (including mobile browsers that allow turning off images and script files) has decided to skip unsupported stylesheets. Print stylesheets are quite common and virtually no mobile phones support printing. – Már Örlygsson Jun 13 '11 at 18:04
1

The only logical reason I can think of is that when you are changing dynamically (javascript) the faulty attribute's value of the <link> element to a recognized one, the file must be available immediately.
In fact in certain cases it could be considered a feature if you wanna load the file but defer its appliance for later.

Knu
  • 14,806
  • 5
  • 56
  • 89