Tutorial Less: 6. @Import en Less

Logo less

En CSS los imports casi tienen más inconvenientes que ventajas, pero con las nuevas posibilidades que nos da Less pasan a ser muy útiles para separar los estilos en diferentes archivos y conseguir una mejor organización, facilitar la reutilización al poder incluir solo los estilos necesarios para cada caso sin tener que duplicarlos o cargar listas interminables de estilos.

¿Cómo funciona los @import en Less?

El @import tiene 2 funcionamientos diferentes dependiendo del tipo de extensión del archivo que se importe.

  • Extensión .css: En este caso Less no hace nada (si el @import no está en el inicio del archivo lo mueve al inicio para sea correcto en CSS) y el @import se pasa directamente al CSS generado sin hacer ningún tipo de tratamiento.
  • Extensión .less: Si lo que se importa es un archivo con extensión .less, sin extensión o con cualquier otra extensión se trata como un archivo Less y el contenido de este archivo se incluye en el lugar desde donde se importa de forma que en el CSS resultante no hay ningún @import y quedan todos los estilos unificados en un único archivo.

@import "estilos.css";  // Import clasico de CSS
@import "estilos.less"; // Se incluye "aqui" el contenido estilos.less
@import "estilos";      // Se incluye "aqui" el contenido estilos
@import "estilos.mass"; // Se incluye "aqui" el contenido estilos.mass

A continuación vamos a ver los distintos modos o tipos de @import que nos ofrece Less.

Tipos de @import en Less

El @import de Less cuenta con la posibilidad de añadirle parámetros para definir la forma en la que se ha de comportar.

La sintaxis es @import (opcion1, opcion2) «estilos.less»; donde las opciones o tipos de import van entre paréntesis y separados por comas si hay varios.

Los tipos de import que hay son los siguientes.

@import (css): Import clasico de CSS

Si se usa @import (css) «estilo.ext» se trata como un import de CSS y se deja como tal indiferentemente de la extensión del archivo.


@import (css) "estilos.css";
@import (css) "estilos.less";

El resultado es el mismo que hacer el import de un fichero .css sin usar ninguna opción.


@import "estilos.css";
@import "estilos.less";

@import (less): Importa como archivo Less

Usar la opción less sirve para que se trate como un archivo .less aunque tenga cualquier otro tipo de extensión .css incluido. El resultado es el mismo que si no se usa ninguna opción siempre y cuando la extensión no fuese .css.

Como habíamos comentado antes, un @import de Less lo que hace es copiar el CSS resultante de compilar el archivo importando e incluirlo en el lugar en el que se hace el import.

Marchando un ejemplo para verlo más claro.


.estiloAnterior {
  color: blue;
}

@import (less) "cosas_less_css.css";

.estiloSiguiente {
  color: red;
  @import "cosas_less.less";
}

// Contenido de cosas_less_css.css
.claseA {
  background: blue;
}

.claseB {
  background: darkblue;
}

// Contenido de cosas_less.less
@colorFondo: #654321;

.estilazo {
  background: @colorFondo;
  font-size: 26px;

  &:hover {
    font-weight: bold;
  }
}

// Contenido de cosas_less_css.css
.claseA {
  background: blue;
}

.claseB {
  background: darkblue;
}

// Contenido de cosas_less.less
@colorFondo: #654321;

.estilazo {
  background: @colorFondo;
  font-size: 26px;

  &:hover {
    font-weight: bold;
  }
}

Y el resultado como podemos ver es que el código se incluye en lugar concreto en el que se hizo el @import con lo que no estamos limitados a ponerlo al principio e incluso lo podemos meter dentro de una clase o una @media query.


.estiloAnterior {
  color: blue;
}
.claseA {
  background: blue;
}
.claseB {
  background: darkblue;
}
.estiloSiguiente {
  color: red;
}
.estiloSiguiente .estilazo {
  background: #654321;
  font-size: 26px;
}
.estiloSiguiente .estilazo:hover {
  font-weight: bold;
} 

@import (inline): Importa el archivo sin tratarlo

Con inline se pueden incluir archivos sin tratar su contenido, esta opción es útil si se quiere incluir algún fragmento de CSS que no soporte Less como algunos hacks.


.estilo1 {
  height: 10px;
}

@import (inline) "cosas_inline.css";

.estilo2 {
  height: 20px;
}

Con el código anterior y si el contenido de cosas_inline.css fuese el siguiente


/*Aqui puede haber cualquier cosa*/

.clase {
  background: blue;
  border: ponme 2;
}

El CSS resultante sería este.


.estilo1 {
  height: 10px;
}
/*Aqui puede haber cualquier cosa*/

.clase {
  background: blue;
  border: ponme 2;
}
.estilo2 {
  height: 20px;
} 

@import (reference): Importa solo los estilos referenciados

