Tutorial Less: 1. Introducción a Less

Logo less

¿Que es LESS?

Less es uno de los preprocesadores de CSS más populares junto con Sass y Stylus y como tal nos facilita y mejora la creación y el mantenimientod de hojas de estilo CSS simplificando la estructura mediante el anidamiento de las propiedades CSS, añadiendo el uso de variables (bueno, ahora ya tenemos las Custom properties que aunque siguen siendo un borrador ya estan soportadas por los navegadores actuales), funciones, herencia, reutilización de código, bucles, sentencia condicionales, operaciones aritmeticas, operaciones con colores,… y todo esto manteniendo una retrocompatibilidad total con CSS con lo que la migración a Less se puede ir haciendo de forma progresiva.

Es una extensión de CSS y no su sustituto y utiliza su misma sintaxis también para las funcionalidades adicionales que nos ofrece lo que nos facilita su aprendizaje.

¿Cómo funciona LESS?

Los preprocesadores CSS en general y Less como caso particular son programas que preprocesan un fichero con un formato propio (.less) para convertirlo en un fichero CSS convencional que podremos utilizar en cualquier navegador como si lo hubiesemos escrito directamente en CSS puro, por lo que la compatibilidad no será un problema, siempre que el propio CSS no lo sea.

Vale, entoces se escribe codigo Less pero los navegadores no entienden este formato y por esto tenemos que compilar para generar un CSS que puedan interpretar los navegadores.

Para compilar los archivos .less tenemos las siguientes opciones:

Compiladores online

Podemos usar compiladores online especificos como less2css.org o algo un poco más generico como codepen que es la plataforma que utilizo habitualemente para compartir los ejemplos para que se pueda ver el resultado, en la web de Less hay una lista de compiladores online es bastante extensa, pueden ser utiles para compartir o para hacer alguna prueba pero no son una alternativa real para algo más serio.

Compilar en el lado del cliente

Se puede realizar la compilación mediante javaScript en el propio navegador del usuario utilizando less.js que se encargará de realizar la compilación cada vez que se cargue la página lo que afecta negativamente al rendimiento y como se produzca algún fallo en el javaScript nos arriesgamos a que no se llege a generar el CSS y la página se quede sin estilos.

Para hacer la compilación en el cliente hay que hacerlo del siguiente modo (el script de configuración es opcional).


<link rel="stylesheet/less" type="text/css" href="styles.less" />

<!-- opcional -->
<script>
  less = {
    env: "development",
    logLevel: 2,
    async: false,
    fileAsync: false,
    poll: 1000,
    functions: {},
    dumpLineNumbers: "comments",
    relativeUrls: false,
    globalVars: {
      var1: '"string value"',
      var2: 'regular value'
    },
    rootpath: ":/a.com/"
  };
</script>

<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js" ></script>

Aunque su uso no esta recomendado para entornos de producción por el rendimiento hay un punto que puede resultar interesante y es la posibilidad de modificar los valores de las variables dinamicamente para que se vuelva a generar el CSS resultante de aplicar los nuevos valores de mediante javaScript, con lo que se puede consguir unos estilos muy dinamicos.


less.modifyVars({
  '@bg-color': '#ccc',
  '@font-color': '#741'
});

Compilar en el lado del servidor

También esta la opción de compilar en el lado del servidor con Node.js para lo que hay que instalar less y con less.render se genera el CSS final y podemos obtener los mismos resultados que compilandolo en el cliente, aunque en este caso estamos delegando el trabajo extra de hacer la compilación en el servidor lo que me parece poco aconsejable.


var less = require('less');
var fs = require('fs');

var options = {
    modifyVars: {
        '@bg-color': '#ccc',
        '@font-color': '#741'
    }
};

fs.readFile('estilos_base.less', 'utf8', function(error, lessInput) {
    if (error) {
        console.log(error);
    } else {
        less.render(lessFile, options, function(error, cssOutput) {
            console.log(cssOutput);
            ...
        });
    }
});

Aplicaciones de escritorio

Aquí el abanico de posibilidades es muy grande, tenemos aplicaciones completas para editar y compilar el código (Crunch 2!, Koala, Prepros, …),
Crunch 2
compiladores (SimpLESS, WinLess, Plessc, …)
Sublime text + SimpLESS
y plugins para los IDEs y editores más habituales (Sublime text, Brackets, Notepad++, Eclipse, NetBeans, Visual Studio, …).

Linea de comandos

Por supuesto esta la opción de compilar los archivos .less por linea de comandos, para lo que necesitamos tener instalado Node.js e instalar el compilador de Less.

Para comprobar si lo tenemos instalado comprobamos la versión de node o de npm y si no lo descargamos.


