构建媒体查询的LESS函数

时间:2014-09-15 00:06:21

标签: less

您是否可以在LESS中编写一个函数,在传递其断点的值时输出媒体查询?

我希望能够像这样动态创建它们:

  // Something like this

  .media(@min, @max) {
    @query: ~"@media (min-width: @{min}) and (max-width: @{max})";
  }

  .class {
    .media(100px, 400px) {
      color: red;
    }

    .media(401px, 500px) {
      color: green;
    }
  }

  // Outputs this:

  @media (min-width: 100px) and (max-width: 400px) {
    .class {
      color: red;
    }
  }
  @media (min-width: 401px) and (max-width: 500px) {
    .class {
      color: green;
    }
  }

我认为我有这个工作,但因为mixins在同一范围内被调用,所以变量不会在第二次调用中被分配:

  .media (@min, @max) {
    @query: ~"(min-width: @{min}) and (max-width: @{max})";
  }

  .class {
    width: 100%;
    max-width: 300px;

    .media(100px, 400px);
    @media @query {
      color: red;
    }

    .media(401px, 800px);
    @media @query {
      color: green;
    }

  }

1 个答案:

答案 0 :(得分:1)

第一个代码段的主要问题是无法使用mixin调用来设置{...}块的标识符。在以下片段中:

.media(100px, 400px) {
    color: red;
}

实际上是 new mixin定义,而不是之前定义的.media mixin调用(因此它不会输出任何内容,因为从未调用过这个新的mixin)。 适当的mixin调用语法:

.media(100px, 400px); {
   color: red;
}
在这种情况下,

将等同于:

@query: ~"@media (min-width: 100px) and (max-width: 400px)"; {
   color: red;
}

当然对Less来说没有任何意义,它会引发错误。

<强> -------

您的第二个代码段更正确,但是,因为两个mixin调用共享相同的范围,因此只有一个@query变量。可以通过将每个命名空间放入未命名的命名空间(它只是一个带有&名称的规则集来隔离它们,以便创建一个新的范围,然后作为外部规则集的一部分输出):

.class {
    & {.media(100px, 400px);
        @media @query {
            color: red;
    }}

    & {.media(401px, 800px);
        @media @query {
            color: green;
    }}
}

这就是诀窍,但显然它看起来并不像真正有用的东西(太冗长和不可读)所以为了参考起见,提到其他方法是有道理的:

<强> -------

今天,针对特定案例的最干净的解决方案是使用ruleset as mixin parameter

.media(@min, @max, @styles) {
    @media (min-width: @min) 
        and (max-width: @max) {
            @styles();
    }
}

.class {
    .media(100px, 400px, {
        color: red;
    });

    .media(401px, 800px, {
        color: green;
    });
}

虽然我怀疑在实际项目中你每次需要相应的媒体时都要明确重复像素值,所以最有可能最终你会以更多的语义混合结束,例如:

.media(@min, @max, @styles) {
    @media (min-width: @min) 
        and (max-width: @max) {
            @styles();
    }
}

.tiny-screen(@styles)        {.media(100px, 400px, @styles)}
.not-so-tiny-screen(@styles) {.media(401px, 800px, @styles)}

.class {
    .tiny-screen({
        color: red;
    });

    .not-so-tiny-screen({
        color: green;
    });
}

<强> ------

将规则集传递给mixins并不是实现目标的唯一方法,其他方法有各种优点和缺点(如果你去了#34;语义媒体块,其中一些方法看起来更具可读性&# 34;方式)。例如,请参阅https://stackoverflow.com/a/15842048/2712740(显然,在此处搜索[less] media将指向更多灵感。