Estilos con baja especificidad

El combinador :where()


En un tema anterior vimos la forma de calcular la especificidad CSS y que existían algunas excepciones como por ejemplo al utilizar combinadores CSS como :where(). Esto se puede utilizar a nuestro favor, de modo que nos sirva para aplicar «estilos base» que en un futuro planeamos sobreescribir.

Observa el siguiente fragmento de código:

<div class="container">
  <div class="box">¡Hola! ¡Soy ManzDev!</div>
</div>

<style>
  /* Especificidad: 0,2,0 */
  .container .box {
    background: indigo;
    color: white;
    padding: 1rem;
  }

  /* Especificidad: 0,1,0 */
  .box {
    background: orangered;
  }
</style>
  • 1️⃣ En un primer bloque .container .box establecemos unos estilos de base.
  • 2️⃣ Posteriormente, establecemos en .box unos estilos para sobreescribir los anteriores.

Sin embargo, como el primer selector es mucho más específico que el segundo, vencerá el color indigo. Esto es bastante claro en este ejemplo porque estamos sobre aviso, pero si añadimos varios cientos de líneas entre los dos bloques o colocamos el código CSS en diferentes archivos, puede resultar mucho más complejo de encontrar o darse cuenta.

Usando :where() como estilo base

El combinador :where() es ideal si te encuentras el problema anterior muy a menudo. Como vimos anteriormente, si colocas selectores CSS dentro de un :where() anulas la especificidad de los selectores del interior de sus paréntesis, por lo que puede utilizarse para establecer estilos base.

Observa que en este caso, los estilos se aplican exactamente igual que si no utilizaramos el :where():

<div class="container">
  <div class="box">¡Hola! ¡Soy ManzDev!</div>
</div>

<style>
  /* Especificidad: 0,0,0 */
  :where(.container .box) {
    background: indigo;
    color: white;
    padding: 1rem;
  }
</style>

Sin embargo, ahora añadimos el bloque .box anterior. Como hemos declarado un selector de baja especificidad con :where(), ahora el bloque .box si que tiene mas especificidad que el bloque anterior, y por lo tanto se aplican los estilos como buscabamos:

<div class="container">
  <div class="box">¡Hola! ¡Soy ManzDev!</div>
</div>

<style>
  /* Especificidad: 0,0,0 */
  :where(.container .box) {
    background: indigo;
    color: white;
    padding: 1rem;
  }

  /* Especificidad: 0,1,0 */
  .box {
    background: orangered;
  }
</style>

Usando :where() de forma parcial

Observa también el siguiente caso. En esta ocasión, estamos utilizando el :where() de forma parcial, donde solo incluimos una parte del selector. Recuerda que :where() permite anular la especificidad de los selectores entre paréntesis:

<div class="container">
  <div class="box">¡Hola! ¡Soy ManzDev!</div>
</div>

<style>
  /* Especificidad: 0,1,0 */
  :where(.container) .box {
    background: indigo;
    color: white;
    padding: 1rem;
  }

  /* Especificidad: 0,1,0 */
  .box {
    background: orangered;
  }
</style>

De esta forma, la especificidad es 0,1,0, ya que anula la especificidad del .container, pero mantiene la del .box. En este caso, la especificidad de los dos bloques de código es la misma, por lo que vence la que se ha definido en último lugar.

Esto, unido a ventajas como que tanto :where() como :is() permiten establecer listas de selectores para crear combinaciones, lo convierten en una herramienta super útil en muchas situaciones. Si quieres aprender más sobre los combinadores :is() y :where(), echa un vistazo a este artículo donde hablamos y profundizamos más sobre ellos.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev