MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

Especificidad

Esta traducción está incompleta. Por favor, ayuda a traducir este artículo del inglés.

El concepto

Especificidad son los medios por los que el navegador decide qué valores de una propiedad de CSS son más relevantes para un elemento y, por lo tanto, serán aplicados. Especificidad se basa en en las reglas de concordancia que siguen los diferentes tipos de Selectores CSS.

¿Cómo se calcula?

Especifidad es una carga que se aplica a una declaración CSS dada, determinada por el número de cada tipo de selector correspondiente. Cuando la especificidad es igual a varias de las multiples declaraciones, se apicará la última declaración encontrada en el CSS. La especificidad solo se aplica cuando el mismo elemento es objetivo de múltiples declaraciones. Siguiendo las reglas de CSS, en caso de que un elemento sea objetivo de una declaración directa, esta siempre tendrá preferencia sobre las reglas heredadas de un ancestro.

Nota: Proximidad de elementos en el árbol de documentos no tiene efecto en la especificidad.

Tipos de selectores

La siguiente lista de selectores se incrementa en función de la especificidad.

  1. Selectores de título (p.e., h1) y pseudo-elementos (p.e., :before).
  2. Selectores de clase (p.e., .example), selectores de atributos (p.e., [type="radio"]) y pseudo-clases (p.e., :hover).
  3. Selectores de ID (p.e., #example).

El selectore Universal (*), combinadores (+, >, ~, ' ') y la pseudo-clase negación (:not()) no tienen efectos sobre la especificidad. (Sin embargo, los selectores declarados dentro de :not() si lo tienen.)

Los estilos inline añadidos a un elemento (p.e., style="font-weight:bold") siempre sustituyen a cualquier estilo escrito en hojas de estilo externas, por lo que se puede pensar que tienen la mayor especificidad.

La excepción !important

Cuando se emplea important en una declaración de estilo, esta declaración sobrescribe a cualquier otra. Aunque técnicamente !important  no tiene nada que ver con especificidad, interactúa directamente con esta. Sin embargo, el uso de !important, es una mala práctica y debería evitarse porque hace que el código sea más difícil de depurar porque rompre la cascada (artículo en ingles) natural de las hojas de estilo. Cuando dos declaraciones en conflicto con el !important son aplicadas al mismo elemento, se aplicará la declaración con mayor especificidad. 

Algunas reglas del juego:

  • Busca siempre una manera de emplear la especificidad antes de considerar el uso de !important
  • Usa !important solo en delcaraciones específicas de CSS que sobrescriban CSS foráneo (de librerías externas como Bootstrap o normalize.css).
  • Nunca uses !important cuando estás intentando escribir un plugin/mashup.
  • Nunca uses !important en todo el CSS.

En lugar de usar !important, considera:

  1. Hacer un mejor uso de las propiedades en cascada de CSS.
  2. Usar reglas más específicas. Indicando uno o más elementos antes del elemento que estás seleccionando, la regla se vuelve más específica y gana mayor prioridad:

    <div id="test">
      <span>Texto</span>
    </div>
    div#test span { color: green }
    div span { color: blue }
    span { color: red }
    

No importa el orden, el testo será verde porque la regla es más específica. (Además, la regla para el azul sobrescribe a la regla para el rojo, a pesar del orden de las reglas)

Deberías usarlo cuando:

A) Escenario uno:

  1. Tienes un archivo CSS que establece aspectos visuales de tu sitio de manera global.
  2. Tú (o otros) usas estilos inline en los propios elementos. Esto es considerado como una muy mala práctica.En este caso, puede establecer ciertos estilos en su archivo CSS global como importantes, superando así los estilos en línea configurados directamente en los elementos.

En este caso, puedes establecer ciertos estilos en tu archivo CSS global como importantes, superando así los estilos en línea configurados directamente en los elementos.

Ejemplo del mundo real: Algunos plugins jQuery muy mal escritos que usan estilos inline.Real world example: Some badly written jQuery plugins which use inline styles.

