I'm trying to call a mixin using a variable as the name, like so:
@include $mixin-name;
I've seen a few people online mention wanting to do this. This ticket (http://dev.vaadin.com/ticket/9546) says "fixed", which I assumed meant that in Sass 3.2 it was possible, but this comment from the Sass group on Google Groups seems to suggest otherwise: http://goo.gl/HtdHu
I see what they're saying, it seems many people who are asking about it could quite easily solve their issues another way.
I can't think of another way for my issue though, so let me explain and maybe someone might have an idea or two?
I've created a mixin for @keyframes
so that I can call @include animation();
and get the full list of prefixed and official @keyframes
@include keyframes(reveal) {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
Gives me:
@-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;
}
}
Which is great! But if I use Compass transform
in one of the keyframe states:
@include keyframes(round) {
from {
@include transform(rotateZ(-145deg));
opacity: 1;
}
to {
@include transform(rotateZ(-45deg));
opacity: 0.5;
}
}
then I end up getting something like:
@-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;
}
}
etc...
So, I know that this is pedantic, but it's really annoying me that I am declaring -webkit-animation
, but then inside I have to declare all of the prefixes when what I want to do is only declare the same prefix as the keyframes and the official, eg:
@-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;
}
}
etc...
So, I've created a mixin using @include experimental-value
, but I can't automate it enough because
@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;
}
}
Calling @include animation-name(-webkit)
will work great and give us:
@-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;
}
}
To automate the process I wanted to be able to call a mixin, something like @include prekeyframes(animation-name);
and have prekeyframes
do exactly what the keyframes
mixin does above, except instead of blindly including the @content
of the, it will include the mixin and only use the prefixes it should based on what prefix the @keyframes has:
@mixin prekeyframes($name) {
$prefixes : -webkit-, -moz-, -o-, -ms-, '';
@each $prefix in $prefixes {
@include $name($prefix);
}
}
This, of course, throws an error. If I interpolate $name
(@include #{$name}($prefix)
), it's still an issue.
So, I could just live with the extra transform
values, or I could do it all manually, but I've always been really impressed with the flexibility of Sass and this seems really limiting to me...
@include transform
within that animation.transform
inside the correctly prefixed @keyframes
I've spent a few hours on this now, and I'll continue to fiddle... But if anyone has similar experiences or problems, I'd love to know...
Thanks!
Check out Bourbon (relevant code and documentation), it's fantastic.