Sass Mixin para fotogramas clave de animación que incluyen múltiples etapas y propiedad de transformación

10

Aquí está el CSS estándar que estoy tratando de producir pero quiero usar un SASS Mixin para hacer el trabajo.

CSS ESTÁNDAR

@-webkit-keyframes crank-up {
  100% { -webkit-transform: rotate(360deg);}
}
@-moz-keyframes crank-up {
  100% { -moz-transform: rotate(360deg);}
}
@-o-keyframes crank-up {
  100% { -o-transform: rotate(360deg);}
}
keyframes crank-up {
  100% { transform: rotate(360deg);}
}

Estoy usando el mismo mixin que en la siguiente publicación, los fotogramas clave de SASS no se compilan como se desea, que se muestra a continuación.

MEZCLAR

@mixin keyframes($name) {
  @-webkit-keyframes #{$name} {
      @content;
  }
  @-moz-keyframes #{$name} {
      @content;
  }
  @-ms-keyframes #{$name} {
      @content;
  }
  @keyframes #{$name} {
      @content;
  }
}

Lo anterior está bien, siempre que ninguno de los fotogramas clave incluya una propiedad que requiera un prefijo de proveedor. Como la propiedad transform, ya que todos los fotogramas clave con prefijo del proveedor se aplican con (en este caso) el prefijo -webkit-. Por ejemplo:

SCSS

@include keyframes(crank-up) {
  100% { -webkit-transform: rotate(360deg);}
}

CSS

@-webkit-keyframes crank-up { 100% { -webkit-transform: rotate(360deg); } }
@-moz-keyframes crank-up { 100% { -webkit-transform: rotate(360deg); } }
@-ms-keyframes crank-up { 100% { -webkit-transform: rotate(360deg); } }
@keyframes crank-up { 100% { -webkit-transform: rotate(360deg); } }

Observe lo anterior, -webkit- con un -moz-keyframe. Debería ser -moz-

Entonces, mi primer pensamiento fue alterar la mezcla anterior para:

MEZCLA ALTERADA

@mixin keyframes($first-name, $last-name, $argument) {
  @-webkit-keyframes #{$first-name} {
    -webkit-#{$last-name}: #{$argument};
  }
  @-moz-keyframes #{$first-name} {
    -moz-#{$last-name}: #{$argument};
  }
  @-o-keyframes #{$first-name} {
    -o-#{$last-name}: #{$argument};
  }
  @keyframes #{$first-name} {
    #{$last-name}: #{$argument};
  } 
}

Con una llamada al mixin pareciendo

SCSS

@include keyframes(crank-up, transform, rotate(360deg)) { }

CSS

@-webkit-keyframes crank-up { -webkit-transform: rotate(360deg); }
@-moz-keyframes crank-up { -moz-transform: rotate(360deg); }
@-o-keyframes crank-up { -o-transform: rotate(360deg); }
@keyframes crank-up { transform: rotate(360deg); }

Todo esto funciona bien si solo hay UNA 'etapa' de fotograma clave (ver en el código original - parte superior de la página, solo hay la marca del 100%), disculpe si mi terminología está un poco fuera de lugar en referencia a la 'etapa' de fotograma clave.

PROBLEMA

Quiero que un mixin como el anterior funcione con algo como.

@-webkit-keyframes crank-up {
  20%,
  40% { -webikit-transform: translateY(34px); }
  80% { opacity: .8; }
  100% { -webkit-transform: rotate(360deg);}
}

También he examinado los dos complementos de Compass Animate; compass-animation y el nuevo compass-animate, pero no estoy seguro de si pueden ayudar. Necesito alguna forma de agregar una variable y probar esto con un mixin, pero no sé si es posible pasar la variable a mixins.

Cualquier ayuda muy apreciada. Gracias

He estado jugando con lo siguiente, pero ninguno funciona, solo pensé en sumarlos para ver si alguien sabe dónde me estoy equivocando.

MEZCLAS EXPERIMENTALES:

@mixin vendor-prefix($name, $argument, $webkit: "-webkit-", $moz: "-moz-",$o: "-o-", $stale: ""){
  #{$webkit}: #{$name}: #{$argument};
  #{$moz}: #{$name}: #{$argument};
  #{$o}: #{$name}: #{$argument};
  #{$stale}: #{$name}: #{$argument};
}

@mixin vendor-prefix($last-name, $argument){
  @if $name == webkit { 
    -webkit-#{$name}: #{$argument};
  } @else if $name == moz { 
    -moz-#{$name}: #{$argument};
  } @else if $name == o { 
    -o-#{$name}: #{$argument};
  } @else { 
    #{$name}: #{$argument};
  } 
}
11

