Less: Can You Group a CSS Selector with a Media Query

LESS: Can you group a CSS selector with a media query?

I'm not a 100% certain of the output you are going for, but this LESS only defines the color red once, and applies it to both:

@tablet: ~"(min-width: 768px) and (max-width: 980px)";
body {
aside { color: blue }

&.homepage {
aside { color: red }
}

@media @tablet {
.homepage;
}
}

Yields this CSS:

body aside {
color: #0000ff;
}
body.homepage aside {
color: #ff0000;
}
@media (min-width: 768px) and (max-width: 980px) {
body aside {
color: #ff0000;
}
}

Can I combine CSS media queries with CSS selectors?

I've now played about with this a bit more and come up with a solution that doesn't duplicate the code in the same way:

.article-sidebar, .article-sidebar-bottom {
text-align: left;
padding-top: 46px;
border-top: 1px solid #eeeeee;
padding-left: 5%;
padding-right: 5%;
}

@media (min-width: 992px) {
.article-sidebar {
float: right;
max-width: 28%;
border-top: initial;
padding-left: initial;
padding-right: initial;
}
}

I think my problem was that I was thinking 'top down', i.e. starting with large screens and then adding support for smaller devices in the media query. If it's the larger screens that are handled by the media query then I think it becomes much neater.

Thanks to everyone who's commented so far. Although I've found a better solution to my own problem I'd still be interested in an answer to the original phrasing of the question... i.e. whether anyone can provide the syntax to use the same style for different combinations of class & media query (if this syntax exists...)

Defining CSS media queries within selectors

Short answer, no. There are no performance issues in defining media queries within CSS selectors.

But let's dive in...

As described in Anselm Hannemann great article Web Performance: One or Thousands of Media Queries there is no performance loss from adding the media queries in the manner you are.

As long as the same set of media queries are being used in each selector there is no major performance hit other than your CSS file might be a bit larger.

.foo {
@media (min-width: 600px) { ... }
@media (min-width: 1000px) { ... }
@media (min-width: 1500px) { ... }
}

.bar {
@media (min-width: 600px) { ... }
@media (min-width: 1000px) { ... }
@media (min-width: 1500px) { ... }
}

However, it does matter how many different media queries you use. Different being different min-widths, max-widths and so on.

Grouping styles by selector or media query first

After doing ample research, I've personally arrived at this answer

  1. Keeping the styles for the same selector at different breakpoints is good for the developer experience - it keeps CSS more maintainable to be able to see a selector's behavior at every breakpoint all in the same place.
  2. In vanilla CSS, the pattern for doing this can be a bit ugly and unwieldy - if it's not minified, it can also lead to some performance issues due to duplicate media queries. Ruling: avoid grouping selectors and their media query counterparts in vanilla CSS - it's probably more trouble than it's worth.
  3. If you're using SCSS, absolutely nest your media queries inside your selectors. It's clean and more maintainable. With the right compilation you avoid duplicate media queries, avoiding the earlier discussed performance issues. Learn more here

Is there an advantage in grouping css media queries together?

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

Why media queries has less priority than no media queries css

This has to do with the way the Cascade in CSS works. When two conflicting rules target the same element, the browser uses the rules of the cascade to determine which one to apply.

Selector specificity is the most important part of this: styles with a more specific selector will override those with a less-specific selector... but
media queries do not change the specificity of your selectors. This means that your two selectors have the same specificity. When that happens, the one appearing later in your stylesheet will override the earlier one.

Your easiest and best fix is to swap the order of your rulesets:

.logo img{
width: 100%;
}

@media screen and (min-width: 100px) and (max-width: 1499px) {
.logo img {
width: 120%;
}
}

This way, the media query comes later, and will override the earlier rule when the media query matches the viewport size.


If that's not an option for some reason, you will need to increase the selector specificity of the rule you want to win. Changing it to the following would work:

@media screen and (min-width: 100px) and (max-width: 1499px) {
.logo img {
width: 120%;
}

}
.logo a img{
width: 100%;
}

This way the selector now has two tags and a class, or [0,1,2], making it more specific than one tag and one class, or [0,1,1] (the zero in each of those indicates no ids, which are highly specific).


Do not use !important to fix specificity issues like this. If you need to override the style again elsewhere, the only way to do it is to add another !important. This will eventually lead to !importants all over the place, and then you will still need to deal with the specificity of the selectors.

using media queries with LESS

CSS supports multiple identical media queries, if you like, but CSS doesnt support nesting.

LESS, on the other hand, does support a few methods for nesting media queries. You can read about it here: http://lesscss.org/features/#extend-feature-scoping-extend-inside-media

Example:

@media screen {
@media (min-width: 1023px) {
.selector {
color: blue;
}
}
}

Compiles to:

