Conflictos CSS

Colisiones o conflictos de estilos CSS


Existen varias formas de añadir código CSS en una página, pero en esencia son tres formas diferentes:

  • 1️⃣ Usar un <link rel="stylesheet"> a un archivo .css (estilos externos).
  • 2️⃣ Usar un <style> con los estilos CSS (estilos embebidos en HTML).
  • 3️⃣ Atributo style en una etiqueta HTML (estilos en línea).

Antes de continuar con este artículo, si no conoces bien estas tres formas de definir estilos CSS, lee primero el post cómo enlazar CSS desde HTML.

Conflictos de nombres CSS

Al principio, cuando tenemos poco código, no suelen haber dudas, pero... ¿Qué ocurre si utilizamos varias de las formas anteriores y escribimos código CSS que entra en conflicto entre sí? ¿Y si cambiamos el orden? ¿Qué propiedad tendría prioridad sobre la otra? Vamos a analizar estos casos y entender como funciona.

Solemos decir que hay un conflicto o una colisión de nombres CSS cuando tenemos varios fragmentos de código CSS que dan diferentes estilos a un mismo elemento. El navegador debe buscar una forma de resolver ese conflicto, ya que no puede aplicar dos colores diferentes a un mismo elemento (por ejemplo). Uno de los dos fragmentos de código debe predominar sobre el otro.

Para comprender bien lo que es un conflicto de nombres CSS, observa este fragmento de código:

<div class="text">
  ¡Desde Manz.dev puedes ver mis streams!
</div>

Vamos repasar varios ejemplos, donde le daremos estilo al elemento <div class="text"> y veremos como resuelve el navegador dicho conflicto.

Caso 1: Desde diferentes fuentes

Veamos el siguiente ejemplo. En él, podrás ver que se aplican estilos CSS al mismo elemento:

  • 1️⃣ Aplicamos color azul desde el <link>
  • 2️⃣ Aplicamos color rojo desde el <style>
  • 3️⃣ Aplicamos color verde desde la propia etiqueta HTML mediante style
<html>
<head>
  <link rel="stylesheet" href="index.css">
  <!-- contiene un .text { background-color: blue; } -->
  <style>
    .text { background-color: red }
  </style>
</head>
<body>
  <div class="text" style="background-color: green">
    ¡Desde Manz.dev puedes ver mis streams!
  </div>
</body>
</html>

En este caso, tendría prioridad el estilo definido en la propia etiqueta HTML (estilo en línea), ya que el orden de prioridad es el siguiente:

  • 1️⃣🟥 El atributo style="" del HTML (mayor prioridad)
  • 2️⃣🟧 Bloque de estilos <style> en el HTML (prioridad intermedia)
  • 3️⃣🟨 Archivo .css externo vía <link rel="stylesheet"> (menor prioridad)

Lo recomendable y habitual suele ser escribir los estilos en una hoja de estilos externa (más fácil de mantener y organizar). De esta forma, esa hoja externa tendría la menor prioridad. Si en algún caso necesitamos añadir CSS con mayor prioridad, lo haríamos en un bloque <style> o en un estilo en línea.

Caso 2: De fuentes del mismo tipo

Vamos con otro ejemplo. Supongamos ahora que nos encontramos en la misma fuente (por ejemplo, una hoja de estilos externa). Vamos a aplicar estilos a exactamente el mismo selector, en este caso, al elemento .text.

La duda sería: ¿Cuál de las dos propiedades background-color prevalece? Se refieren al mismo elemento por exactamente el mismo selector y están en la misma fuente de datos:

.text {
  padding: 8px;
  background-color: red;
}

.text {
  background-color: grey;
  color: white;
}
<div class="text">Texto del elemento</div>

La respuesta es muy fácil: Prevalece siempre la última regla definida (orden). Como el selector es exactamente el mismo, entonces el navegador mezcla los estilos de ambos bloques y se fusionan. El resultado final interpretado por el navegador (valor computado) sería el siguiente:

.text {
  padding: 8px;             /* No hay conflicto, se añade */
  background-color: grey;   /* Hay conflicto: se sobreescribe la última */
  color: white;             /* No hay conflicto, se añade */
}

Caso 3: Diferente selector

Sin embargo, puede ocurrir que en determinados casos no esté tan claro cuál es el estilo que debería sobreescribir a los anteriores, porque tenemos selectores diferentes que se refieren al mismo elemento.

Por ejemplo, en este caso tenemos un elemento HTML con una clase y con un id. Si a este código HTML le aplicamos el código CSS del bloque <style>, aunque los selectores sean diferentes, nos estamos refiriendo al mismo elemento, por lo que no resulta tan intuitivo como vimos al principio de este artículo:

<div class="text" id="element">¡Hello from Manz.dev!</div>

<style>
#element {
  background: blue;
}

.text {
  background: red;
}
</style>

Aquí es cuando entra en juego el concepto de Especificidad CSS, en el que profundizaremos más adelante. Este concepto se encarga de eliminar la ambigüedad determinando cuál es el selector más específico que debería «vencer».

Para entenderlo mejor, veamos otro fragmento de CSS aplicado a la etiqueta HTML <div> anterior:

<div id="element" class="text">Texto del elemento</div>

<style>
div { background-color: red; }
#element { background-color: steelblue; }
.text { background-color: green; }
</style>

Si nos fijamos en el HTML, nuestro único <div> encaja con los tres selectores del CSS:

  • 1️⃣ Es un <div> por lo que se le aplica el color rojo.
  • 2️⃣ Tiene el id con valor element, por lo que se le aplica el color azul.
  • 3️⃣ Tiene la clase con valor text, por lo que se le aplica el color verde.

Aunque puede que lo que nos resulte más natural es pensar que el estilo vencedor es el último definido, no funciona así.

El navegador analiza cuál es el selector más específico, para descubrir cuál es el vencedor:

  • El selector div tiene especificidad 0,0,1 (es un elemento)
  • El selector #element tiene especificidad 1,0,0 (es un id)
  • El selector .text tiene especificidad 0,1,0 (es una class)

De estos tres selectores, el vencedor es el segundo (número más alto): el selector #element, ya que los elementos con id no se pueden repetir en un mismo documento, y son más específicos.

Más adelante profundizaremos en el tema de Especificidad CSS, ya que debemos explicar exactamente como se calcula ese número y otros detalles relacionados.

Importancia: Excepción !important

Existe una forma de saltarse todo lo anterior mediante una palabra clave llamada !important.

Hay que tener en cuenta que su uso debería estar siempre justificado y no utilizarse a la ligera. Con !important podemos dar máxima prioridad a un valor sobre una propiedad, dando igual la especificidad que tenga, el orden en el que esté o la fuente donde haya sido declarada.

Lo explicamos más en detalle en el tema de La palabra clave !important en CSS.

¿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