Mantener baja la especificidad de CSS en todos los selectores de su proyecto es un objetivo valioso. Generalmente es una señal de que las cosas están en relativa armonía. No estás luchando contra ti mismo y tienes mucho espacio para anular los estilos cuando lo necesites. La especificidad de los selectores tiende a aumentar con el tiempo, y eso tiene un límite estricto. Estoy seguro de que todos hemos sentido el dolor de las etiquetas! Importantes y los estilos en línea.
Entonces, ¿cómo mantenemos baja esa especificidad a lo largo del tiempo?
Date la clase que necesitas
Quizás esté escribiendo un selector de alta especificidad porque está anulando un selector ya existente. Tal vez el elemento que está tratando de seleccionar está incluido en varias páginas, por lo que lo selecciona de una clase superior:
.section-header {
/* normal styles */
}
body.about-page .section-header {
/* override with higher specificity */
}
Independientemente de cómo se sienta al respecto, reconozca que esa especificidad se está arrastrando hasta aquí. Para evitar esto, ¿hay alguna manera de alterar el nombre de la clase en ese elemento que está tratando de diseñar directamente? A veces, la creación de algunas funciones auxiliares del lado del servidor o variables para emitir clases puede ser útil para evitar la lógica en las vistas.
<header class="<%= header_class %>">
Which could output one class, or both, as desired.
</header>
.section-header {
/* normal styles */
}
.about-section-header {
/* override with same specificity */
/* possibly extend the standard class */
}
Considere el orden de origen de las hojas de estilo
En la misma línea de intentar anular algo, tal vez esté aplicando un nombre de clase adicional para manejar una anulación de estilo por usted.
<header class="section-header section-header-about">
</header>
Pero, ¿dónde está escribiendo sus estilos de anulación con .section-header-about
en realidad están siendo anulados por la clase existente. Eso puede suceder debido al orden del selector en la hoja de estilo. Ambos selectores tienen exactamente la misma especificidad, por lo que las reglas de cualquiera que se declare como la última victoria.
Arreglar eso significa simplemente asegurarse de que dondequiera que escriba, su clase de anulación llegue más tarde. Quizás organice sus hojas de estilo de la siguiente manera:
@import "third-party-and-libs-and-stuff";
@import "global-stuff";
@import "section-stuff";
@import "specific-things-and-potential-overrides";
Reduzca la especificidad de lo que está anulando
Sabes lo que dicen sobre dejar las cosas mejor de lo que las encontraste. Debes hacer eso.
Si hay una ID en un elemento y ese es el estilo de su estilo, ¿puede eliminarlo? Definitivamente, haz una búsqueda en todo el proyecto para # eso antes de hacerlo. Es posible que se esté utilizando como un gancho JS (perfectamente bien), en cuyo caso debe dejarlo solo y agregar una clase o usar una clase que ya esté en él para el CSS.
No evites las clases para empezar
Se me conoce por usar un selector como:
.module > h2 {
}
Eso funcionará bien, hasta el día en que desee un estilo especial para ese elemento h2. Podrías ir en tu marcado y ser como:
<div class="module">
<h2 class="unique">
Special Header
</h2>
</div>
Pero tristemente:
.module > h2 {
/* normal styles */
}
.unique {
/* I'm going to lose this specificity battle */
}
.module .unique {
/* This will work, but specificity creep! */
}
El deslizamiento de la especificidad está sucediendo porque el selector original nos está mordiendo. Es por eso que casi todas las metodologías CSS recomiendan estructuras planas en la línea de:
<div class="module">
<h2 class="module-header">
</h2>
<div class="module-content">
</div>
</div>
Puede parecer un trabajo más tedioso desde el principio porque es posible que no necesite esas clases de inmediato. Pero al no evitar ese trabajo (¡no seas perezoso!), Los ganchos que tendrás más adelante pueden salvar tu dolor.
Usa la cascada
A medida que un proyecto envejece, se vuelve cada vez más peligroso alterar los selectores con baja especificidad, porque potencialmente pueden afectar más cosas y tener consecuencias no deseadas.
#im #just .gonna[do] .this .to .be #safe {
/* cries (ಥ_ʖಥ) */
}
Pero afectar más cosas es el poder de CSS. Con suerte, tener una base sólida a partir de la cual está construyendo significa que siempre se necesitan menos anulaciones. Las estrategias para esto pueden ser cosas como …
Use una biblioteca de patrones y / o guía de estilo y / o diseño atómico
Una biblioteca de patrones (algo como esto) puede significar que tiene lo que busca cuando lo necesita. ¿Necesitas algunas pestañas? Aquí tienes, esta es la forma establecida para hacer eso. Y es probable que esté construido de tal manera que la especificidad ya sea ligera, por lo que anular no será demasiado difícil.
El diseño atómico (libro) puede guiar cómo se construye su sitio (o la biblioteca de patrones), por lo que incluso si no tiene un patrón completo para lo que necesita, tiene los bloques de construcción debajo.
Una guía de estilo podría salvarlo, porque podría hacer cumplir reglas específicas sobre la especificidad, en un intento de salvarlo de sí mismo.
Considere la tipografía opt-in
Al mismo tiempo que intenta usar la cascada y tiene valores predeterminados inteligentes para muchos elementos, es posible que desee analizar algunos de esos valores predeterminados inteligentes a veces. Por ejemplo, un elemento de lista se usa a menudo para la navegación y dentro del contenido. Los estilos para ellos serán drásticamente diferentes. Entonces, ¿por qué no comenzar con una pizarra limpia y aplicar estilo de texto solo cuando sea necesario?
/* reset styles globally */
ul, ol, li {
list-style: none;
margin: 0;
padding: 0;
}
/* scope text styles to text content */
.text-content {
h1, h2, h3 {
}
p {
}
ul {
}
ol {
}
/* etc */
}
Eso aumenta la especificidad de esos selectores de texto, pero significa que las reglas específicas para el texto no afectan más de lo necesario y hay menos necesidad de anulaciones.
Problemas fuera de su control
Quizás algún código de terceros espera o inyecta cierto HTML en su página. Tienes que trabajar con eso. Aún puede intentar utilizar selectores de especificidad tan baja como sea posible. Puede dejar comentarios en el código indicando por qué los selectores son así. Puede usar selectores de baja especificidad, pero use invalidaciones importantes. Puede preguntar a las personas responsables del código no ideal si pueden solucionarlo.
Solo sube la especificidad a la ligera y anótala.
Si necesita entrar en una pelea de especificidad, en lugar de alcanzar un mazo como una identificación o! Importante, pruebe algo más ligero.
Un calificador de etiqueta es la mejora de especificidad mínima posible.
ul.override {
/* I win */
}
.normal {
}
Pero limitar un selector a una etiqueta específica es un factor limitante extraño. En su lugar, sería inteligente agregar una clase adicional. Si otro nombre no tiene sentido, incluso puede usar la misma clase si es necesario.
.nav.override {
}
.override.override {
}
.nav {
}
El hecho de que anidar sea agradable no significa que la especificidad deba aumentar
En ocasiones, se desaconseja el anidamiento en preprocesadores porque facilita mucho la escritura de selectores en exceso. Pero anidar a veces es visualmente agradable en la hoja de estilo, porque agrupa las cosas para que sea más fácil de leer y digerir.
Bohdan Kokotko me recordó recientemente que el ampersand en Sass se puede usar esencialmente para hacer espacios de nombres en lugar de selectores compuestos.
.what {
color: red;
&-so {
color: green;
&-ever {
color: blue;
}
}
}
.what {
color: red;
}
.what-so {
color: green;
}
.what-so-ever {
color: blue;
}
La envoltura de una sola clase
Una forma bastante contundente de manejar una anulación es usar un elemento de envoltura existente sobre el área a la que necesita aplicar anulaciones de estilo, o agregar una nueva.
<div class="override">
... existing stuff ...
</div>
Ahora tiene la capacidad de anular cualquier estilo existente allí agregando solo una clase al selector. Es un arrastre de especificidad, pero un intento de mantenerlo bajo.
.override .existing {
}
Sólo una vez
Si alguna vez anula una anulación, ese es un buen lugar para detenerse y reconsiderar.
¿Puedes darte una sola clase que puedas usar en su lugar? En realidad, una sola anulación puede ser eficaz, como una variación de un patrón en lugar de crear un nuevo patrón. Una anulación de una anulación es una receta para la confusión y más luchas.
Solo hazlo mejor la próxima vez
Si ha sido mordido por problemas de especificidad, incluso si solucionarlos no es práctico en este momento, al menos ahora sabe que es problemático y puede abordar las cosas de manera diferente la próxima vez.