Search code examples
csslessmedia-queries

Using class set in media query as mixin in less


I am trying to reuse a set of classes set inside a media query as mixins to use throughout a website instead of embedding un-semantic class names in html.

Here is an example of my problem.

@media (min-width: 1000px) {

    .foo{width:120px;}
    .foo-2{width:150px;}
}
@media (max-width: 999px) {

    .foo{width:110px;}
    .foo-2{width:120px;}
}

.bar{.foo;}
.bar-2{.foo;}
.bar-3{.foo-2;}

the .bar-X will never get any styles applied. I can guess that this is happening because LESS doesn't create .bar-X inside media queries, so nothing will ever be applied.

Is this a bug in LESS, or something I can never achieve? A workaround to this would be ideal.


Solution

  • Your problem is a common misconception. LESS does not process the @media query, the browser does after LESS has done its work. LESS can only create the CSS code that the browser is going to read. So the @media is "meaningless" to LESS, it is just like any other selector (.someClass div table, etc.), it only processes what the @media is going to serve to the browser.

    So that means you need to put all your code that changes for the @media in the @media block. But you also don't want a bunch of repeated code. So instead, create a master mixin to set your @media code, and then call that mixin from the media queries:

    .makeFooGroup(@w1, @w2) {
        .foo {width: @w1}
        .foo-2{width: @w2}
        .bar{.foo}
        .bar-2{.foo}
        .bar-3{.foo-2}
    }
    
    @media (min-width: 1000px) {
        .makeFooGroup(120px, 150px);
    }
    @media (max-width: 999px) {
        .makeFooGroup(110px, 120px);
    }
    

    Produces this css:

    @media (min-width: 1000px) {
      .foo {width: 120px;}
      .foo-2 {width: 150px;}
      .bar {width: 120px;}
      .bar-2 {width: 120px;}
      .bar-3 {width: 150px;}
    }
    @media (max-width: 999px) {
      .foo {width: 110px;}
      .foo-2 {width: 120px;}
      .bar {width: 110px;}
      .bar-2 {width: 110px;}
      .bar-3 {width: 120px;}
    }
    

    For some further info I've given on LESS and @media related to this, see:

    1. CSS pre-processor with a possibility to define variables in a @media query
    2. Media Query grouping instead of multiple scattered media queries that match