sassmedia-queries

Using Sass Variables with CSS3 Media Queries


I'm trying to combine the use of a Sass variable with @media queries as follows:

$base_width:1160px;

@media screen and (max-width: 1170px) {$base_width: 960px;}
@media screen and (min-width: 1171px) {$base_width: 1160px;}

$base_width is then defined at various points in the stylesheet width percentage-based measurements to produce fluid layouts.

When I do this, the variable seems to be recognized properly but the conditions for the media query are not. For example, the above code produces an 1160px layout regardless of screen width. If I flip-flop the @media statements like so:

@media screen and (min-width: 1171px) {$base_width: 1160px;}
@media screen and (max-width: 1170px) {$base_width: 960px;}

It produces a 960px layout, again regardless of screen width. Also note that if I remove the first line of $base_width: 1160px; it returns an error for an undefined variable. Any ideas what I'm missing?


Solution

  • This is simply not possible. Since the trigger @media screen and (max-width: 1170px) happens on the client-side.

    Achieving your expected result would only be possible if SASS grabbed all rules and properties in your stylesheet containing your $base_width variable and copied/changed them accordingly.

    Since it won't work automatically you could do it by hand like this:

    @media screen and (max-width: 1170px)
          $base_width: 960px // you need to indent it to (re)set it just within this media-query
          // now you copy all the css rules/properties that contain or are relative to $base_width e.g.
          #wrapper
              width: $base_width
              ...
    
    @media screen and (min-width: 1171px)
        $base_width: 1160px
          #wrapper
              width: $base_width
              ...
    

    This is not really DRY but the best you can do.

    If the changes are the same every time you could also prepare a mixin containing all the changing values, so you wouldn't need to repeat it. Additionally you can try to combine the mixin with specific changes. Like:

    @media screen and (min-width: 1171px)
        +base_width_changes(1160px)
        #width-1171-specific-element // additional specific changes, that aren't in the mixin
            display: block
    

    And the Mixin would look like this

    =base_width_changes($base_width)
        #wrapper
            width: $base_width