Herencia en Sass con @extend

  • Por
  • CSS
Qué es la directiva @extend de Sass, cómo nos permite organizar el código y crear CSS más limpio gracias a la herencia y las clases placeholder.

El objetivo de Sass es doble. Por una parte ser más productivos y por otra parte tener la capacidad de mantener mejor nuestro código CSS. En este artículo vamos a conocer una funcionalidad que nos ayuda en el segundo caso, ya que nos permite de una manera más sencilla ser más concisos en el código, reutilizar partes de nuestras reglas CSS y evitar tener que escribir el mismo código una y otra vez.

Conoceremos la herencia, un mecanismo por el cual un selector puede recibir estilos CSS que nos llegan de declaraciones realizadas con anterioridad. Conseguir este objetivo es sencillo gracias a la directiva @extend y las denominadas "placeholder class", que son una construcción de Sass que no tiene representación en el CSS hasta que no la usemos. Vamos a verlo todo con calma y hacer algunos ejemplos.

Clases placeholder

Este tipo de clases CSS son específicas de Sass, no existen en el lenguaje CSS de momento, así que probablemente será algo nuevo para ti. Básicamente son declaraciones CSS que podemos realizar agrupando diversas reglas de estilo. Hasta aquí son iguales que una class CSS común, la diferencia es que no tienen una representación directa en el código CSS compilado. Sólo se escribirán en el CSS resultante cuando sean usadas.

Comencemos viendo un ejemplo de una de estas clases placeholder. La sintaxis para crearlas consiste en anteponerle un símbolo "%".

%heading {
  background-color: blanchedalmond;
  color: brown;
  font-family: 'Times New Roman', Times, serif;
}

Esta declaración indica un estilo de base para nuestros encabezados y nos sirve para poder agregarla en donde la necesitemos. Sin embargo, si la dejamos tal cual en nuestro código Sass, sin usarla, no serviría para nada, debido que al compilarse simplemente se eliminaría sin producir salida alguna.

Nota: Si sabes algo de programación, podrías considerarla como una función que nunca se ha invocado, simplemente no entró en marcha en el flujo de ejecución de un programa.

Así que ahora, vamos a aprender a usar estas clases placeholder, de modo que tenga algún sentido apoyarse en ellas.

Directiva @extend de Sass

La directiva @extend nos sirve, como su nombre indica, para extender el código de cierta declaración de CSS con nuevos estilos. Las reglas de estilo con las que podremos extender las declaraciones serán tomadas directamente de las clases placeholder.

Por ejemplo, podemos tener varios encabezados en nuestra página que se extienden mediante el placeholder class creado en el punto anterior. Para ello usamos la sintaxis @extend, seguido del nombre de la clase placeholder que queremos usar.

h1 {
  @extend %heading;
  font-size: 2em;
}

h2 {
  @extend %heading;
  font-size: 1.5em;
}

Como puedes comprobar, ambos encabezados usarán los mismos estilos base, con la única diferencia que sus tamaños de fuente serán distintos.

Nuestro código Sass ahora es más modular, pero es otra utilidad distinta de la que conocimos con los import de Sass. Alguien podría decir que es similar en funcionalidad a lo que nos ofrecen los mixins, pero realmente los @extend son más sencillos y en la mayoría de las ocasiones es suficiente con ellos.

Lo interesante de este mecanismo proporcionado por @extend es que Sass te produce un código optimizado, ya que las reglas de estilo no se repiten realmente dos veces en cada selector. El código producido mantendrá las buenas prácticas. Puedes verlo a continuación.

h1, h2 {
  background-color: blanchedalmond;
  color: brown;
  font-family: 'Times New Roman', Times, serif; }

h1 {
  font-size: 2em; }

h2 {
  font-size: 1.5em; }

Como puedes apreciar, a pesar que hemos usado el @extend en cada uno de los selectores H1 y H2, no se produce una repetición del código, sino que la declaración se realiza de manera que sólo aparecerán esas reglas escritas una única vez.

Una vez declarado un placeholder class lo podemos usar en cualquier parte del código mediante un @extend, por supuesto también en otros archivos que estemos importando con @import.

Caso práctico de optimización con @extend

Como puedes imaginar, usar @extend te facilita el mantenimiento del código, ya que te permite no escribir varias veces las mismas reglas. Si más adelante se quieren cambiar los estilos es suficiente con editar la placeholder class una vez.

