En CSS no hay variables y por este motivo las variables son una de las características más importantes que nos aporta Less porque si hay algo en lo que se repiten los mismos valores montones y montones de veces es en el CSS, seguro que mientras lees esto estarás pensando en los colores, tamaños de fuente, márgenes, … y lo pesado que puede ser cambiarlos sin olvidarse ninguno pero por suerte con los preprocesadores podemos usar las variables y hacer la definición una sola vez y usarlo tantas veces como queramos con la tranquilidad de saber que si quieres cambiar el valor solo lo tenemos que hacerlo en un sitio.
¿Son variables de verdad?
Depende, como solo existen en Less en el momento en el que se compilan y se convierten en CSS desaparecen al sustituirse por su valor así que vistas desde el CSS las podríamos consideran como constantes porque no las podemos modificar pero no es cierto que sean constantes porque podemos modificar su valor volviendo a declarar la variable por ejemplo para que dentro de un ámbito tenga un valor distinto, pero dentro del mismo ámbito actúan como constantes porque siempre se aplica el último valor definido, es decir, si definimos una variable al principio del documento y la usamos una vez y después la volvemos a redefinir nuevamente en el mismo ámbito en los dos casos se aplicará el segundo valor.
Entonces no son constantes porque las constantes no se pueden volver a definir ni tampoco son variables 100% porque siempre aplican el último valor, pero se aproximan más al concepto de variable y cuando se utilizan en mixins y bucles actúan como tales.
Sea como sea sus valores solo se pueden modificar en los archivos .less y cuando se compilan desaparecen porque en CSS no existen, por lo tanto solo se pueden modificar antes de hacer la compilación.
Si has seguido los 2 artículos anteriores habrás podido ver cómo se pueden modificar estos valores con Gulp o Grunt y si haces la compilación en el cliente entonces las variables se pueden modificar con javaScript desde el navegador, aunque como comentemos la compilación en el cliente tiene un impacto negativo en el rendimiento.
Sintaxis de las variables en Less
Las variables en Less tiene el prefijo @ y pueden contener cualquier combinación letras, números guiones y guiones bajos y como en las propiedades CSS entre el nombre y el valor hay que poner : y en cuanto al valor de la variable podemos usar cualquier tipo de valor que pudiésemos asignar en CSS.
Vamos a ver unos ejemplos básicos para ver cómo podemos usarlas para definir colores, tamaños, texto o propiedades compuestas.
@bgColor: green;
@fontColor: #147;
@fontFamily: Verdana, Geneva, sans-serif;
@fontSizeBase: 14px;
@paddingBase: 2px 5px;
@1_texto: " probando";
.contenedor {
width: 90%;
font-size: 20px;
h1 {
color: @fontColor;
text-align: center;
}
p {
color: #888;
font-family: @fontFamily;
font-size: @fontSizeBase;
}
.boton {
color: @fontColor;
font-family: @fontFamily;
width: 200px;
height: 50px;
padding: @paddingBase;
font-size: @fontSizeBase;
&:hover {
color: #741;
background: @bgColor;
transform: rotate(5deg);
}
&::after{
content: @1_texto;
}
}
}
Así de sencillo es utilizar las variables, básicamente es tan simple como mover los valores de las propiedades a variables para que sea más sencillo el mantenimiento de las hojas de estilo, el CSS que resultante es el siguiente.
.contenedor {
width: 90%;
font-size: 20px;
}
.contenedor h1 {
color: #147;
text-align: center;
}
.contenedor p {
color: #888;
font-family: Verdana, Geneva, sans-serif;
font-size: 14px;
}
.contenedor .boton {
color: #147;
font-family: Verdana, Geneva, sans-serif;
width: 200px;
height: 50px;
padding: 2px 5px;
font-size: 14px;
}
.contenedor .boton:hover {
color: #741;
background: green;
-webkit-transform: rotate(5deg);
transform: rotate(5deg);
}
.contenedor .boton::after {
content: " probando";
}
Operaciones con variables en Less
En los estilos los valores de las variables en muchos casos están relacionados, se suelen usar gamas de colores, los tamaños de los márgenes o el padding suelen tener relación con el de los propios elementos y los tamaños de los elementos normalmente son divisores del tamaño del contenedor por poner algunos ejemplos y aunque podemos usar una variable para cada uno puede ser que con una sola variable y alguna que otra operación podamos conseguir el mismo resultado a la vez que simplificamos aún más las futuras modificaciones.
El ejemplo del tamaño quizás es el más sencillo porque las operaciones con números son fáciles de entender.
@ancho: 100px;
.col-1 {
width: @ancho * 0.1;
}
.col-2 {
width: @ancho * 0.2;
}
.col-3 {
width: @ancho * 0.3;
}
.col-4 {
width: @ancho * 0.4;
}
.col-5 {
width: @ancho / 2;
}
.col-6 {
width: @ancho * 0.6;
}
.col-7 {
width: @ancho * 0.7;
}
.col-8 {
width: @ancho * 0.8;
}
.col-9 {
width: @ancho - (@ancho / 10);
}
.col-10 {
width: @ancho;
}
Con una sola variable y las operaciones básicas podemos definir el ancho de los elementos muy rápido y crear las clases necesarias para construir un grid por ejemplo.
.col-1 {
width: 10px;
}
.col-2 {
width: 20px;
}
.col-3 {
width: 30px;
}
.col-4 {
width: 40px;
}
.col-5 {
width: 50px;
}
.col-6 {
width: 60px;
}
.col-7 {
width: 70px;
}
.col-8 {
width: 80px;
}
.col-9 {
width: 90px;
}
.col-10 {
width: 100px;
}
También se pueden realizar las operaciones directamente sobre el valor de la variable, en el caso anterior no tendría sentido porque si quieres que el ancho sea 200 pues pones 200 no tiene mucho sentido hacer operaciones pero también es posible definir una variable de otra y en estos casos sí que es interesante.
@ancho: 100px;
@paddingBase: 2px (@ancho / 10);
.elemento {
height: @ancho / 2;
width: @ancho;
padding: @paddingBase;
}
En este caso hacemos que el padding lateral sea el 10% del ancho de forma que si se cambia el ancho el padding también lo hace y nos ahorramos tener que cambiarlo en dos sitios y de paso garantizamos que se mantienen las mismas proporciones.
.elemento {
height: 50px;
width: 100px;
padding: 2px 10px;
}
Otras de las operaciones que seguro que vas a utilizar son las operaciones con colores que dejare para un artículo posterior pero de las que vamos a ver un pequeño ejemplo.
@color1: #147;
@color2: #352;
.elemento {
background: lighten(@color1, 10%);
color: @color1 + @color2;
border: 1px solid @color1 / 2;
}
También se pueden realizar operaciones matemáticas con los colores, pero son un poco arriesgadas porque no es difícil convertir todo en blanco o en negro. En el caso de que la operación sea entre dos colores se hace entre los valores hexadecimales para los colores rojo, verde y azul de forma independiente como podemos ver con la suma y si la operación es entre un color y un numero se realiza la operación entre el número y cada uno de los componentes del color (recordar estamos en hexadecimal 11 = 18 y 18 / 2 = 09 para el rojo). Pero las funciones con colores son lo realmente interesante como por ejemplo lighten que aclara el color en el grado que le indiquemos, más adelante veremos todas las funciones que hay para el trabajo con colores.
.elemento {
background: #175da4;
color: #449999;
border: 1px solid #09223c;
}
Ámbito de las variables en Less
En el Less los valores de las variables se aplican una vez que se ha terminado de leer todo el fichero .less incluidas las importaciones que se hagan (Lazy loading) de modo que no es necesario definir las variables antes de usarlas y si las defines varias veces se aplicará siempre el valor de la última definición por lo que una variable siempre tendrá el mismo valor a no ser que la definición este en distintos ámbitos.
Hasta ahora todas las variables que hemos visto son globales y aplican a toda la hoja de estilos pero también se pueden definir variables dentro de los selectores para que su valor solo se utilice en su ámbito.
@ancho: 100px;
.boton1 {
@ancho: 250px;
width: @ancho;
.subBoton {
width: @ancho/2;
}
}
@ancho: 500px;
.boton2 {
width: @ancho;
}
@ancho: 1000px;
Con este ejemplo podemos ver como el boton2 toma el último valor del ancho aunque este después de su definición mientras que para el boton1 y el subBoton se coge el valor de la definición dentro de boton1.
.boton1 {
width: 250px;
}
.boton1 .subBoton {
width: 125px;
}
.boton2 {
width: 1000px;
}
De esto podemos sacar 2 conclusiones, la primera es que el valor de la variable que se utilizará es el primero que se encuentre subiendo en la jerarquía del elemento (para .boton1 y .subBoton el ancho es 250px) y que es muy recomendable poner la definición de las variables en un único lugar (normalmente al principio) para evitar efectos indeseados al redefinir variables inconscientemente.
Variables de variables en Less
Otra de las posibilidades que nos da Less es usar el valor de una variable como el nombre de otra variable, con lo que hemos visto hasta el momento puede parecer simplemente una forma enrevesada para no poner el nombre de la variable que tiene el valor realmente pero puede ser útil cuando se usan estructuras condicionales, pero vamos a ir paso a paso así que vamos a ver un ejemplo con lo que controlamos hasta ahora.
@colorOk: green;
@colorError: red;
.mensajeError {
@color: colorError;
.flotante {
color: @@color;
position: fixed;
top: 100;
left: 100;
}
.fijo {
color: @@color;
padding: 20px;
}
}
Para utilizar el valor de la variable color como nombre de otra variable utilizamos 2 arrobas para que cuando se sustituya @color por colorError quede aun una delante y así el valor que se le aplique a la propiedad color sea red.
.mensajeError .flotante {
color: red;
position: fixed;
top: 100;
left: 100;
}
.mensajeError .fijo {
color: red;
padding: 20px;
}
Interpolación de variables en Less
En Less las variables también se pueden usar en el nombre de propiedades y de selectores y dentro de cadenas de texto que es muy útil para definir rutas para las imágenes o para los imports.
Para que se puedan interpolar las variables en estos casos hay que encerrar el nombre de la variable entre llaves @{nombre_variable}
.
@propiedad: color;
@color1: #147;
@color2: #352;
.boton {
@{propiedad}: @color1;
border-@{propiedad}: @color2;
}
En este ejemplo podemos ver como la variable se puede usar tanto como el nombre completo de la propiedad o bien como una parte de su nombre.
.boton {
color: #147;
border-color: #352;
}
Y del mismo modo que para las propiedades se puede utilizar para los selectores.
@selector1: boton1;
@selector2: parrafo;
.@{selector1} {
width: 20px;
color: #fff;
}
#@{selector2}Info {
font-size: 20px;
}
Al contrario que con las propiedades donde la utilidad parece limitada en el caso de los selectores sí que puede ser de mayor utilidad ya que nos permite generar clases o identificadores dinámicamente y con el uso de bucles y condicionales le podemos sacar bastante partido.
.boton1 {
width: 20px;
color: #fff;
}
#parrafoInfo {
font-size: 20px;
}
Y finalmente también se pueden usar las variables interpoladas dentro de cadenas de texto.
@rutaImportsLess: "importsA";
@rutaImagenes: "/img"
@import "@{rutaImportsLess}/formularios.css";
.contenedor {
color: #444;
background: url("@{images}/logo/less.png");
}
Que se convertirán en el siguiente CSS.
@import "importsA/formularios.css";
.contenedor {
color: #444;
background: url("/img/logo/less.png");
}
En este enlace puedes descargar un archivo .less con todos los ejemplos.