node -v 
v6.11.0

npm -v
3.10.10

Para instalar el compilador de Less ejecutamos el siguiente comando:


npm install less -g

Comprobamos que la instalacion esta correctamente instalado y compilamos nuestro archivo .less con lessc el_archivo_less > el_archivo_css_generado.


lessc -v
lessc 2.7.2 (Less Compiler) [JavaScript]

lessc estilos_base.less > estilos_base.css

Para un archivo o unos pocos puede ser pasable pero como tengas que estar compilando muchos…

Automatizador de tareas

Una de las mejores alternativas para la compilación es utilizar un automatizador de tareas como Grunt, Gulp, Broccoli,… que además de realizar la compilación automatica cuando hagamos un cambio podemos ver el resultado directamente en el navegador usando LiveReload, minificar el css resultante, añadir los vendor prefixes automaticamente para no tener que preocuparse y tener que estar recordando que propiedades los necesitan para cada navegador y de paso dejando el código más limpio porque tener una propiedad escrita un monton de veces solo para añadir -ms-, -webkit-, -moz- y -o-. La lista de tareas que se pueden realizar es muy grande y desde luego no se limitan a operaciones con el css por lo que podemos utilizar para el html, el javaScript,…

En los siguientes articulos explicare como usar Gulp y Grunt para la compilación aderezado con las funcionalidades que acabo de comentar.

Comenzamos con Less

Despues de una pequeña introdución y de preparar nuestro entorno para trabajar con Less empezamos a ver que nos ofrece…

Sintaxis anidada en Less

GraLa sintaxis anidada es una caracteristica muy simple porque es simplemente un cambio en la organización de los estilos pero hace que el código sea más facil de leer y este mejor estructurado.

El siguiente es un es un fragmento de css tipico en el que se define una clase y dentro de esta se definen estilos para otras clases o elementos y nos obliga a poner una y otra vez como prefijo la clase contenedor con lo que para cambiar el nombre de la clase nos vemos obligados a cambiarlo en unos cuantos sitios y en este caso estan todos los estilos juntos pero no hay nada que nos impida tenerlo desperdigado por la hoja de estilos y de hecho esto es relativamente frecuente.


.contenedor {
  width: 90%;
  font-size: 20px;
}
.contenedor h1 {
  color: #444;
  text-align: center;
}
.contenedor p {
  color: #888;
}
.contenedor .boton {
  color: #147;
  width: 200px;
  height: 50px;
}
.contenedor .boton:hover {
  color: #741;
  background: green;
}

Para solventar esto una de las posibilidades que nos ofrecen los preprocesadores es anidar las propiedades con lo que ganamos en organización y no tenemos que poner nombres infinitos cuando hay jerarquias de estilos de muchos niveles.


.contenedor {
  width: 90%;
  font-size: 20px;

  h1 {
    color: #444;
    text-align: center;
  }

  p {
    color: #888;
  }

  .boton {
    color: #147;
    width: 200px;
    height: 50px;

    &:hover {
      color: #741;
      background: green;
    }
  } 
}

Ambos códigos son 100% iguales de hecho el primero es el resultado de la compilación de este primer ejemplo de código Less.

El selector & en Less

El ampersand (&) nos sirve para referenciar la estructura hacia arriba completa desde donde se utiliza. Es un comodin para sutituir el elemento padre pero no solo el padre sino el padre con todos sus padres.


.boton-solitario {
  color: blue;

  &:hover {
    background: red;
  }
}

.contenedor {
  .boton {
    color: #147;
    width: 200px;
    height: 50px;

    &:hover {
      color: #741;
      background: green;
    }
  } 
}

En el caso del boton-solitario el ampersand toma el valor del padre (& = .boton-solitario) con lo que el :hover se aplica sobre dicho elemento y el resultado sera este.


.boton-solitario {
  color: blue;
}
.boton-solitario:hover {
  background: red;
}

En el segundo caso el & esta un nivel más bajo en la jerarquia y como comentaba toma el valor completo por lo tanto & = .contenedor .boton y en este caso se generan ambas reglas con el «abuelo».


.contenedor .boton {
  color: #147;
  width: 200px;
  height: 50px;
}
.contenedor .boton:hover {
  color: #741;
  background: green;
}

Con este par de ejemplos hemos visto como el & nos ayuda para poder anidar los pseudo-elemento pero no es la unica utilidad, por ejemplo se puede utilizar para invertir la estructura si se pone despues de una clase.


.contenedor {
  width: 90%;
  font-size: 20px;

  .boton & {
    color: #147;
    width: 200px;
    height: 50px;

    &:hover {
      color: #741;
      background: green;
    }
  } 
}