Puede haber infinitos casos de uso en los que podamos sacarle partido a esta declaración. Pero por poner un ejemplo concreto que ocurre en la vida real, veamos el siguiente caso.

Imagina que tienes diversas declaraciones de cajas. Podemos tener cajas normales, cajas con borde, cajas con un color de fondo dado, cajas con un espaciado mayor, etc. Y luego podemos tener muchas combinaciones, por ejemplo cajas con borde, y color de fondo. O una caja con un color de fondo y un margen mayor...

Generalmente, cuando escribes los estilos, incluso usando la característica de anidación de selectores de Sass para escribir menos código, haces algo como esto:

.caja {
  padding: 10px;
  font-size: 1.2em;

  &-borde {
    border: 1px solid #ddd;
  }

  &-fondo {
    background-color: #f0f0f0;
  }

  &-espaciadoextra {
    padding: 20px;
  }
}

Realmente no hay problema alguno en hacer este código y muchos desarrolladores, incluso frameworks, lo vienen haciendo así. Pero el HTML que debes usar cuando quieres una caja específica es un poco feo.

<div class="caja caja-borde">
    Esto es una caja con borde
</div>

El problema se magnifica cuando quieres hacer una caja que tiene borde, fondo y espaciado extra, todo a la vez. El código HTML será horrible.

<div class="caja caja-borde caja-fondo caja-espaciadoextra">
	Esto es una práctica habitual, pero el class me ha quedado un chorizo, poco mantenible y sucio por ser demasiado largo.
</div>

Ahora imagina que usas constantemente ese tipo de caja en tu código (caja + caja con borde + caja con fondo + caja con espaciado extra), con lo cual tienes que repetir ese chorizo de clases en un montón de etiquetas HTML, quedando un marcado redundante, pesado, de complicada lectura y peor mantenimiento.

Gracias a @extend podemos conseguir una situación un poco mejor. Tú podrías seguir teniendo todos esos tipos de cajas, pero además la declaración de diferentes cajas que combinan distintos tipos a la vez, como el caso de antes.

%caja {
  padding: 10px;
  font-size: 1.2em;
}

%caja-borde {
  border: 1px solid #ddd;
}

%caja-fondo {
  background-color: #f0f0f0;
}

%caja-espaciadoextra {
  padding: 20px;
}

.caja {
  @extend %caja;
  
  &-borde {
    @extend %caja;
    @extend %caja-borde;
  }
  
  &-fondo {
    @extend %caja;
    @extend %caja-fondo;
  }

  &-espaciadoextra {
    @extend %caja;
    @extend %caja-espaciadoextra;
  }

  &-combinada {
    @extend %caja;
    @extend %caja-borde;
    @extend %caja-fondo;
    @extend %caja-espaciadoextra;
  }
}

Bien cierto es que el código Sass nos ha quedao mucho más largo. En este caso no hemos sido más productivos, puesto que nos ha dado más trabajo de escribirlo, pero sin embargo el código CSS resultante será muy optimizado, puesto que las declaraciones de estilos no se van a repetir. Pero lo realmente interesante será en nuestro HTML, ya que estaremos ahorrando expresar todo el chorizo de clases cada vez que queramos usar cajas determinadas.

Por ejemplo para una caja con borde escribimos esto:

<div class="caja-borde"> ... </div>

Para una caja con varios estilos combinados también usaremos solamente una clase de CSS.

<div class="caja-combinada"> ... </div>

Por si alguien tiene curiosidad, el código CSS generado será como este:

.caja, .caja-borde, .caja-fondo, .caja-espaciadoextra, .caja-combinada {
  padding: 10px;
  font-size: 1.2em; }

.caja-borde, .caja-combinada {
  border: 1px solid #ddd; }

.caja-fondo, .caja-combinada {
  background-color: #f0f0f0; }

.caja-espaciadoextra, .caja-combinada {
  padding: 20px; }

Como puedes apreciar, las reglas de estilos CSS no se repiten, por lo que es lo más resumido posible y por tanto muy optimizado. Pero donde realmente obtenemos una ventaja representativa es en nuestro HTML, ya que no tenemos que usar un montón de clases CSS en la misma etiqueta.

Espero que este nuevo truco te haya parecido interesante. No te olvides consultar el Manual de Sass para obtener más detalles útiles para el trabajo con este poderoso preprocesador CSS.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir