I assume that, just like the media queries that are used in link tags, the media queries which we define in our CSS files are parsed/overwritten or omitted by the browser according to their media query rules (Actually I know that, although the CSS files requested by the link tags with unmatched media are anyway downloaded, they are not render blocking the browser).
So, from the CSSOM build optimization stand point, isn't it better to separate the generic CSS rules that applies to all screen devices from the mobile specific CSS rules and encapsulate the mobile specific rules in a max-width media query? So that browser will parse less CSS to build CSSOM without the need of overwriting them for tablet, desktop etc. I wonder if that would affect the building of CSSOM performance or is it just overkill?
<link> tags with unmatched media queries are download with low priority so that they don't block page rendering, but are still downloaded in order to be available in case media properties change (for example by rotating a smartphone or by zooming out a desktop browser). There is an advantage in having separate stylesheets for different media types, but there is also a disadvantage in creating multiple HTTP requests.
Media blocks inside a stylesheet are already downloaded and I would assume that they are compiled anyway, so it's not really the same as a media query in the tag. But if a certain set of rules is only relevant to a certain width and is always overriden in wider screens, it makes sense to tell the browser that by encapsulating it inside a media query. It's not just about the original page rendering but about any change to the window or to the DOM that requires a redraw - the less rules the browser would need to evaluate, the faster it would be.
While refactoring my main css into a modular approach I'm using #media all {} to wrap css modules in the IDE. This approach makes it much more easy to scan the files' content as we can't use a preprocessor like less or sass right now.
My only concern is that all those media queries (one for each css module / set of coherent selectors) might cause a performance hit while rendering the site. I am NOT concerned about the file size of our css files as this is a minor issue with a slim modular css framework and proper zipping.
Do media queries like #media all {} have an impact on the performance (both on desktop and mobile/other) devices if used to frequently?
The answer is no... and yes. Having a bunch of media queries will not make the site harder to render. But more lines of code makes a file larger and that technically takes longer to load. Still this isn't much of a performance hit.
But when resizing the browser, it will be taxing on the browser to recalculate a bunch of different mq settings. Read more here: Web Performance: One or thousands of Media Queries?
But...if you want to be proactive about this, with out a preprocessor, just use Pleeease. Pleeease gives you preprocessor like ability with vanilla css. AND it provides a PostProcessor function called mqpacker. It will find all similar media queries in your style sheet and merge them into related media queries. But again, if you are gzipping your stylesheet on the server, you don't need to worry about it.
Good luck! Stay awesome!
My current Website-Design is built with the Bootstrap responsive framework. It uses several custom fonts, which make up about 50% of the document size. The fonts are included via CSS, the way of inclusion can not be changed.
My goal now is to stop mobile devices from requesting these fonts, in order to reduce their bandwidth consumption.
Is there a CSS way, like #media (min-width: 480px), to not load the fonts in the responsive layout?
In most implementations, background images that are referenced in CSS media queries get pre-downloaded. (Unless you do some fiddling with your use of display:none;, but that won't be supported in all browsers.)
The same applies to any fonts you've included via media queries — even if they're specified for a larger/different viewport.*
Why?
This allows for a smoother transition if viewport size is changed, e.g. from portrait to landscape.
Solution?
Considering the constraints you mentioned, I don't see a clean way to do this only with CSS. You could do something with JS (but make sure it degrades gracefully), or PHP.
But the easiest ways to reduce HTTP requests and how much your visitors have to download include doing one or all of the following:
Using less fonts, or web-safe fonts instead.
Using a CDN for fonts.
Including 'minified' font files that only have the characters you'll
be using them for.
Check out Google Web Fonts for the latter two.
If you expect or get a lot of mobile traffic that's important for the site, it's always worth re-thinking a website's design and markup from a mobile-first approach: what's necessary and what isn't. (That approach can often help to even reduce clutter on the desktop version of your site.)
* The fiddling approach could be useful for fonts too, but you'd have to do browser testing yourself, as so far it's undocumented.
You could create two different stylesheets, one for mobile and one for desktop, then use PHP browser detection or various other methods to see if the user is on a mobile device or desktop device, and provide them with the corresponding stylesheet.
Take a look at the PHP get_browser function: http://php.net/manual/en/function.get-browser.php
All background images aren't necessarily pre-downloaded if referenced in your media queries -
http://timkadlec.com/2012/04/media-query-asset-downloading-results/
perhaps this technique would also work for fonts too. Not if you're using anything that'd need JS (like typekit, google) your font's will be requested because of the JS anyways afaik.
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!"
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.
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.
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...
<script src="bork.js" type="bork/bork"></script>
<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.
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).
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).
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.
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>
As this article suggesting
http://www.456bereastreet.com/archive/201002/css_efficiency_tip_use_a_single_stylesheet_file_for_multiple_media/
or different external CSS for different media would be better option?
in terms of maintainability, site performance.
Basically, if you can programmatically add CSS files to your client based on the media (as long as you only send ONE css file in the end), then yes, build multiple CSS files based on the #media.
If you cannot add css programmatically, then I would suggest combining them into a single css file (since you have to send them all to the client regardless), thus reducing the number of http requests by the client.
fewer http requests = faster page loads.
Combined Style Sheet Pros:
Optimal/Fast
Good reduction in size after compression
and yes fewer http requests
Combined Style Sheet Cons:
Messed up; all different style sheets in one place
Difficult to maintain
Less readable
You could use media-dependent #import rules like so:
#import url("print.css") print;
#import url("projection.css") projection, tv;
it should work in everything but IE5-7 (as per: http://www.westciv.com/wiki/CSS_Guide:_Media#mediaspecific )
I can't test for IE8 so you might be disappointed there too.
it would result in a very small initial CSS load, then upload just the needed stylesheets based on media.