Cómo abordar los problemas de especificidad de CSS y cuándo usar la palabra clave! Important

Un caso de estudio

Recientemente, hubo una encuesta de Twitter en la que el usuario hizo una pregunta a sus seguidores sobre la especificidad de CSS. Desafortunadamente, no pude encontrar el tweet original (¡comente a continuación si lo encuentra!), Pero en pocas palabras, la mayoría de las personas se equivocaron.

Esa encuesta de Twitter (y sus consecuencias) me llevó a repasar mi propio conocimiento del tema de la especificidad y, a su vez, me hizo empezar a solucionar problemas de especificidad en mis propios proyectos, lo que me lleva al propósito de esta publicación.

En esta publicación, refactorizaremos el código CSS de un proyecto mío que tiene problemas de especificidad de CSS que deben solucionarse.

Especificidad CSS

Definición

MDN Web Docs describe la especificidad como:

el medio por el cual los navegadores deciden qué valores de propiedad CSS son los más relevantes para un elemento y, por lo tanto, aplicados.

Reglas

Al decidir qué valores de propiedad CSS son los más relevantes para aplicar a un elemento, el navegador usa el orden de origen (es decir, la cascada) de la hoja de estilo CSS para determinar esto. Pero esta regla se aplica cuando los selectores de CSS tienen la misma especificidad. ¿Qué sucede cuando la especificidad de un selector de CSS es mayor que la de otro?

En ese caso, los navegadores utilizarán la especificidad de un selector de CSS para determinar qué declaraciones de CSS aplicar. Cuanto mayor sea la especificidad de un selector de CSS, es más probable que los navegadores apliquen sus declaraciones de CSS sobre otro.

nav a { color: green; } a { color: red; }

Por ejemplo, en el ejemplo anterior, ambos selectores de CSS apuntan al mismo elemento HTML, la etiqueta de anclaje. Para determinar qué regla CSS aplicar a la etiqueta de ancla, el navegador calculará el valor de especificidad y comprobará cuál es la más alta. En este caso, el primer selector tiene un valor de especificidad más alto, por lo tanto, el navegador usará sus declaraciones para aplicar a la etiqueta de anclaje.

Me gustaría señalar aquí que, aunque ! Important no es un selector de CSS, es una palabra clave que se utiliza para anular con fuerza una regla de CSS, independientemente del valor de especificidad, el origen o el orden de origen de un selector de CSS. Algunos casos de uso incluyen:

  • Arreglos temporales (un poco como poner cinta adhesiva en una tubería con fugas)
  • Estilo en línea predominante
  • Fines de prueba / depuración

Por muy útil que parezca usar la palabra clave ! Important , su uso puede ser más problemático que útil. Con el tiempo, puede dificultar el mantenimiento de su CSS y puede afectar negativamente la legibilidad de su hoja de estilo, especialmente para cualquier otra persona que esté o vaya a trabajar con ella en el futuro.

Lo que nos lleva a lo que haremos hoy: solucionar los problemas de especificidad de un proyecto.

El proyecto

Un poco de historia sobre el proyecto que refactorizaremos: es una página de inicio inspirada en Netflix que utiliza la API de MovieDB.

La hoja de estilo

El objetivo es eliminar la palabra clave "! Important" de las reglas CSS a las que se ha aplicado mediante la refactorización del código para que siga las reglas de especificidad.

A continuación, puede ver la hoja de estilo del proyecto.

