Search code examples
lessmixinsless-mixins

Set "min-width" or "max-width" in a media query passing a parameter to a mixin


I would like to make dynamic MIN/MAX suffix in properties defined in a Less MediaQuery.

I wrote this code but it does not compile:

@screen-md: 800px;

.MEDIAQUERY(@min-max, @size) 
{
  @media screen and (@{min-max}-width: @size) 
  { 
    @{min-max}-width:100px;
  }
}

header 
{
  background-color: blue;

  .MEDIAQUERY ( @min-max: max, @size: @screen-md );
}

While @{min-max}-width:100px; is a correct syntax, equivalent applied in Mediaquery definition is not allowed, but I need to set sometime "max-width" value, and others "min-width" value in my media queries. How to obtain this?


Solution

  • Option 1: (Using a variable and interpolation)

    You can do it like below

    .MEDIAQUERY(@min-max, @size) {
          @mediaQuery: ~"screen and (@{min-max}-width: @{size})";
          @media @mediaQuery {
                @{min-max}-width:100px;
          }
    }
    

    Option 2: (Using Guards)

    You can use guards in the mixin like below to check what was the value that was passed for the @min-max parameter and then output the appropriate CSS based on it.

    .MEDIAQUERY(@min-max, @size){
        & when (@min-max = min) {
            @media screen and (min-width: @size) {
                min-width:100px;
            }
        }
        & when (@min-max = max) {
            @media screen and (max-width: @size) {
                max-width:100px;
            }
        }
    }
    

    When the above mixin is called like below (with either of the options mentioned above):

    header 
    {
      background-color: blue;
      .MEDIAQUERY ( @min-max: max, @size: @screen-md );
    }
    
    div{
      background-color: red;
      .MEDIAQUERY ( @min-max: min, @size: @screen-md );
    }
    

    it would compile into the below CSS:

    header {
        background-color: blue;
    }
    @media screen and (max-width: 800px) {
        header {
            max-width: 100px;
        }
    }
    div {
        background-color: red;
    }
    @media screen and (min-width: 800px) {
        div {
            min-width: 100px;
        }
    }