在Sass中使用变量作为名称包含mixin

7

我想使用一个变量作为名称来调用一个mixin,像这样:

@include $mixin-name;

这似乎并不困难...

我在网上看到一些人提到想要做到这一点。这个票 (http://dev.vaadin.com/ticket/9546) 说 "fixed",我认为在Sass 3.2中可能已经可以了,但是Sass小组在Google Groups上的评论似乎表明不是这样的:http://goo.gl/HtdHu

我知道他们在说什么,似乎很多人问起这个问题的人都可以很容易地用另一种方式解决自己的问题。

不过,我无法想出其他的方法来解决我的问题,所以让我解释一下,也许有人会有一两个想法?

CSS动画

我创建了一个@keyframes的mixin,这样我就可以调用@include animation();,并获得完整的前缀和官方的@keyframes列表。

@include keyframes(reveal) {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

给我:

@-webkit-keyframes reveal {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@-moz-keyframes reveal {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@-ms-keyframes reveal {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@-o-keyframes reveal {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@keyframes reveal {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

这很棒!但是如果我在关键帧状态之一中使用Compass transform

@include keyframes(round) {
    from {
        @include transform(rotateZ(-145deg));
        opacity: 1;
    }
    to {
        @include transform(rotateZ(-45deg));
        opacity: 0.5;
    }
}

然后我最终得到了类似这样的东西:
@-webkit-keyframes round {
    from {
        -webkit-transform: rotateZ(-145deg);
        -moz-transform: rotateZ(-145deg);
        -ms-transform: rotateZ(-145deg);
        -o-transform: rotateZ(-145deg);
        transform: rotateZ(-145deg);
        opacity: 1;
    }
    to {
        -webkit-transform: rotateZ(-45deg);
        -moz-transform: rotateZ(-45deg);
        -ms-transform: rotateZ(-45deg);
        -o-transform: rotateZ(-45deg);
        transform: rotateZ(-45deg);
        opacity: 0.5;
    }
}

前缀内嵌

我知道这有点迂腐,但是我声明了-webkit-animation,但是在里面我必须声明所有的前缀,而我想做的只是声明与关键帧和官方相同的前缀,例如:

@-webkit-keyframes round {
    from {
        -webkit-transform: rotateZ(-145deg);
        transform: rotateZ(-145deg);
        opacity: 1;
    }
    to {
        -webkit-transform: rotateZ(-45deg);
        transform: rotateZ(-45deg);
        opacity: 0.5;
    }
}

@-moz-keyframes round {
    from {
        -moz-transform: rotateZ(-145deg);
        transform: rotateZ(-145deg);
        opacity: 1;
    }
    to {
        -moz-transform: rotateZ(-45deg);
        transform: rotateZ(-45deg);
        opacity: 0.5;
    }
}

混合问题

我创建了一个使用@include experimental-value的混合,并且想要自动化它,但是遇到了问题。

@function browser-is-prefix($browser, $prefix) {
    @if $browser == $prefix {
        @return true;
    } @else {
        @return false;
    }
}

@mixin transform-prefix($transform, $browser) {
    @include experimental-value(transform, $transform,
        browser-is-prefix($browser, -moz),
        browser-is-prefix($browser, -webkit),
        browser-is-prefix($browser, -o),
        browser-is-prefix($browser, -ms),
        false, true);
}

@mixin animation-name($browser) {
    from {
        @include transform-prefix(transform(translate(-25px,200px) scale(0.5)), $browser);
        opacity: 0;
    }
    to {
        @include transform-prefix(transform(translate(0,0) scale(0.5)), $browser);
        opacity: 1;
    }
}

调用@include animation-name(-webkit)将非常有效,并给我们带来以下结果:

@-webkit-keyframes animation-name {
    from {
        -webkit-transform: translate(-25px,200px) scale(0.5);
        transform: translate(-25px,200px) scale(0.5);
        opacity: 0;
    }
    to {
        -webkit-transform: translate(0,0) scale(0.5);
        transform: translate(0,0) scale(0.5);
        opacity: 1;
    }
}

但我无法自动化它!

为了自动化这个过程,我想要能够调用一个mixin,类似于@include prekeyframes(animation-name);,并且让prekeyframes做与上面的keyframes mixin完全相同的事情,只是不会盲目地包含@content,而是包含mixin,并根据@keyframes所使用的前缀仅使用应该使用的前缀:

@mixin prekeyframes($name) {
    $prefixes : -webkit-, -moz-, -o-, -ms-, '';
    @each $prefix in $prefixes {
        @include $name($prefix);
    }
}

当我插值$name@include #{$name}($prefix))时,会抛出错误。当然,这个问题仍然存在。
所以,我可以忍受额外的transform值,或者我可以手动处理所有内容,但我一直非常欣赏Sass的灵活性,这对我来说非常有限制...
总之,我想要做到以下三点:
  • 在一个地方定义动画。
  • 能够在该动画中包含@include transform
  • 在正确前缀的@keyframes内获得正确的前缀transform
我已经花了几个小时在这上面,我还会继续调整...但如果有人有类似的经验或问题,我很想知道...
谢谢!

这更像是对Sass / Compass的功能要求,而不是一个实际的问题。 - cimmanon
这是一个问题、难题和讨论的话题。从链接中所说的内容可以看出,这是一个因某种原因被拒绝的请求。我认为这很有趣,想知道是否还有其他人有任何意见。 - Trolleymusic
1
SO不是一个讨论论坛。很明显,您已经在Sass项目的当前状态下耗尽了所有可能的选项。唯一剩下的选择是通过提供一个好的用例来请求开发人员添加/更改它。 - cimmanon
好的,谢谢。我会这么做的。也许其他人也会遇到同样的问题,并觉得这篇文章有价值。 - Trolleymusic
事实上,他们已经在处理一个功能请求了: https://github.com/nex3/sass/issues/626 - Trolleymusic
1个回答

2

谢谢。我看了一下,但是看起来他们有同样的问题:演示动画的CSS(http://bourbon.io/docs/#animations)是这样的:@-webkit-keyframes scale { 0% { -webkit-transform: scale(1); -moz-transform: scale(1); 等等... - Trolleymusic
1
你错了。请查看我给你提供的文档,这是输出结果,没有不必要的属性。 - fregante
啊,太棒了!谢谢!我正在查看文档页面的源代码。 - Trolleymusic

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