Nested CSS3 media queries in SCSS/Sass - css

I'm working on a responsive web-site which is based on Bootstrap. I use SCSS/Sass and Compass to optimize the CSS workflow. And in my Sass code I have the following:
$sm-screens-and-wider: "screen and (min-width: 768px)";
$lg-screens: "screen and (min-width: 1200px)";
#media #{$sm-screens-and-wider} {
.search-copyright-tab .copyright {
font-size: 19px;
#media #{$lg-screens} {
font-size: 21px;
}
}
}
this results into the following CSS:
#media screen and (min-width: 768px) {
.search-copyright-tab .copyright {
font-size: 19px;
}
}
#media screen and (min-width: 768px) and (min-width: 1310px) {
.search-copyright-tab .copyright {
font-size: 21px;
}
}
Note the repeating min-width in the second media-query. That is valid CSS code and works quite fine in modern browsers. But respond.js fails parsing it, since it's regex grabs the first value and IE8 renders content in wrong way.
I have googled a lot and haven't find any mentions of issues like that. I found even why it fails with responds.js:
minw : thisq.match( /\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ),
this regex only considers first found min-width in media-query statement (thisq).
So currently I have several possible solutions (arranged by severity):
Use max-width media-queries for such case, though braking mobile-first concept;
Change my SCSS/Sass file structure and make it less readable by separating the same class styles;
Fork and modify respond.js library;
Post-process the output of Sass and rewrite the broken entries.
To be honest I'm not happy with any of these solutions, and I have a feeling that Sass should process such cases himself and it is my weird Sass use-case, which forces it behaves like that (except using Sass with Bootstrap, which is Less powered). Can anybody point out the easier/better solution here?

It makes sense to merge identical items (screen) but not the min-widths as they are different. I've found SASS actually has very little understanding of what CSS rules are valid by design, in order to future-proof itself.
I wouldn't be comfortable using a merge query that has multiple queries like that not only because of the issue you're having but because it's precious wasted bytes that still have to go over the wire.
I would use #include to define the #media queries as it's a little nicer than the string method you're using and do it like this, which I feel is just as readable as your solution without the problems:
// The mixins can be defined in some shared file
#mixin media-gte-sm {
#media screen and (min-width: 768px) {
#content;
}
}
#mixin media-gte-lg {
#media screen and (min-width: 1200px) {
#content;
}
}
.search-copyright-tab .copyright {
#include media-gte-sm {
font-size: 19px;
}
#include media-gte-lg {
font-size: 21px;
}
}

Related

Media query for mobile is controlling desktop style

I'm building the site for a desktop with the CSS below for an element. . .
.give-donation-level-btn {
font-size: 16px;
When I apply the media query for mobile, it controls the desktop style as well.
#media screen and (max-width: 767px) {
.give-donation-level-btn {
font-size: .9rem !important;
}
With the !important declaration for the query, I thought that style would be applied only to screens ≤. What am I missing?
You're missing out a curly bracket.
#media screen and (max-width: 767px) {
.give-donation-level-btn {
font-size: .9rem !important;
}
}
Don't worry, this only happens to the best programmers ;).
I hope this solves the problem.
It looks like device-width was the culprit. max-device-width worked, though I'm uncertain why.

CSS order of precedence with

So I am currently building a system which allows the CSS to be stored within MariaDB (MySQL) database. I am currently going over the logic flow for this, and wondered what is preferable in terms of media queries.
So, what I really want to know is;
Should I load the media queries at the top of the CSS file or the non media query selectors at the top of the CSS file? Which one is preferable? Or is this subjective, because of how things are overwritten by code further down the page.
Thanks in advance everyone.
Actually this could be subjective, however, there is the best practice for that.
What I prefer is to keep your normal CSS selectors in one file like app.scss and keep your media-query in another file like responsive.scss while developing. so even would be better to make all modules separate. However, at the end, you need to concatenate them and the best would be to keep your normal CSS selectors first and then load Media-Query right after that.
#import 'custom/app';
#import 'custom/responsive';
The reason to follow this practice is that CSS will be read from TOP to BOTTOM, thus, you may understand that all your media query rules will be implied right after their original rules and it won't affect responsiveness.
All in all, that could be very subject and may other developers would prefer to write their CSS and media query CSS rules right after each other but that would be obvious that they most likely to code media query right after main rules. TO clarify, I will write only one sample code in my perspective:
GOOD
body {
background-color: lightblue;
}
#media only screen and (orientation: landscape) {
body {
background-color: lightblue;
}
}
BAD
#media only screen and (orientation: landscape) {
body {
background-color: lightblue;
}
}
body {
background-color: lightblue;
}
Update:
I'd like to also mention two different approaches.
Mobile First
Your small screen styles are in your regular screen CSS and then as the screen gets larger you override what you need to.
body { background: lightblue; }
#media (min-width: 480px) {
body { background: lightblue; }
}
Desktop First
Your large screen styles are in your regular screen CSS and then as the screen gets smaller you override what you need to.
body { background: lightblue; }
#media (max-width: 480px) {
body { background: lightblue; }
}
It doesn't matter. For practical purposes i put the media queries after the modelled element but you could put all the queries in the top or in the bottom of the page and it would be indifferent (it won't load faster or slower). For debugging purposes i think it's better my method.
For example:
.box { max-width: auto; }
#media (min-width: 1200px) {
.box {
max-width: 10px;
}
}

Performance impact of multiple responsive declarations

