91

It would be nice to wrap css-styles for different resolutions within some css-classes using less.

I'd like to do something like:

footer {
  width: 100%;
}

.tablet {
  footer {
    width: 768px;
  }
}

.desktop {
  footer {
    width: 940px;
  }
}

At the end something like this should be the result:

footer {
  width: 100%;
}

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

@media screen and (min-width: 992px) {
  footer {
    width: 940px;
  }
}

.tablet could look somehow like this:

@media screen and (min-width: 768px) {
  .tablet {

  }
}

Hope somebody has a nice idea!

Hai Nguyen
  • 4,059
  • 1
  • 20
  • 16
Andre Zimpel
  • 2,323
  • 4
  • 27
  • 42
  • possible duplicate of [Media Query grouping instead of multiple scattered media queries that match](http://stackoverflow.com/questions/13503862/media-query-grouping-instead-of-multiple-scattered-media-queries-that-match) – ScottS Apr 05 '13 at 16:30
  • Based on the conversation in the comments to @zzzzBov, perhaps we need a bit more clarity in your question about _what_ you are trying to achieve and _how_ you are wanting to achieve it. – ScottS Apr 05 '13 at 17:36

8 Answers8

249

Here is what I've done in my projects:

@desktop:   ~"only screen and (min-width: 960px) and (max-width: 1199px)";
@tablet:    ~"only screen and (min-width: 720px) and (max-width: 959px)";

@media @desktop {
  footer {
    width: 940px;
  }
}

@media @tablet {
  footer {
    width: 768px;
  }
}

This allows you to only define your media queries once and you can use it throughout your less files. Also a little easier to read. :)

