【问题标题】:How to Convert Sass Function to Less?如何将 Sass 函数转换为 Less?
【发布时间】:2017-06-21 09:23:53
【问题描述】:

有谁知道如何在 Less 中重新创建下面的 Sass 函数?我希望能够轻松地转换任何 CSS 属性中的单位(例如:字体大小、边距、填充等)。

萨斯:

@function get-vw($target) {
    $vw-context: (1440 * 0.01) * 1px;
    @return ($target / $vw-context) * 1vw;
}

CSS:

selector {
    font-size: get-vw(20px)vw;
}

Sass 来自这里:http://emilolsson.com/tools/vw-unit-calc-an-online-responsive-css-font-size-calculator/

【问题讨论】:

    标签: css sass less viewport-units


    【解决方案1】:

    更新答案:

    作为seven-phases-max has mentioned in comments below,他创建了一个很棒的自定义 Less 插件,它允许我们在 Less 中编写函数(是的,有返回值)并在规则中使用它们。

    为了我们使用这个插件,我们必须首先通过执行以下命令来安装插件:

    npm install -g less-plugin-functions
    

    下一步是为我们编写一个自定义函数。执行此操作的语法是首先将函数包装在名为 .function {} 的混合/选择器块中,然后复制粘贴我在原始答案中给出的混合代码(见下文)。唯一的变化是@output 变量必须替换为return,因为函数返回分配给该属性的值。因此,代码将如下所示:

    .function{
      .get-vw(@target) {
        @vw-context: (1440 * 0.01) * 1px;
        return: (@target / @vw-context) * 1vw; /* do calc, set output to "return" property */
      }
    }
    

    创建函数后,使用起来非常简单,就像我们在 Sass 中所做的一样:

    .selector {
      font-size: get-vw(20px);
      margin-top: get-vw(16px);
    }
    

    现在,下一步是编译 Less 文件以生成输出 CSS。命令行编译使用相同的lessc 命令完成,但我们必须在执行此操作时包含/调用自定义插件。所以编译语句如下所示:

    lessc --functions test.less test.css
    

    所有这些信息都已在GitHub Page 中提供,但为了完整和安全起见,我在答案中再次记录了它们。

    注意:如果自定义函数中没有指定return属性,那么编译时会抛出以下错误:

    RuntimeError:错误评估函数get-vw

    [plugin-functions] 无法推断返回值,没有 mixin 匹配或 [file name] 中缺少 return 语句


    原答案:

    首先,没有办法在 Less 中编写真正的函数,因为 return 语句是不可能的。

    我们可以做的一件事是编写一个 mixin 并破解我们的方法,让它的行为有点接近函数的行为。下面是一个例子:

    .get-vw(@target) { /* take an input */
      @vw-context: (1440 * 0.01) * 1px;
      @output: (@target / @vw-context) * 1vw; /* do calc, set an output var */
    }
    
    .parent {
      .get-vw(20px); /* expose output var + value to current scope by calling mixin */
      font-size: @output; /* use the value of output var wherever needed */
      .child { /* scoping is not a problem as you can see with the child */
        .get-vw(16px); 
        padding: @output;
        }
    }
    

    但是上面sn-p的问题是,如果两个属性需要使用这个函数的输出,并且每个属性都有不同的输入值,那么就会因为Less中的变量延迟加载而出现问题。例如,考虑下面的 sn-p(.get-vwmixin 与之前的 sn-p 保持一致。

    .parent {
      .get-vw(20px);
      font-size: @output;
      .get-vw(16px);
      margin-top: @output;
    }
    

    您可能期望输出如下:

    .parent {
      font-size: 1.38888889vw;
      margin-top: 1.11111111vw;
    }
    

    但实际输出是这样的:(如您所见,相同的值应用于两者

    .parent {
      font-size: 1.38888889vw;
      margin-top: 1.38888889vw;
    }
    

    解决方案是变得更加 hacky,并将每个此类属性放在一个未命名的命名空间 (&) 中,从而为每个属性赋予自己的范围:

    .parent {
      & {
        .get-vw(20px);
        font-size: @output;
      }
      & {
        .get-vw(16px);
        margin-top: @output;
      }
    }
    

    如您所见,这一切都变得非常非常混乱。在 Less 中编写真正的函数的唯一方法是编写一个自定义插件,就像 Bass Jobsen 在his answer here 中描述的那样。它很复杂,但这是唯一正确的方法。

    【讨论】:

    • “后处理器/功能插件”->“函数”。
    • 这真是太棒了@seven-phases-max。刚刚安装并试用,非常棒。在我看来,正是少的东西。我会给你一个 100 喜欢的插件!即使你给了我链接,我也只关注那个 Sass2Less 插件,并没有下来看这个。我马上修改我的答案。
    • Functions 功能一直被计划作为原生功能添加 - 但是关于它的确切语法有很多争论(仍然没有达成共识,因此插件)。
    • @seven-phases-max:再次感谢这个出色的补充。我真的很喜欢它。我现在已经编辑了答案,如果您发现任何错误(或需要更正)并且如果您有时间,请随时编辑我的答案:)
    • @Harry 我实际上想出了一个类似的解决方案,它的用途更广,尽管@seven-phases-max 提到的插件似乎最终是最好的答案。我的解决方案是调用值为 1 的 mixin:.get-vw(1); 然后将返回的值乘以我想要的任何大小:font-size: @output * 20;margin-top: @output * 16; 这有助于避免多次调用 mixin 并创建单独的范围.然而,它仍然不理想。我会试试这个插件!
    猜你喜欢
    • 2017-05-01
    • 2014-07-07
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-18
    • 2018-07-25
    相关资源
    最近更新 更多