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

20

我想在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 吗?请看下面的答案。 - Stuart M
3个回答

28

当前似乎不支持在 @mixin 中使用变量插值。

SASS 文档将此称为 #{} 插值,并且这样描述

插值:#{}

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

$name: foo;
$attr: border;
p.#{$name} {
  #{$attr}-color: blue;
}
根据文档,变量名的插值似乎只支持选择器和属性名,而不支持@mixin。如果您需要此功能,可以提交问题,不过已有问题可能已经跟踪了您想要的内容。

编辑:您确定需要使用@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(它们包装图标)。 - Cristian
在这种情况下,在for循环声明中最好使用through。否则,最后一个元素(launch)将不被计算。 - Matt McCarthy

20
截至2014年3月30日,Chris Eppstein仍然拒绝实现动态mixin。请参见Github上的issue 857issue 626
我一直在努力说服Chris,这个功能对于Sass发挥其真正的威力非常重要...而且我不是唯一一个这样想的人。
如果您认为这是一个重要的功能,请前往issue 857issue 626并自己解决此问题。我们提供了越多的用例,就越有可能说服Chris或其他主要开发人员。

更新: 由于用户的需求,Eppstein在2016年实现了这个功能。然而,到今天(2018年中期),这些更改仍未合并到主分支中,因此在sass发布版中仍然不可用。请参见问题2057


7
正如我在帖子中所说,这是一个很好的功能 - 我在工作中实际需要它。一旦 Sass 功能冻结结束,我们就可以开始开发它了。我不知道你为什么要游说一项我们已经同意是好主意的功能。也许,你应该着手撰写一份拉取请求以便更快地完成这个功能? - chriseppstein
@chriseppstein,很抱歉,我并不是非常熟悉Ruby。我更熟悉PHP/MySQL、HTML/CSS/JS和XML/Json等技术。不管怎样,你会发现这个回答是在2014年3月30日发布的。当时,您还非常不愿意添加此功能。我很高兴您改变了主意。也许我的游说最终起到了作用?;-) - John Slegers
实际上你是正确的。我还没有被说服动态定义mixin是一个好主意。然而,你链接到的问题是关于使用动态名称包含mixin的问题。我支持这种做法。OP的问题最好通过接受单个mixin的参数来解决,而不是为每个图标定义一个唯一的mixin。 - chriseppstein
@chriseppstein: 定义并包含mixin将是一件好事,类似于动态定义和扩展占位符的功能(这是我喜欢的功能)。不过,我认为动态定义它们并不是一个真正必要的功能。在我看来,动态包含它们才是更加重要的功能(参见https://github.com/sass/sass/issues/857#issuecomment-39013579)。 - John Slegers

9
最好的解决方案是实现一个带有参数的单一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

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