Hai Nguyen
  • 4,059
  • 1
  • 20
  • 16
  • 2
    This is awesome, thanks @Hai! A minor issue in Visual Studio is that this warning message is generated on the usage of `@media` in a .less file: "*Unexpected '@' block in the style rule*". It doesn't seem to be a problem though. – Ian Campbell Dec 24 '13 at 19:06
  • Why can't I pull the `@media` into the variables defined in line 1+2 ? ➪ regrettable a pure `@tablet { ...` doesn't resolve then, while a `@media @tablet {...` (resulting in a doubled `@media` of course, if taken into the string. – Frank N Jan 11 '16 at 08:39
123

I completely agree with Hai Nguyen's answer (which has been accepted) but you can clean it up a bit more by doing something like this:

@desktop:   ~"only screen and (min-width: 960px) and (max-width: 1199px)";
@tablet:    ~"only screen and (min-width: 720px) and (max-width: 959px)";

footer{
  width: 100%;
  @media @tablet {
    width: 768px;
  }
  @media @desktop {
    width: 940px;
  }
}

It's essentially the same thing but lets you nest your media queries inside of the original selector. It keeps all css for a specific element together and makes your styles much more modular (vs the split breakpoint approach).

Joseph Yancey
  • 1,498
  • 1
  • 9
  • 7
  • After reading this, I found this Grunt task to group the MQs after the nested MQs are compiled: https://github.com/buildingblocks/grunt-combine-media-queries Removes the bloat. – Jazzy Oct 19 '14 at 00:29
  • This is nice and clean. Can I ask, why the ~ in front of "only...? – Anthony_Z May 01 '15 at 18:08
  • In LESS, a tilde ~ before a string "" literal outputs the string as-is, because it may be a syntax error in pure LESS. – Joseph Yancey May 04 '15 at 18:02
  • 1
    what if you try to make an operation inside of that "literal string"? Let's say that I want to use a variable to contain the screen resolution, for instance: Can I do something like: ~"only screen and (min-width: @mySize - 20px)". I know it does not work, but what's the correct way for doing that? – fablexis Mar 05 '18 at 23:13
48

+1 for Nguyen and Yancey - and one more addition.

If you want explicit definition of the widths, you can accomplish that with string interpolation and variables for your breakpoints. Here for example with those of bootstrap - the strict rules are to prevent definition overlapping.

@screen-xs-min:     480px;
@screen-sm-min:     768px;
@screen-md-min:     992px;
@screen-lg-min:     1200px;

@screen-xs-max:     (@screen-sm-min - 1);
@screen-sm-max:     (@screen-md-min - 1);
@screen-md-max:     (@screen-lg-min - 1);

@phone:             ~"only screen and (max-width: @{screen-xs-min})";
@phone-strict:      ~"only screen and (min-width: @{screen-xs-min}) and (max-width: @{screen-xs-max})";
@tablet:            ~"only screen and (min-width: @{screen-sm-min})";
@tablet-strict:     ~"only screen and (min-width: @{screen-sm-min}) and (max-width: @{screen-sm-max})";
@desktop:           ~"only screen and (min-width: @{screen-md-min})";
@desktop-strict:    ~"only screen and (min-width: @{screen-md-min}) and (max-width: @{screen-md-max})";
@large:             ~"only screen and (min-width: @{screen-lg-min})";

footer{
    width: 100%;
    @media @tablet {
        width: 768px;
    }
    @media @desktop {
        width: 940px;
    }
}
Roman
  • 19,236
  • 15
  • 93
  • 97
SunnyRed
  • 3,525
  • 4
  • 36
  • 57
  • What is this "-strict" excactly about, from what you have written I am not capable of understanding the construct. Is there any source you could point me to for further reading on this topic? – Kevkong Mar 05 '16 at 00:46
  • 2
    Actually, the "strict-queries" are for convenience and should only be used, if you want your CSS to apply to a single screen range exclusively. When using mobile first (e.g. see: http://zellwk.com/blog/how-to-write-mobile-first-css/), I would say, that their usage is possibly a bit of a design smell and I would normally try to avoid them. But depending on the circumstances you might want some (heavy) CSS to target, say `@tablet` exclusively, and you do not want to override it in, say `@desktop` and/or `@large`. In these cases, you can use a strict query (here `@tablet-strict`). – SunnyRed Mar 08 '16 at 20:29
11

And you can also combine media queries like this

 @desktop:   ~"only screen and (min-width: 960px) and (max-width: 1199px)";
 @tablet:    ~"only screen and (min-width: 720px) and (max-width: 959px)";

    @media @desktop, @tablet, @ipad{ 
    
    //common styles... 
    
    }
spicykimchi
  • 1,151
  • 5
  • 22
  • 41
7

We use a setup like this:

@vp_desktop:    801px;
@vp_tablet:     800px;
@vp_mobile:     400px;

.OnDesktop(@rules) { @media screen and (min-width:@vp_desktop){ @rules(); } };
.OnTablet(@rules) { @media screen and (max-width:@vp_tablet){ @rules(); } };
.OnMobile(@rules) { @media screen and (max-width:@vp_mobile){ @rules(); } };

You only need to set variables, the mixins handle the rest so it's very easy to maintain yet still flexible:

div {
  display: inline-block;
  .OnTablet({
    display: block;
  });
}

It is worth mentioning that while this technique is very easy, if used badly your CSS output will be full of media queries. I try to limit my media queries to 1 per-breakpoint, per-file. Where a file would be header.less or search.less.

N.B. This method probably won't compile unless you're using the javascript compiler.

Matt W
  • 3,883
  • 3
  • 19
  • 19
4

I am using these mixins & variables

.max(@max; @rules){@media only screen and (max-width: (@max - 1)){@rules();}}
.min(@min; @rules){@media only screen and (min-width: @min){@rules();}}
.bw(@min; @max; @rules){@media only screen and (min-width: @min) and (max-width: (@max - 1)){@rules();}}

@pad: 480px;
@tab: 800px;
@desktop: 992px;
@hd: 1200px;

So this

footer{
    width: 100%;
    .bw(@tab,@desktop,{
        width: 768px;
    });
    .min(@desktop,{
        width: 940px;
    });
}

becomes

footer {
  width: 100%;
}
@media only screen and (min-width: 800px) and (max-width: 991px) {
  footer {
    width: 768px;
  }
}
@media only screen and (min-width: 992px) {
  footer {
    width: 940px;
  }
}
Atul Gupta
  • 725
  • 1
  • 6
  • 20
0

And this is what I have used for my project:

    @mobile:   ~"only screen and (min-width: 320px) and (max-width: 767px)";
    @tablet:    ~"only screen and (min-width: 768px) and (max-width: 991px)";
    @ipad:    ~"only screen and (min-width: 992px) and (max-width: 1024px)";

    @media @mobile {
      .banner{
        width: auto;
      }
    }

    @media @tablet {
      .banner{
        width: 720px;
      }
    }

  @media @ipad {
      .banner{
        width: 920px;
      }
    }
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Sunil R.
  • 851
  • 8
  • 15
0
@highdensity:  ~"only screen and (-webkit-min-device-pixel-ratio: 1.5)",
               ~"only screen and (min--moz-device-pixel-ratio: 1.5)",
               ~"only screen and (-o-min-device-pixel-ratio: 3/2)",
               ~"only screen and (min-device-pixel-ratio: 1.5)";

@mobile:        ~"only screen and (max-width: 750px)";
@tab:       ~"only screen and (min-width: 751px) and (max-width: 900px)";
@regular:        ~"only screen and (min-width: 901px) and (max-width: 1280px)";
@extra-large:  ~"only screen and (min-width: 1281px)";