@import url("//fonts.googleapis.com/css?family=Montserrat:400,400i,700"); body { margin: 0; padding: 0; overflow-x: hidden; } .wrapper { width: 100%; } .wrapper #header { position: fixed; z-index: 300; padding: 15px; width: calc(100% - 30px); display: flex; justify-content: space-between; align-items: center; background: linear-gradient(to bottom, black 0%, transparent 100%); } .wrapper #header #brand-logo { color: #d32f2f; text-shadow: 1px 1px 2px black; letter-spacing: 5px; text-transform: uppercase; font-family: Montserrat; font-weight: bold; font-size: 22px; } .wrapper #header #menu-icon { display: none; } .wrapper #header .nav-link, .wrapper #header .icon { color: #bdbdbd; cursor: pointer; } .wrapper #header .nav-menu { width: 400px; display: flex; justify-content: space-around; align-items: center; } .wrapper #header .nav-link { padding: 5px 10px; font-size: 15px; font-family: century gothic; text-decoration: none; transition: background-color 0.2s ease-in; } .wrapper #header .nav-link:hover { color: #c62828; background-color: rgba(0, 0, 0, 0.7); } .wrapper #header .icon { font-size: 16px; } .wrapper #header .icon:hover { color: #c62828; } .wrapper #site-banner, .wrapper #categories { width: 100%; } .wrapper #site-banner { height: 550px; background-image: url("//s1.gifyu.com/images/rampage_2018-1024x576.jpg"); background-size: cover; background-position: center; background-repeat: no-repeat; background-attachment: fixed; } .wrapper #site-banner .main-movie-title, .wrapper #site-banner .watch-btn, .wrapper #site-banner .main-overview { position: absolute; z-index: 3; } .wrapper #site-banner .main-movie-title, .wrapper #site-banner .watch-btn { text-transform: uppercase; } .wrapper #site-banner .main-movie-title { top: 120px; left: 20px; background: -webkit-linear-gradient(#ff9100, #dd2c00); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-size: 55px; font-family: Montserrat; font-weight: bold; } .wrapper #site-banner .main-overview { width: 400px; top: 230px; left: 25px; color: #fafafa; line-height: 25px; font-family: helvetica; } .wrapper #site-banner .watch-btn { width: 150px; height: 35px; top: 350px; left: 25px; border: none; border-radius: 20px; color: #fafafa; cursor: pointer; transition: all 0.2s ease-in; background-color: #ff0000; box-shadow: 1px 5px 15px #940000; } .wrapper #site-banner .watch-btn:hover { color: #F5F5F5; background-color: #940000; } .wrapper .after { position: relative; top: 0; left: 0; z-index: 2; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.3); } .wrapper #categories { padding: 30px 0; display: flex; flex-direction: column; background: linear-gradient(to top, #090909 0%, #000000 100%); overflow: hidden; } .wrapper #categories .category { margin: 30px 0; } .wrapper #categories .category-header, .wrapper #categories .content { margin-left: 20px; color: #B0BEC5; font-family: helvetica; } .wrapper #categories .category-header { margin-bottom: 50px; font-weight: normal; letter-spacing: 5px; } .wrapper #categories .content { position: relative; right: 0; display: flex; justify-content: flex-start; transition: all 3s ease-in-out; } .wrapper #categories .movie { margin-right: 10px; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; } .wrapper #categories .movie-img { transition: all 0.2s ease-in; } .wrapper #categories .movie-img:hover { -webkit-filter: contrast(1.1); filter: contrast(1.1); -webkit-transform: scale(1.05); transform: scale(1.05); cursor: pointer; } .wrapper #footer { width: 100%; height: 120px; background-color: #090909; display: flex; align-items: flex-end; justify-content: flex-start; } .wrapper #footer #copyright-label { margin-left: 20px; padding: 10px; color: rgba(255, 255, 255, 0.3); opacity: 0.7; letter-spacing: 2px; font-family: helvetica; font-size: 12px; } //Media Query @media (max-width: 750px) { .nav-menu { visibility: hidden; } #menu-icon { display: block !important; font-size: 22px; } .main-movie-title { font-size: 45px !important; } .main-overview { width: 350px !important; font-size: 14px !important; } .watch-btn { width: 130px !important; height: 25px !important; font-size: 13px; } .movie-img { width: 170px; } }

Por lo tanto, podemos ver en la hoja de estilo que el uso de la palabra clave ! Important se centra principalmente en la sección de consulta de medios, que describe los estilos que el navegador debe aplicar cuando el ancho de la pantalla es inferior a 750 píxeles.

Entonces, ¿qué sucede cuando eliminamos la palabra clave ! Important de las reglas CSS a las que se ha aplicado? Bueno, ya no tenemos una "carta de triunfo" que anule a la fuerza las reglas CSS de otros selectores CSS que tienen como objetivo el mismo elemento HTML. Por lo tanto, el navegador examinará la hoja de estilo para ver si hay reglas CSS en conflicto.

Si las hay, para determinar qué reglas CSS aplicar sobre otra, el navegador utilizará el orden de origen, la especificidad y la importancia de los selectores de CSS. Si los selectores de CSS con reglas de CSS en conflicto tienen la misma especificidad, el navegador usará la regla de orden de origen y aplicará las reglas de CSS del selector de CSS que se encuentra más abajo en la hoja de estilo. Con esta información, podemos ver que esta situación no es el caso de nuestra hoja de estilo.

