Break out of scope

2019-05-24 11:29发布

Ideally, I would like to do this :

@w: 4px;

@media (max-width:900px) {
    @r: 3px; 
}
@media (min-width:900px) {
    @r: 5px; 
}

.myclass {
    border-radius: @w + @r;
}

This doesn't compile because @r isn't defined in the scope where I define .myclass. The obvious solutions are either to define .myclass inside the @media blocs or to copy the @media queries inside the definition of .myclass.

But as soon as you use @r in many classes, both solutions are messy and involve many duplications.

Is there a clean dry solution ?

2条回答
啃猪蹄的小仙女
2楼-- · 2019-05-24 12:27

I found a solution, based on @import, which lets me keep dry.

I make two files :

classes.less

@w: 4px;

.myclass {
    border-radius: @w + @r;
}

mediawidth.less

@media (max-width:900px) {
    @r: 3px; 
    @import "classes.less";
}
@media (min-width:900px) {
    @r: 5px; 
    @import "classes.less";
}

Generated CSS :

@media (max-width: 900px) {
  .myclass {
    border-radius: 7px;
  }
}
@media (min-width: 900px) {
  .myclass {
    border-radius: 9px;
  }
}

This way I don't have to repeat the many classes definition but only the import.


I accepted Martin's answer, which is much cleaner in the most common case when there are only a few numbers of variables to pass. My solution might be dryer and cleaner as soon as you have more variables and when your classes are defined in many files.

查看更多
女痞
3楼-- · 2019-05-24 12:31

Just use a mixin, that calculates the property values according to the mediaquery. It is unnecessary to do this via import.

LESS:

@w: 4px;
.bordermixin(@w,@r) {
  .myclass{
    border-radius: @w + @r;
  }
}
@media (max-width:900px) {
    .bordermixin(@w,3px);
}
@media (min-width:900px) {
    .bordermixin(@w,5px);
}

CSS:

@media (max-width: 900px) {
  .myclass{
    border-radius: 7px;
  }
}
@media (min-width: 900px) {
  .myclass{
    border-radius: 9px;
  }
}
查看更多
登录 后发表回答