@media screen and (min-width: 1023px) {
.selector {
color: blue;
}
}

LESS also supports nesting media queries below selectors like this:

footer {
width: 100%;
@media screen and (min-width: 1023px) {
width: 768px;
}
}

Compiles to:

footer {
width: 100%;
}
@media screen and (min-width: 1023px) {
footer {
width: 768px;
}
}

If this doesnt answer your question, then please post the relevant part of your LESS file(s).

Is it best to group similar media queries at the end of the CSS or to just keep them separated within the CSS?

Media queries were introduced in CSS3 are used for responsive CSS over different media types. Since usually the CSS code itself is applied for describing the presentation of the document or page, responsiveness is a separate feature altogether, so usually they are kept separate at the end of the CSS formatting codes. However, let me answer this question by stating the usage of both of the formats mentioned in the question.

At the end of code

Most templates of CSS available online usually keep their media queries at the bottom of the entire code making it easier to access and work with the responsiveness feature. Whenever the focus is more on "chasing device-widths" then this type of coding practice helps.

As observed, this allows to group together many basic CSS attributes that are applied over many elements.

Also, considering the cascading nature of CSS, the styling below usually (not always, refer this to know more) overwrites the styling present above. With @media queries present at the bottom of the stylesheet, it allows easy overwriting of relevant styles present above.

Finally ,as mentioned by @rguttersohn, media queries along with @keyframes are kept at the end with @keyframes usually above @media. This makes coding cleaner and easier to comprehend by others as well.

Below relevant styling counterparts

If styling is more layout-centric, it's highly useful to place @media queries next to their styling counterparts. This allows ease in editing the style and its corresponding @media query both in a single go.

This does mean that there is slightly more code, but these too can be cut down by grouping at breakpoints and section ends.

This type of styling is rarely seen in templates available online, however it's an ongoing trend.

To Summarize: I personally am of the opinion to keep all of the @media queries together at the bottom, but if I had to divide the labor of styling, I would opt for keeping the styles and @media queries together.

Also, given the broad and opinionated scope of this question, I think no answer can determined as right or wrong. I hope this answer brings enough light and information to the question.

Media Query grouping instead of multiple scattered media queries that match

First, your solution given in the question certainly has some usefulness to it.

One thing I thought, however, was that it would be nice to define all the media query variables "near" one another (your solution would have them under each media query call). So I propose the following as an alternative solution. It also has drawbacks, one being perhaps a bit more coding up front.

LESS Code

//define our break points as variables
@mediaBreak1: 800px;
@mediaBreak2: 1024px;
@mediaBreak3: 1280px;

//this mixin builds the entire media query based on the break number
.buildMediaQuery(@min) {
@media only screen and (min-width: @min) {

//define a variable output mixin for a class included in the query
.myClass1(@color) {
.myClass1 {
color: @color;
}
}

//define a builder guarded mixin for each break point of the query
//in these is where we change the variable for the media break (here, color)
.buildMyClass1() when (@min = @mediaBreak1) {
.myClass1(red);
}
.buildMyClass1() when (@min = @mediaBreak2) {
.myClass1(green);
}
.buildMyClass1() when (@min = @mediaBreak3) {
.myClass1(blue);
}

//call the builder mixin
.buildMyClass1();

//define a variable output mixin for a nested selector included in the query
.mySelector1(@fontSize) {
section {
width: (@min - 40);
margin: 0 auto;
a {
font-size: @fontSize;
}
}
}

//Again, define a builder guarded mixin for each break point of the query
//in these is where we change the variable for the media break (here, font-size)
.buildMySelector1() when (@min = @mediaBreak1) {
.mySelector1(10px);
}
.buildMySelector1() when (@min = @mediaBreak2) {
.mySelector1(12px);
}
.buildMySelector1() when (@min = @mediaBreak3) {
.mySelector1(14px);
}

//call the builder mixin
.buildMySelector1();

//ect., ect., etc. for as many parts needed in the media queries.
}
}

//call our code to build the queries
.buildMediaQuery(@mediaBreak1);
.buildMediaQuery(@mediaBreak2);
.buildMediaQuery(@mediaBreak3);

CSS Output

@media only screen and (min-width: 800px) {
.myClass1 {
color: #ff0000;
}
section {
width: 760px;
margin: 0 auto;
}
section a {
font-size: 10px;
}
}
@media only screen and (min-width: 1024px) {
.myClass1 {
color: #008000;
}
section {
width: 984px;
margin: 0 auto;
}
section a {
font-size: 12px;
}
}
@media only screen and (min-width: 1280px) {
.myClass1 {
color: #0000ff;
}
section {
width: 1240px;
margin: 0 auto;
}
section a {
font-size: 14px;
}
}


Related Topics



Leave a reply



Submit