Para lidiar con los prefijos de proveedores, recomiendo usar Autoprefixer en lugar de sass mixins.

Autoprefixer interface is simple: just forget about vendor prefixes and write normal CSS according to latest W3C specs. You don’t need a special language (like Sass) or special mixins.

Because Autoprefixer is a postprocessor for CSS, you can also use it with preprocessors, such as Sass, Stylus or LESS.

Entonces, en su caso, solo necesita escribir esto:

@keyframes crank-up {
  20%,
  40% { -webkit-transform: translateY(34px); }
  80% { opacity: .8; }
  100% { -webkit-transform: rotate(360deg);}
}

Y autoprefixer lo convierte automáticamente en:

@-webkit-keyframes crank-up {
  20%, 40% {
    -webkit-transform: translateY(34px);
  }

  80% {
    opacity: .8;
  }

  100% {
    -webkit-transform: rotate(360deg);
  }
}

@keyframes crank-up {
  20%, 40% {
    -webkit-transform: translateY(34px);
  }

  80% {
    opacity: .8;
  }

  100% {
    -webkit-transform: rotate(360deg);
  }
}

Autoprefixer es ampliamente compatible, puede procesar sus estilos scss o css con esta herramienta a través de Compass, Grunt, Sublime Text, node.js, Ruby, Ruby on Rails, PHP ...

Aquí hay más información sobre el proyecto.

4
  • Gracias, pero estoy un poco confundido. ¿Dónde están los prefijos de fotogramas clave -moz- y -o- CON sus propios prefijos de transformación dentro de cada etapa de fotogramas clave?
    fidev
    27/11/2013 a las 18:55
  • @-moz-keyframes crank-up { 20%, 40% { -moz-transform: translateY(34px); } 80% { opacity: .8; } 100% { -o-transform: rotate(360deg);} } y @-o-keyframes crank-up { 20%, 40% { -o-transform: translateY(34px); } 80% { opacity: .8; } 100% { -o-transform: rotate(360deg);} }
    fidev
    27/11/2013 a las 18:55
  • 2
    Con autoprefixer puede especificar los navegadores a los que desea dirigirse en su proyecto y las versiones de cada navegador. Tengo la configuración predeterminada que admite las dos últimas versiones de cada navegador web (las dos últimas versiones Firefox no necesita prefijos para los fotogramas clave y Opera ahora usa Webkit ). Si desea editar sus preferencias, consulte la guía 27/11/2013 a las 19:18
  • Gracias @Alex, es por eso que no hay un prefijo -o- en mi respuesta. ¡Bueno saber!
    fidev
    27/11/2013 a las 19:38
10

Si ya está utilizando Compass y no desea cargar un rebote completo de biblioteca adicional y solo desea escribir un poco de mezcla, ESTA es la mejor opción.

/* animation mixing
keyframe animation
@include animation('animation-name .4s 1')*/

@mixin animation($animate...) {
$max: length($animate);
$animations: '';

@for $i from 1 through $max {
    $animations: #{$animations + nth($animate, $i)};

    @if $i < $max {
        $animations: #{$animations + ", "};
    }
}
-webkit-animation: $animations;
-moz-animation:    $animations;
-o-animation:      $animations;
animation:         $animations;
}

Y aquí está la mezcla de fotogramas clave para incluir propiedades CSS3 dentro del prefijo del proveedor del navegador en particular, en lugar de @include translate, usamos el CSS completo (Nota: si está usando Sass 3.3 o anterior, deberá eliminar la !globalmarca):

@mixin keyframes($animationName) {
    @-webkit-keyframes #{$animationName} {
        $browser: '-webkit-' !global;
        @content;
    }
    @-moz-keyframes #{$animationName} {
        $browser: '-moz-' !global;
        @content;
    }
    @-o-keyframes #{$animationName} {
        $browser: '-o-' !global;
        @content;
    }
    @keyframes #{$animationName} {
        $browser: '' !global;
        @content;
    }
} $browser: null;

Para su referencia, aquí está el ejemplo de SASS:

@include keyframes(animation-name) {
   0% {
       #{$browser}transform: translate3d(100%, 0, 0);
   }
   100% {
      #{$browser}transform: translate3d(0%, 0, 0);
   }
}

Y aquí cómo incluye su animación a la clase o identificadores en particular

.new-class {
@include animation('animation-name 5s linear');
}

Eso es todo.

1
  • El fragmento de código sass no funciona en sass 3.4+, debido a la importación de alcance; Deberíamos hacer que funcione bien con la palabra clave "! Global". 24 de septiembre de 2015 a las 9:31