B) Otro escenario:

#someElement p {
    color: blue;
}

p.awesome {
    color: red;
}

¿Cómo haces que párrafos awesome se vuelvan siempre rojos, inclos los que se encuentren dentro de #someElement? Sin !important, la primera regla tendrá más especificidad y ganará a la segunda.

Cómo sobrescribir !important

A) Simplemente añade otra regla CSS con !important y, o bien da al selector una especificidad mayor (añadiendo una etiqueta, id o clase al selector), o añadiendo una regla CSS con el mismo selector en un punto posterior al ya existente. Esto funciona porque en caso de empate en especificidad, la última regla prevalece.

Algunos ejemplos con una gran especificidad:

table td    {height: 50px !important;}
.myTable td {height: 50px !important;}
#myTable td {height: 50px !important;}

B) O añade el mismo selector después de uno existente:

td {height: 50px !important;}

C) O reescribe la regla original para evitar el uso de !important.

Para más información, visita (en inglés):

http://stackoverflow.com/questions/3706819/what-are-the-implications-of-using-important-in-css

http://stackoverflow.com/questions/9245353/what-does-important-in-css-mean

http://stackoverflow.com/questions/5701149/when-to-use-important-property-in-css

http://stackoverflow.com/questions/11178673/how-to-override-important

http://stackoverflow.com/questions/2042497/when-to-use-important-to-save-the-day-when-working-with-css

 

La excepción :not

La pseudo-clase negación :not no es considerada una pseudo-clase para el cálculo de la especificidad. Pero los selectores colocados dentre de ella, si cuentan como selectores normales a la hora de determinar el valor de los tipos de selectores

Aquí tienes un pedazo de CSS:

div.outer p {
  color:orange;
}
div:not(.outer) p {
  color: lime;
}

cuando se usa con el siguiente HTML:

<div class="outer">
  <p>Esto está en el outer div.</p>
  <div class="inner">
    <p>Este texto está en el inner div.</p>
  </div>
</div>

Debería aparecer en pantalla como:

Esto está en el outer div

Este texto está en el inner div

 

Especificidad basada en la forma

La especificidad está basada en la forma de un selector. En el siguiente caso, el selector *[id="foo"] cuenta como un atriburo selector para la determinación de la especificidad de un selector, incluso cuando se selecciona una ID.

Las siguientes declaraciones de estilo:

*#foo {
  color: green;
}
*[id="foo"] {
  color: purple;
}

cuando se usan con este marcador:

<p id="foo">Soy un texto de ejemplo.</p>

Se acabarán viendo así:

Soy un texto de ejemplo

 

Debido a que coincide con el mismo elemento, pero el selector ID tiene una mayor especificidad.

Ignorancia de proximidad en el árbol

La proximidad de un elemento con otros a los que se hace referencia en un selector determinado, no tiene impacto en la especifidad. La siguiente declaración de estilo:

body h1 {
  color: green;
}
html h1 {
  color: purple;
}

Con el siguiente HTML:

<html>
<body>
  <h1>¡Aquí va un título!</h1>
</body>
</html>

Se mostrará como:

¡Aquí va un título!

 

Porque las dos declaraciones tienen un resultado de tipo de selector igual, pero el selector html h1 se ha declarado después.

Declaración directa vs estilos heredados

Los estilos para elementos objetivo de una declaración directa siempre tienen preferencia sobre los eltilos heredados, sin importar la especificidad de la regla heredada.

#parent {
  color: green;
}
h1 {
  color: purple;
}

Con el siguiente HTML:

<html>
<body id="parent">
  <h1>¡Aquí va un título!</h1>
</body>
</html>

Se verá así:

¡Aquí va un título!

 

Porque el selector h1 selecciona el objetivo de manera específica, pero el color verde simplemente es heredad de su padre.

Consulta también (en inglés)

Etiquetas y colaboradores del documento

 Colaboradores en esta página: Remohir
 Última actualización por: Remohir,