How to declare same style for @media and descendant selector?

224 views Asked by At

I need to define same style for elements under a media query and descendant by another class.

Perfect solution in LESS could be the following [pseudo-code]:

.foo
{
  color:red;

  .example &,
  @media (min-width:800px)
  {
    color:blue;
  }
}

that should be desirable that would be compiled into:

.foo {
  color: red;
}
.example .foo {
  color: blue;
}
@media (min-width: 800px) {
  .foo {
    color: blue;
  }
}

THIS SYNTAX IS INCORRECT but, do you have some suggestion to solve my problem?

3

There are 3 answers

0
Luca Detomi On BEST ANSWER

Thanks to @seven-phases-max suggestion, I finally found a possible solution using Detached Ruleset:

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

.MEDIAQUERY(@only-media, @min-max, @size, @RULES) 
{
  @screen-width:~"@{screen-@{size}}";

  @mediaQuery: ~"screen and (@{min-max}-width: @{screen-width})";

  @media @mediaQuery { @RULES(); }

  & when (@only-media = false) {
    .@{size} &       { @RULES(); }  
  }
}

.foo_media-and-class
{
  color:red;

  .MEDIAQUERY(@only-media:false, @min-max:max, @size:md,
    { 
        color:blue;
    }
  );

  .MEDIAQUERY(@only-media:false,  @min-max:min, @size:lg,
    { 
        color:yellow;
    }
  );
}

.foo_only-media
{
  color:red;

  .MEDIAQUERY(@only-media:true,  @min-max:max, @size:md,
    { 
        color:blue;
    }
  );

  .MEDIAQUERY(@only-media:true,  @min-max:min, @size:lg,
    { 
        color:yellow;
    }
  );
}

This solution go beyond and offer other options:

  • Possibility to set a custom value of screen width for media query,
  • Pass MIN/MAX value of property used in media query (Try to pass "max" instead of "min" calling .MEDIAQUERY mixin)
  • Toggling generation of simple media query or media query + descendant selector, through @only-media boolean.
1
Aibrean On

I think your comma might be causing the error.

.foo {
   color:red;
   .example & {
   color:blue;
     @media (min-width:800px) {
      color:blue;
     }
   }
}

This is proper syntax to output the following:

.foo {
  color: red;
}
.example .foo {
  color:blue;
}
 @media (min-width:800px) {
  .example .foo {
    color:blue;
   }
}
0
seven-phases-max On

Nope, selectors and @media queries are too different language entities (despite having similar {} syntax) so you can't combine those with comma like in your example.

So to get it DRY (assuming that shared style has more than one property of course) you'll need a mixin (or sort of), for example:

.foo {
    color: red;
    .somename() {
        color: blue;
    }

    .example &                {.somename}
    @media (min-width: 800px) {.somename}
}

Also see Passing Rulesets to Mixins examples (if you need even more generic solution).