你能否使用LESS mixins创建自定义断点?

9
大多数情况下,我使用预设断点的LESS变量来进行媒体查询,例如:
@s-max : ~"screen and (max-width: 40em)";
@m-max : ~"screen and (max-width: 50em)";
@l-max : ~"screen and (max-width: 60em)";

USAGE

.some-class {
    color: red;

    @media @s-max {
       color: blue;
    }
}

有时候,我希望能够在我的.less样式表中引用任意断点而不必在单独的mixin文件中设置新的预设值。
在SASS中,您可以这样做。mixin看起来像这样:
@mixin bp-min($canvas) {

    @media only screen and (min-width:$canvas) {@content;}
}

USAGE

@include bp-min(750px) {

//responsive styling for min-width of 750px

}

在LESS中,我想象等效的mixin看起来应该像这样:
.bp-min(@min) {

    @media only screen and (min-width:@min)...
}

唯一的问题是,在LESS中缺少{@content}参数,它可以获取开发人员输入的其余样式。我喜欢SASS,但我不能在工作中使用它。

有没有人知道基于LESS的解决方案来解决这个问题?


这是我从LESS转向SCSS的原因之一。当我转换时,没有支持此功能。 - AfromanJ
还有其他很好的理由可以进行迁移。 - GolezTrol
我知道,我知道。Sass是一件美好的事情。我正在考虑(并不是非常认真)将我的一些个人项目从Sass转移到LESS,这样我就可以停止想起在工作中错过的东西了。 - Bryce Johnson
4个回答

15

现在它类似于SASS

1.7.0(2014-02-27)开始,您现在可以使用@规则来代替时髦的@content。

例如:

.breakpoint-small(@rules) {
  @media screen and (min-width: 40em) { @rules(); }
}

ul {
  width: 100%;
  .breakpoint-small({
    width: 50%;
  });
}

输出,如预期:

ul {
  width: 100%;
  @media screen and (min-width: 40em) {
    width: 50%;
  }
}

区别在于:

  • 函数接受 @rules 作为参数
  • 调用函数时需要添加额外的括号
  • 使用 '.' 语法而不是 '@include'

这可以与其他参数结合使用,提供与 Sass 的一些有用语法等效的语法:

.breakpoint(@size, @rules) {
  @media screen and (min-width: @size) { @rules(); }
}

@large: 60em;
ul {
  .breakpoint(@large, {
    width: 50%;
  });
}

编辑: 说实话,我更喜欢一种更简单的方法:

@break-large: ~"screen and (min-width: 60em)";
ul {
  @media @break-large {
    width: 50%;
  }
}

来源:我在家也使用Sass,但在工作中使用Less。


你上一个看起来到目前为止都很棒 - anhnt

6

使用模式匹配

我相信这可以实现你想要的:

LESS

/* generic caller */
.bp-min(@min) {
    @media only screen and (min-width:@min) {
      .bp-min(@min, set);
    }
}

/* define them */
.bp-min(750px, set) {
  test: (@min - 300px);
}
.bp-min(400px, set) {
  test: (@min - 100px);
}

/* call them */
.bp-min(750px);
.bp-min(400px);

输出CSS

@media only screen and (min-width: 750px) {
  test: 450px;
}
@media only screen and (min-width: 400px) {
  test: 300px;
}

通过为不同尺寸定义一个“set”模式mixin,然后在通用的“.bp-min(@min)” mixin中使用该模式,我认为我们在LESS中拥有了与SCSS相同的抽象,只是代码略微多一些,因为我认为SCSS在一个@include语句中定义和调用,而这里我们需要两个。

有趣的方法。看起来需要的时间/工作量与创建另一个预设媒体查询(使用@变量)差不多,但我会更深入地思考这个解决方案,看看能否使用它。谢谢! - Bryce Johnson
1
可能的工作量并没有减少多少,但我想要表达的关键是它与你提供的 SCSS 版本几乎没有什么不同,这是你所希望实现的例子。唯一额外的是调用调用开始进程滚动的命令。 - ScottS
我知道你的意思。只是我的懒惰大脑想要像Sass一样快速,简单和无脑的东西...但看起来你可能已经在LESS中找到了下一个最好的解决方案。谢谢。 - Bryce Johnson

2

在我的情况下,我需要我的变量引用其他变量,因此一些解决方案并不适用。这是我采用的方法。

@bp-xs: ~"screen and (max-width:"@screen-xs-max~")";
@bp-sm: ~"screen and (max-width:"@screen-sm-max~")";
@bp-md: ~"screen and (max-width:"@screen-md-max~")";
@bp-lg: ~"screen and (max-width:"@screen-lg-max~")";

然后就可以像这样使用它们。
@media @bp-sm {
  ...
}

2
(除了之前的答案)或者类似这样的内容:
.bp-min(@canvas) {
    @media only screen and 
        (min-width: @canvas) {.content}
}

// usage:

& { .bp-min(900px); .content() {
    color: red;
}}

& { .bp-min(600px); .content() {
    color: blue;
}}

// more usage examples:

.class-green { 
    .bp-min(450px); .content() {
        color: green;
}}

& { .bp-min(300px); .content() {

    .class-yellow {
        color: yellow;
    }

    .class-aqua {
        color: aqua;
    }
}}

如果您更喜欢简短的东西,请使用.-代替.content


我实际上比第一种方法更喜欢这种方法,因为所有的使用都发生在一个地方/选择器中。谢谢分享。 - Bryce Johnson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接