Usando la especificidad de: where () como CSS Reset | Programar Plus

No sé ustedes, pero escribo estas tres declaraciones muchas veces en mi CSS:

ul {
  padding: 0;
  margin: 0;
  list-style-type: none;
}

Podrías gritarme y decirme que puedo ponerlos en mis reinicios de CSS. Ojalá pudiera, pero no quiero y te diré por qué en un segundo.

Los agentes de usuario establecen valores para esas propiedades en una lista con un propósito, y es hacer que las listas sean más legibles. Estos son los estilos predeterminados en los navegadores de chrome para un <ul> elemento:

ul {
  list-style-type: disc;
  margin-block-start: 1em;
  margin-block-end: 1em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
  padding-inline-start: 40px;
}

Entonces, sin agregar ninguna clase en HTML o estilo en CSS, los obtenemos gratis. Eso es bueno y no quiero perderlo. Pero agradecería si pudiera hacer que el navegador entienda que existe una gran posibilidad de que no quiera esa característica predeterminada en los casos en que agregue una clase al elemento.

Así que aquí hay una solución rápida para restablecer un <ul> elemento que tiene una clase:

ul[class] {
  padding: 0;
  margin: 0;
  list-style-type: none;
}

Ahora no pierdo el estilo predeterminado, excepto cuando agrego una clase a mi <ul> elemento.

El problema

Hay un problema con esta solución. Imagina que hay una lista que queremos tener de forma diferente. list-style-type para ello, como el siguiente:

ul[class] {
  padding: 0;
  margin: 0;
  list-style-type: none;
}

.list {
  list-style-type: square;
}

Esto no funciona desde ul[class] tiene mayor especificidad. Ahí es donde falla nuestra solución.

Podríamos agregar más peso a la especificidad del selector:

ul.list {
  list-style-type: square; /* Specificity: 0, 1, 1 */
}

/* or */

.sidebar .list {
  list-style-type: square; /* Specificity: 0, 2, 0 */
}

Si está bien agregando más peso al selector, está listo para comenzar. Pero no estoy de acuerdo con eso, personalmente. Por ejemplo, no quiero poner el nombre del elemento en mi CSS la mayoría de las veces debido a un principio de separación de preocupaciones. O, si está siguiendo la metodología BEM, seguramente surgirán problemas ya que esto entra en conflicto con ella.

Entonces, ¿qué podemos hacer?

La solución

Hace unos meses, me enteré de algunos selectores calientes, incluidos :is() y :where(). Una cosa acerca de estos dos pseudo selectores funcionales es que pueden cambiar la especificidad, dándonos el poder de anular o aumentar esa especificidad.

La clave sobre :where() es que siempre tiene 0 especificidad. Entonces podemos deshacernos de nuestro problema muy fácilmente de esta manera:

:where(ul[class]) {
  list-style: none;
}

.list {
  list-style: square; /* Now this works like a charm! */
}

Con el poder de este selector, las bibliotecas pueden darnos estilo sin especificidad. Por lo tanto, no habría ninguna especificidad con la que competir cuando nosotros, como autores, escribamos CSS.

Manifestación

En la siguiente demostración, puede eliminar :where() para ver de qué hablamos en acción:

(Visited 3 times, 1 visits today)