【问题标题】:LESS function that builds a media query构建媒体查询的 LESS 函数
【发布时间】:2014-11-08 11:00:40
【问题描述】:

你能否在 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;
    }
  }

我以为我已经完成了这项工作,但是由于在同一范围内调用了 mixin,因此在第二次调用中没有分配变量:

  .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;
    }

  }

【问题讨论】:

    标签: less


    【解决方案1】:

    您的第一个 sn-p 的主要问题是您不能使用 mixin 调用来设置 {...} 块的标识符。在 sn -p 中如下:

    .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 毫无意义,而且会引发错误。

    -------

    您的第二个 sn-p 更正确,但是是的,因为两个 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 并不是实现目标的唯一方法,还有其他各有利弊的方法(如果您采用“语义媒体块”方式,其中一些看起来更具可读性)。参见例如https://stackoverflow.com/a/15842048/2712740(显然在这里搜索[less] media 将指向更多灵感)。

    【讨论】:

    • 我昨天实际上在做一些与你最后两个 sn-ps 非常相似的东西,但是,就像你提到的那样,它变得太冗长以至于不实用。 +1以获得非常彻底的答案。谢谢。
    猜你喜欢
    • 2013-09-30
    • 2013-05-04
    • 2011-12-08
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    相关资源
    最近更新 更多