Un @import con reference permite importar solo los estilos que están referenciados dentro del .less donde se hace el import, es decir, solo se importan los estilos que se extiendan con extend y los mixins, en los siguientes artículos los veremos en profundidad, pero para entendernos de momento podemos quedar en que son una especie de clases reutilizables.

Si tenemos los siguientes estilos en los que se hace un @import (reference) del que usamos algunas de sus clases para extenderlas y algunos de sus mixins.


.blabla:extend(.miniborde) { // Heredamos las propiedades de .miniborde
  color: blue;
}

@import (reference) "cosas_reference.less";

.blablabla {
  .superborde(); // Usamos el mixin .superborde

  color: red;
}

.miMixin(); // Usamos el mixin .miMixin

Y donde el cosas_reference.less tiene es el siguiente


@colorFondo: #654321;

.miMixin {
  .estilazo {
    background: @colorFondo;
    font-size: 26px;

    &:hover {
      font-weight: bold;
    }
  }
}

.miOtroMixin {
  background: @colorFondo;
  color: #341256;
}


.superborde() {
  border: 10px solid #000;
}

.miniborde {
  border: 1px dotted #ddd;
}

.minibordeRedondeado {
  border: 1px dotted #cdd;
  border-radius: 5px;
}

Generan un .css en el que solo está el contenido del archivo original más el contenido de los mixins usados y las propiedades heredadas.


.blabla {
  color: blue;
}
.blabla {
  border: 1px dotted #ddd;
}
.blablabla {
  border: 10px solid #000;
  color: red;
}
.estilazo {
  background: #654321;
  font-size: 26px;
}
.estilazo:hover {
  font-weight: bold;
} 

Como puedes ver con la herencia hace una cosa un poco rara porque aunque podría meter las propiedades heredadas y las extendidas juntas las pone por separado porque el funcionamiento del @import (reference) lo que hace es que en un primer momento incluye todas las propiedades importadas y cuando hace la compilación deja solo las referencias y por eso queda así.

Y en cuanto a los mixins sucede lo mismo solo se incluye su contenido y no el contenido y los mixins que no tengan paréntesis en la declaración (los paréntesis se usan precisamente para que no se exporten al CSS final como clases sueltas), como aclaración la sintaxis para usar un mixin es .nombreMixin(); donde los parentesis son opcionales.

No sé si se entenderá muy bien esto porque no quiero desviarme demasiado del tema pero si no en cuanto veas un poco como funcionan veras que son muy sencillos.

@import (once): Importa el archivo una sola vez

La opción once hace que el archivo solo sea importado una única vez, si se vuelve a encontrar un @import dek mismo archivo simplemente se ignora. Por defecto este es el comportamiento estándar de los imports en Less.


@import (once) "cosas_multiple.less";
@import (once) "cosas_multiple.less";

// Contenido cosas_multiple.less
@colorError: red;

.error {
  color: @colorError;
}

En el CSS final solo aparece en contenido importado una vez aunque el @import esta duplicado.


.error {
  color: red;
}

@import (multiple): Se puede importar el mismo archivo varias veces

Multiple tiene el comportamiento opuesto a once, el archivo se importa tantas veces como aparezca.


.contenedor {
  background: #223344;

  @import (multiple) "cosas_multiple.less";
}
@import (multiple) "cosas_multiple.less";
@import (multiple) "cosas_multiple.less";

Con este ejemplo se puede ver como se hace el @import las 3 veces que se llama, con multiple existe la posibilidad de que se genere código duplicado pero también permite hacer un @import dentro de distintos selectores.


.contenedor {
  background: #223344;
}
.contenedor .error {
  color: red;
}
.error {
  color: red;
}
.error {
  color: red;
}

Aunque como veremos los mixins son la opción más apropiada para hacer esto, pero al fin y al cabo importar un archivo en distintos lugares no deja de ser un mixin cuyo contenido es un archivo entero.

@import (optional): Importa el archivo si existe

En Less si se intenta importar un fichero y no existe falla la compilación a no ser que utilicemos optional, por lo tanto, esta opción es útil si tenemos algunos estilos que puede que tengamos o que no.

Por norma general normalmente si hacemos un @import es porque queremos incluirlo por lo tanto lo normal sería que fallase la compilación para que nos demos cuenta de que se nos ha olvidado y por esto esta opción solo se debería usar si existe una justificación real porque si no sencillamente nos estamos quitando un elemento de seguridad.


.claseAnterior {
  border-bottom: 2px;
}

@import (optional) "no_existe.fake";

.claseSiguiente {
  border-top: 2px;
}

Como el archivo no existe es como si el @import no existiese porque hemos usado optional.


.claseAnterior {
  border-bottom: 2px;
}
.claseSiguiente {
  border-top: 2px;
}

En este enlace puedes descargar un archivo .less con todos los ejemplos.