Mixins avanzados en Stylus
Anteriormente hemos visto lo básico sobre mixins y funciones en Stylus. Pero se pueden construir mixins más complejos utilizando algunas propiedades que nos ofrece Stylus.
Añadir prefijos propietarios con mixins
Cuando queremos añadir los prefijos propietarios a alguna propiedad de CSS podemos crear un mixin con el mismo nombre de la propiedad. Es una forma muy transparente de agregar los prefijos.
transform()
-webkit-transform arguments
-ms-transform arguments
transform arguments
.rotar
transform rotate(45deg)
Con este mixin agregamos los prefijos a la propiedad transform. Esto nos da el siguiente resultado:
.rotar {
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
Pero en CSS existen otras muchas propiedades que pueden requerir prefijos. Para evitar repetir código continuamente podemos hacer un mixin genérico que sirva para cualquier propiedad:
vendor(prop, val, prefixes = ())
for prefix in prefixes
-{prefix}-{prop} val
{prop} val
transform()
vendor('transform', arguments, webkit ms)
.rotar
transform rotate(45deg)
vendor
nos permite generar los prefijos de la propiedad que queramos pasándole el nombre de la propiedad, el valor, y una lista de los prefijos necesarios. Un bucle recorrerá esa lista de prefijos. Ahora podemos crear un mixin para cada propiedad que necesite prefijos que llame a este otro mixin.
Prefijos en valores
¿Pero qué pasa cuando el prefijo lo queremos añadir en el valor de alguna propiedad? Por ejemplo, cuando hacemos una transición de elementos que requieren prefijo.
.rotar {
-webkit-transition: -webkit-transform 1s ease;
-ms-transition: -ms-transform 1s ease;
transition: transform 1s ease;
}
En este caso hay que analizar los valores para comprobar si existe alguna propiedad que debe llevar prefijo. Para ello hay que comprender cómo se estructuran estos valores al ser recibidos como argumentos de un mixin o función.
En CSS hay propiedades que pueden recibir múltiples valores. Estos valores son recogidos como un array, por lo que pueden ser recorridos mediante bucles.
Lo siguiente:
transition: color 1s ease, transform 1s ease
sería equivalente a tener un array como el siguiente:
[
[color, 1s, ease],
[transform, 1s, ease]
]
Es decir, un array bidimensional. El cual podemos recorrer fácilmente con dos bucles
transition()
for v1, k1 in arguments
for value, k2 in v1
p(value)
La variable value
nos irá dando cada valor de los argumentos. Así comprobaremos si cada valor es una propiedad que requiera prefijo.
La función
p()
nos permite mostrar el valor de esa variable en la terminal. Es una función de depuración, por lo que no muestra nada en el CSS procesado.
Existen otras funciones de este tipo para el control de errores:
warn(message)
muestra una advertencia en la consola.error(message)
muestra un mensaje y finaliza la ejecución de Stylus.
Teniendo esto en mente podemos crear un mixin que compruebe si alguno de los valores necesita un prefijo, y en dicho caso, lo añade.
transition()
// Lista de propiedades que requieren prefijo
require-prefix = (transform)
// Bucle que recorre todos los prefijos necesarios
for prefix in (webkit ms)
// Variable que almacenará el nuevo valor con los prefijos
new-value = null
// Recorremos todos los valores
for v1, k1 in arguments
for v2, k2 in v1
// Si el valor está en la lista de prefijos
// añadimos el prefijo
if v2 in require-prefix
new-value = new-value s('-%s-%s', prefix, v2)
// y si no, añadimos el valor sin más
else
new-value = new-value v2
// En caso de que haya valores separados por comas, se añaden las comas
new-value = s('%s,', new-value) unless k1 == length(arguments) - 1
// Agrega la propiedad con prefijo
add-property(s('-%s-%s', prefix, unquote(current-property[0])), new-value)
// Finalmente se muestra la declaración sin prefijos
transition arguments
En los comentarios está descrito lo que hace cada parte de la función. Dentro se usan algunas funciones que explico a continuación:
s()
Esta función nos permite sustituir valores en un string. Se le pasa un string como primer parámetro, y el resto de parametros son los elementos a sustituir.
s('-%s-%s', 'webkit', 'transform') // -webkit-transform
Cada %s
se sustituirá por el parámetro correspondiente. El primero por webkit
y el segundo por transform
. Y así sucesivamente con otros parámetros que pudiese haber.
unquote()
Nos permite eliminar las comillas de una cadena. Puede ser útil cuando tenemos una variable con un string, pero necesitamos mostrar un valor de CSS.
$color = '#345'
html
color unquote($color)
Si no usaramos unquote
el resultado sería el siguiente:
html {
color: '#345';
}
add-property()
Nos permite añadir una propiedad con su valor. Las propiedades que se añadan con esta función se añadirán antes de mostrar el resultado.
box-sizing()
add-property('-webkit-box-sizing', arguments)
add-property('box-sizing', arguments)
Este mixin sería exactamente igual a hacer lo siguiente:
box-sizing()
-webkit-box-sizing arguments
box-sizing arguments
La función add-property
puede ser útil en casos en los que no podamos usar la segunda forma, o en casos en los que usar la segunda forma pueda resultar confusa.
current-property
Esta variable nos indica la propiedad actual sobre la cual se está trabajando. Es un array, por lo que para acceder al nombre de la propiedad debemos acceder al primer elemento del mismo, current-property[0]
.
Funciones de CSS con prefijo
Algunas funciones propias de CSS como calc
o linear-gradient
requieren prefijo para funcionar en algunos navegadores. En este caso la solución es algo más compleja, por lo que veremos varias formas de solucionarlo en una segunda parte de este artículo.