¡Hola! Me parece que andas usando un bloqueador de anuncios =( ¿Nos desbloqueas? ¿Por qué?
F13

Funcion 13

Extendiendo selectores y clases silenciosas con SASS

Cuando hablamos sobre Sass, ya hablamos sobre la función de extender o @extend no obstante hablamos de ella muy de pasada.

Recordemos cómo funciona:

.mi-boton {
   border-radius: 4px;
   padding: 2px 5px;
   font-size: 16px;
 }

.mi-boton-peque {
  @extend .mi-boton;
  font-size: 12px;
}

.mi-boton-grande {
  @extend .mi-boton;
  font-size: 18px;
}

Y el CSS que nos compila es:

.mi-boton, .mi-boton-grande, .mi-boton-peque {
  border-radius: 4px;
  padding: 2px 5px;
  font-size: 16px;
}

.mi-boton-grande {
  font-size: 18px;
}

.mi-boton-peque {
  font-size: 12px;
}

La directiva @extend nos permite declarar que .mi-boton-peque y .mi-boton-grande deben heredar las propiedades de .mi-boton. Si has observado con atención, añade cada clase con una coma detrás de la clase .mi-boton.

¡Muy útil! Ahora veamos otro ejemplo:

.mi-boton {
  border-radius: 4px;
  padding: 2px 5px;
  font-size: 16px;
}

.footer .mi-boton {
  box-shadow: 0 5px -14px 14px #fff;
}

.otro-boton {
  @extend .mi-boton;
}

Supongo que esperas que compile en algo así:

.mi-boton, .otro-boton {
  border-radius: 4px;
  padding: 2px 5px;
  font-size: 16px;
}

.footer .mi-boton {
  box-shadow: 0 5px -14px 14px #fff;
}

Pero lo que en realidad vemos es esto...

.mi-boton, .otro-boton {
  border-radius: 4px;
  padding: 2px 5px;
  font-size: 16px;
}

.footer .mi-boton, .footer .otro-boton {
  box-shadow: 0 5px -14px 14px #fff;
}

Es un poco decepcionante, pero veamos porqué ocurre esto. Lo que Sass hace es extender cada uno de los estilos que encuentra de .mi-boton. Ten en cuenta que quizá así te parezca poca cosa, pero si tienes un proyecto de envergadura, esto se puede convertir en un problema.

¿No sería genial si pudiéramos tener un selector que solo estuviera pensado para ser extendido?

Las clases silenciosas

Las clases silenciosas fueron introducidas en Sass 3.2 para solucionar este problema. En vez de usar un punto . al comienzo, se usa el caracter del porcentaje %. Lo mejor de ellos es que no aparecen en el CSS generado, solo aparece en aquellos selectores que los extiendan.

No obstante, ¿qué pasa si queremos lo mejor de los dos mundos? ¿Qué pasa si queremos poder extender pero solo lo que nos interesa pero además ser capaces de usar la clase?

¡Pues que podemos!

%mi-boton,
.mi-boton {
  border-radius: 4px;
  padding: 2px 5px;
  font-size: 16px;
}

.footer .mi-boton {
  box-shadow: 0 5px -14px 14px #fff;
}

.otro-boton {
  @extend %mi-boton;
}

Esto nos lleva a justo lo que esperábamos:

.otro-boton,
.mi-boton {
  border-radius: 4px;
  padding: 2px 5px;
  font-size: 16px;
}

.footer .mi-boton {
  box-shadow: 0 5px -14px 14px #fff;
}

Así conseguimos que los selectores que extendemos, existen las menos veces posible.

@extend tiene aun así sus limitaciones, como el hecho de que no funciona dentro de reglas @media, pero como ves es un aliado útil en estas situaciones.

Programador Front-end en First + Third y Potato. Trabajando con JavaScript y HTML5 desde el corazón de Sevilla.

Comentarios ¡Únete a la conversación!