I am not entirely sure of the best way to place declarations such as
#media screen and (max-width: 600px) {
//
}
in my stylesheet. If, for example, I have a block of rules pertaining to some element (say, the sidebar) and I want to include some responsive rules with it, then it is tempting to insert the above code along with all the other rules for the sidebar. But then I might have some other element (say, the header) that also needs to change in some way when the screen width is below 600px. Then I'll end up with several #media screen and (max-width: 600px) declarations scattered up and down my CSS file. But it makes more sense- to me- to prioritize grouping together CSS rules according to the HTML elements they control.
So can I do this? Is there a negative performance impact from having
#media screen and (max-width: 600px) {
.sidebar {
font-size: 12px;
}
}
#media screen and (max-width: 600px) {
.header {
font-size: 16px;
}
}
rather than
#media screen and (max-width: 600px) {
.sidebar {
font-size: 12px;
}
.header {
font-size: 16px;
}
}
?
There is no notable loss of performance using several media queries instead of only one. However, if
you resize or zoom-in/out your browser, there can be a peak of memory and CPU load.
You will not resize your browser, but partially-sighted users needs to zoom your website, etc.
You should consider using a CSS Preprocessor like Less, SASS, or Stylus. A media query can be placed as a CSS property in your rule:
// app.less
#max-width: 600px;
.sidebar {
background: #2c2c2c;
#media screen and (max-width: #max-width) {
font-size: 12px;
}
}
If you can't use a CSS Preprocessor, then don't duplicate your media queries because of maintenance nightmare.
I think it would just bulk up your css file size, but if you minify it, you should be fine. It is best practice though to accomplish as much as you can in as little code as possible.

Does less have the "respond-to" technique like SCSS

http://css-tricks.com/media-queries-sass-3-2-and-codekit/
I recently discovered this technique while reading about scss. I've come to enjoy writing lesscss and I would rather not switch. I was curious as to what options lesscss has to accomplishing a similar technique? I really like the idea of writing media queries inside the primary class/id declaration.
#mixin breakpoint($point) {
#if $point == papa-bear {
#media (max-width: 1600px) { #content; }
}
#else if $point == mama-bear {
#media (max-width: 1250px) { #content; }
}
#else if $point == baby-bear {
#media (max-width: 650px) { #content; }
}
}
.page-wrap {
width: 75%;
#include breakpoint(papa-bear) { width: 60%; }
#include breakpoint(mama-bear) { width: 80%; }
#include breakpoint(baby-bear) { width: 95%; }
}
UPDATE
I have found this answer http://blog.scur.pl/2012/06/variable-media-queries-less-css/ my only critism is how can I make it so that the media queries arnt redundant? how would I make this all compile into 1 mediaquery block?
This is how I do my media queries in LESS, utilising query bubbling as outlined in the article you linked to:
#palm : ~"screen and (max-width: 40em)";
#lap : ~"screen and (min-width: 50em)";
#desk : ~"screen and (min-width: 60em)";
.some-class {
color: red;
#media #lap {
color: blue;
}
}
Unfortunately though there is no way to have it all compile down to one media query block. This may also be the case with SASS/SCSS. The only reason this could be a problem is that is increases file size.
However you shouldn't worry about that. Why? The repetition of multiple media query blocks is negated by GZIP (more repetition == better compression). So providing your server is encoding with GZIP (most do, if not you should be able to enable it, it's worthwhile) you will not see any/much increase in file size.
Finally, even discounting GZIP, I still wouldn't want it to compile to one media query block. On any large CSS code base the proximity of having media queries next to the selectors is useful and desirable

Is there an advantage in grouping css media queries together?

(this may have been answered already - couldn't find the answer though)
The traditional #media query override tends to group all the override for one size/medium under the same bracket group.
e.g.
.profile-pic {
width:600px;
}
.biography {
font-size: 2em;
}
#media screen and (max-width: 320px) {
.profile-pic {
width: 100px;
float: none;
}
.biography {
font-size: 1.5em;
}
}
In Sass, there's a really nifty way to write #media query overrides within the nested declaration, like so:
.profile-pic {
width:600px;
#media screen and (max-width: 320px) {
width: 100px;
float: none;
}
}
.biography {
font-size: 2em;
#media screen and (max-width: 320px) {
font-size: 1.5em;
}
}
now, when compiled, sass doesn't group the #media query blocks together, so the output ends up being something like this:
.profile-pic {
width:600px;
}
#media screen and (max-width: 320px) {
.profile-pic {
width: 100px;
float: none;
}
}
.biography {
font-size: 2em;
}
#media screen and (max-width: 320px) {
.biography {
font-size: 1.5em;
}
}
I've used this technique for a recent project and when you apply that principle to a much bigger project you end up with multiple #media query section disseminated throughout your css (i've got about 20 so far).
I quite like the sass technique as it makes it easier to follow the flow of overrides (and also makes it easier to move things around).
However, I'm wondering if there is any disadvantage in having multiple #media section through the CSS, particularly performance wise?
I've tried the chrome css profiler but I couldn't see anything specific to #media queries.
(More info on #media in sass on this page)
A bit late to the party, but based on the tests below the performance impact seems to be minimal. The test shows the rendering times for an example page with 2000 separate and combined media queries, respectively.
http://aaronjensen.github.com/media_query_test/
The main benefit seems to be in file size more than anything else - which, if you're compressing your CSS for production, will be substantially reduced anyway.
But ultimately, as the linked post below puts it:
"If you have 2000+ media queries in your CSS, I think that you may want to reconsider your UI development strategy versus using a gem to re-process your CSS."
Blog post detailing the issue: https://web.archive.org/web/20140802125307/https://sasscast.tumblr.com/post/38673939456/sass-and-media-queries
I would assume that just having to run the media query check once (and then loading all the styles within it) would be less taxing than checking on every selector but I've got no hard evidence of this. If you get the Canary release of Chrome there are media query tools in there.
As you're using SASS this article might be of some interest - http://css-tricks.com/media-queries-sass-3-2-and-codekit/

Resources