Al añadirlo despues de la clase boton generamos la clase .boton .contenedor y el & del hover como referencia la estrutura hacia arriba se aplica sobre .boton .contenedor y no sobre .contenedor .boton .contenedor como también se podría pensar puesto que lo que hay que tener en cuenta es que el & se sustituye por el padre en el momento que se evalua y en este momento el padre ya es .boton .contenedor.


.contenedor {
  width: 90%;
  font-size: 20px;
}
.boton .contenedor {
  color: #147;
  width: 200px;
  height: 50px;
}
.boton .contenedor:hover {
  color: #741;
  background: green;
}

Desde luego esto da muchas posibilidades, por ejemplo para mantener las especializaciones de una clase dentro de la estructura, aunque no es menos cierto que su uso genera estructuras más complejas y más dificilis de entender.

Otra de las posibilidades que nos ofrece es hacer combinaciones de elementos porque no hay ninguna limitación en número de usos y al compilarse se van a generar los estilos de todas las combinaciones posibles.


.ingrediente1, .ingrediente2 {
  & & {
    color: red;
  }

  & > & {
    color: green;
  }

  & + & + & {
    color: blue;
  }

  && {
    font-size: 25px;
  }
  
}

Como el & puede ser tanto .ingrediente1 como .ingrediente2 se generaran las siguientes listas de clases.


.ingrediente1 .ingrediente1,
.ingrediente1 .ingrediente2,
.ingrediente2 .ingrediente1,
.ingrediente2 .ingrediente2 {
  color: red;
}
.ingrediente1 > .ingrediente1,
.ingrediente1 > .ingrediente2,
.ingrediente2 > .ingrediente1,
.ingrediente2 > .ingrediente2 {
  color: green;
}
.ingrediente1 + .ingrediente1 + .ingrediente1,
.ingrediente1 + .ingrediente1 + .ingrediente2,
.ingrediente1 + .ingrediente2 + .ingrediente1,
.ingrediente1 + .ingrediente2 + .ingrediente2,
.ingrediente2 + .ingrediente1 + .ingrediente1,
.ingrediente2 + .ingrediente1 + .ingrediente2,
.ingrediente2 + .ingrediente2 + .ingrediente1,
.ingrediente2 + .ingrediente2 + .ingrediente2 {
  color: blue;
}
.ingrediente1.ingrediente1,
.ingrediente1.ingrediente2,
.ingrediente2.ingrediente1,
.ingrediente2.ingrediente2 {
  font-size: 25px;
}

Y para terminar con este operador «magico» vamos a ver una opción que nos ofrece bastante interesante.


.boton {
  width: 200px;
  height: 50px;

  &-error {
    background: red;

    &:hover {
      color: white;
    }
  }

  &-ok {
    background: green;

    &:hover {
      color: black;
    }
  }
}

Y es que si se concatena el & con un texto se pueden generar nombres de clases compuestos como en este caso que generamos un botón de error y otro de ok a partir de la clase boton.


.boton {
  width: 200px;
  height: 50px;
}
.boton-error {
  background: red;
}
.boton-error:hover {
  color: white;
}
.boton-ok {
  background: green;
}
.boton-ok:hover {
  color: black;
}

Comentarios en Less

Y para terminar esta primera aproximación a Less otra cosa muy simple y que aunque no aporta nada realmente a la generación de los estilos si que puede mejorar la calidad y legibilidad, y es que ademas de los tipicos comentarios multilinea de css (/* comentario */) en less también estan los comentarios de una sola linea que tenemos por ejemplo en javaScript (// Comentario…) y estos comentarios cuando se realiza la compilación no se pasan al css, que en cierto modo es entendible puesto que el css no lo deberiamos de tocar nunca y normalmente no nos va a intersar distribuir los comentarios.


.contenedor {
  width: 90%;
  font-size: 20px;

  /* Comentario que se pasa
  al css cuando se compila*/

  p {
    color: #888;
  }

  // Comentario solo para less
  .boton {
    color: #147;
    width: 200px;
    height: 50px;
  } 
}

Como decia los comentarios propios de Less no se pasan y con los comentarios de css hay que tener cuidado de donde se colocan si por algún motivo se quieren mantener en el css resultante (personalmente no veo ninguno) y es que si estan dentro de una clase se van a quedar dentro de esa clase como si fuesen una propiedad más, en este ejemplo podemos ver como lo que en principio viendo el código original parece un comentario sobre el parrafo se queda dentro de la clase contenedor.


.contenedor {
  width: 90%;
  font-size: 20px;
  /* Comentario que se pasa
  al css cuando se compila*/

}
.contenedor p {
  color: #888;
}
.contenedor .boton {
  color: #147;
  width: 200px;
  height: 50px;
}

Leave a Reply