Pero, si los selectores de CSS con reglas de CSS en conflicto no tienen la misma especificidad, el navegador aplicará las reglas de CSS del selector de CSS que tiene una mayor especificidad. Podemos ver en nuestra hoja de estilo que este es el caso; los selectores de CSS en nuestra consulta de medios tienen menor especificidad que los selectores de CSS en la parte principal de nuestra hoja de estilo.

Ahora que hemos identificado el problema, ¡solucionémoslo!

Primero tenemos que ubicar los selectores CSS correspondientes que coinciden con los selectores CSS en nuestra consulta de medios.

.wrapper #header #menu-icon { display: none; } .wrapper #site-banner .main-movie-title { ... font-size: 55px; ... } .wrapper #site-banner .main-overview { width: 400px; ... } .wrapper #site-banner .watch-btn { width: 150px; height: 35px; ... } @media (max-width: 750px) { #menu-icon { display: block !important; ... } .main-movie-title { font-size: 45px !important; } .main-overview { width: 350px !important; font-size: 14px !important; } .watch-btn { width: 130px !important; height: 25px !important; ... } }

Podemos ver que los selectores CSS en la parte principal de la hoja de estilo tienen mayor especificidad que los selectores CSS correspondientes en la consulta de medios. A pesar de que los selectores de CSS en la consulta de medios aparecen más adelante en la hoja de estilo, debido a las reglas de especificidad (que tienen prioridad sobre las reglas de orden de origen), el navegador aplicará las reglas de CSS de los selectores de CSS que vienen antes.

Para solucionar esto, debemos aumentar los valores de especificidad de los selectores de CSS en la consulta de medios. Si lo hacemos de modo que los selectores de CSS que se dirigen a los mismos elementos HTML tengan la misma especificidad, entonces el navegador seguirá la regla del orden de origen. Las reglas CSS descritas en la consulta de medios (que se encuentra más abajo en la hoja de estilo) se aplicarán cuando el ancho de la pantalla sea inferior a 750 píxeles.

El resultado final se verá así:

.wrapper #header #menu-icon { display: none; } .wrapper #site-banner .main-movie-title { ... font-size: 55px; ... } .wrapper #site-banner .main-overview { width: 400px; ... } .wrapper #site-banner .watch-btn { width: 150px; height: 35px; ... } @media (max-width: 750px) { .wrapper #header #menu-icon { display: block; ... } .wrapper #site-banner .main-movie-title { font-size: 45px; } .wrapper #site-banner .main-overview { width: 350px; font-size: 14px; } .wrapper #site-banner .watch-btn { width: 130px; height: 25px; font-size: 13px; } }

¡Y eso es! Hemos eliminado todos los rastros de la palabra clave ! Important de la hoja de estilo. Ya podemos ver que la hoja de estilo es más fácil de leer, y puedes imaginar que nuestra hoja de estilo refactorizada sería mucho más fácil de trabajar y mantener (especialmente si otros también trabajarán en ella).

Conclusión

¿Así que, qué hemos aprendido?

Hemos aprendido cómo los navegadores determinan qué estilos CSS aplicar utilizando el orden de origen, la especificidad y el origen de los selectores. También hemos aprendido acerca de los problemas que pueden surgir al usar ! Important en su CSS y por qué su uso debe mantenerse al mínimo.

No tenemos que recurrir al uso de ! Important para arreglar las cosas; existen soluciones mucho mejores.

El concepto de especificidad es uno que puede tomar un tiempo para entenderlo, pero espero que al documentar el proceso y usar un proyecto real, te ayude a comprender mejor el concepto de especificidad y cómo aplicarlo en tu propio CSS.

Recursos adicionales

  • Documentos web de MDN
  • Batficity de Mandy Michael
  • Guerras de especificidad CSS por Andy Clarke
  • Visualizador de especificidad de Francesco Schwarz.
  • Cuando se usa! Important es la elección correcta de Chris Coyier

Puede encontrar el proyecto en el que hemos estado trabajando aquí.

¡Espero que hayas disfrutado esta publicación! Si lo hizo, ❤️,? ¡y compartir! ¡Hasta la próxima! ✌️