如何在 SASS 中定义动态 mixin 或函数名?

Posted

技术标签:

【中文标题】如何在 SASS 中定义动态 mixin 或函数名?【英文标题】:How to define a dynamic mixin or function name in SASS? 【发布时间】:2013-03-22 20:26:27 【问题描述】:

我想在 SASS 中动态创建 mixin,以列表中的每个项目命名,但它似乎不起作用。

我试过了,但我得到一个错误:

$event-icons: fair, concert, art-show, conference, dance-show, film, party, festival, theatre, launch
@each $event-icon in $event-icons
  @mixin event-icon-#$event-icon
    background-position: -($event-icon-width * $i) 0

错误:

Invalid CSS after "": expected expression (e.g. 1px, bold), was "#$event-icon"

SASS 不支持这种用法吗?我在手册中找不到任何关于它的内容。

【问题讨论】:

您确定在这种情况下需要使用@mixin 吗?请参阅下面的答案 【参考方案1】:

@mixins 中的变量插值目前似乎不受支持。

SASS 文档称之为# interpolation 和describes it like this:

插值:#

您还可以使用 # 插值语法在 选择器属性名称 中使用 SassScript 变量:

$name: foo;
$attr: border;
p.#$name 
  #$attr-color: blue;

根据documentation,变量名称的插值似乎只支持选择器和属性名称,而不支持@mixins。如果您喜欢该功能,您可能需要file an Issue 获得它,尽管this one 可能已经在跟踪您所描述的内容。

编辑: 您确定需要使用@mixin 来完成您所说的样式吗?您可以只使用带有插值的选择器吗?例如,这是否可行:

$event-icons: fair, concert, art-show, conference, dance-show, film, party, festival, theatre, launch
@for $i from 1 to length($event-icons)
  $event-icon: nth($event-icons, $i)
  .event-icon-#$event-icon
    background-position: -($event-icon-width * $i) 0

【讨论】:

我实际上最终使用了选择器,但这并不适用于所有情况。我想独立于选择器,并拥有可以在其他地方轻松使用的 mixin,也可以使用伪选择器,例如 :hover on links(包裹图标)。 在这种情况下最好在for循环声明中使用through。否则,将不计算最后一个元素 (launch)。【参考方案2】:

截至目前(2014 年 3 月 30 日),Chris Eppstein 仍然拒绝实现动态混合。请参阅 Github 上的 issue 857issue 626

我一直在试图说服 Chris,这个功能对于 Sass 释放其真正力量非常重要......而且我不是唯一一个。

如果您同意这是一项重要功能,请转至 issue 857issue 626 并自行解决此问题。我们越多地为此功能提供用例,就越有可能说服 Chris 和/或其他主要开发人员之一。


更新:在 2016 年,由于请求数量众多,Eppstein 确实最终实现了此功能。然而,今天(2018 年年中),这些更改仍未合并到主分支中,因此在 sass 版本中仍然不可用。看 issue 2057.

【讨论】:

+1 正如我在线程中所说,这是一个很好的功能——我实际上在工作中需要它。一旦 Sass 功能冻结结束,我们就可以对其进行处理。我不知道您为什么要游说我们已经同意的功能是个好主意。相反,也许可以处理一个拉取请求,以便更快地完成? @chriseppstein 恐怕我对 Ruby 不是很流利。我更喜欢 php/mysqlhtml/CSS/JS 和 XML/Json 类型的人。无论如何,您会注意到此答案发布于 2014 年 3 月 30 日。当时,您仍然非常不愿意添加此功能。我很高兴你改变了主意。也许我的游说最终得到了回报?!? ;-) 其实你是对的。我还没有相信 mixins 的动态定义是一个好主意。但是,您链接到的问题是关于使用动态名称包含 mixin。我赞成。通过接受单个 mixin 的参数而不是为每个图标定义唯一的 mixin,可以更好地解决 OP 的问题。 @chriseppstein :定义和包含一个 mixin 会很好,类似于动态定义和扩展占位符(这是我喜欢的一个功能)。不过,我同意动态定义它们并不是真正的基本功能。动态包含它们是 IMO 的一项更为重要的功能(参见例如github.com/sass/sass/issues/857#issuecomment-39013579)。【参考方案3】:

最好的解决方案是实现一个带有参数的 mixin。

$event-icons: fair, concert, art-show, conference, dance-show, film, party, festival, theatre, launch
@mixin event-icon($name)
  @if not index($event-icons, $name)
    @error "#$name is not an event icon."
  background-position: -($event-icon-width * $i) 0

【讨论】:

以上是关于如何在 SASS 中定义动态 mixin 或函数名?的主要内容,如果未能解决你的问题,请参考以下文章

SASS混入

如何使用 webpack 预加载 SASS 自定义实用程序(变量和 mixins)

Bootstrap-Sass 源码解析三:Mixins

Bootstrap-Sass 源码解析三:Mixins

Bootstrap-Sass 源码解析三:Mixins

Sass @mixin 与 @include