css-selectores-y-especificidad

Selectores CSS y Especificidad

  • 6 min

Un selector CSS es el patrón o regla que utilizamos para indicarle al navegador a qué elemento o elementos HTML queremos aplicar un conjunto de estilos concretos.

Hemos visto que CSS sirve para dar estilo a los elementos. Básicamente (spoiler) diremos esto es rojo, esto tiene un bordecito, esto tiene un margen alrededor…

Lógicamente, necesitamos una forma de decír a qué parte del documento queremos cambiarle el estilo. Es decir, necesitamos “seleccionar” partes del documento.

En CSS tenemos muchisimas formas de seleccionar elementos. Vamos a repasar los tres selectores fundamentales que usaréis constantemente, ordenados de menor a mayor puntería.

Selector de etiqueta

El selector de etiqueta es el más burdo de todos. Apunta directamente al nombre de la etiqueta HTML, sin importarle nada más.

Si usamos el selector p, el navegador aplicará ese estilo a absolutamente todos los párrafos que existan en la página web.

/* Esto pintará TODOS los párrafos de rojo */
p {
    color: red;
    font-size: 16px;
}

/* Esto afectará a TODOS los enlaces */
a {
    text-decoration: none;
}
Copied!

Usar selectores de etiqueta es práctico para establecer los estilos base de vuestro sitio (por ejemplo, definir la tipografía general de los títulos <h1> o <h2>).

Sin embargo, se os quedará muy corto en cuanto queráis que un párrafo concreto sea distinto al resto.

Selector de clase

Este es el selector más usado. Una Clase es un atributo que podemos añadir a cualquier etiqueta HTML para darle un “nombre de grupo”.

Para apuntar a una clase desde nuestro archivo CSS, podemos añadir un punto (.) delante del nombre.

<p class="texto-destacado">Este es un mensaje importante.</p>
<button class="boton-primario">Aceptar</button>
<button class="boton-primario">Cancelar</button>
Copied!
/* En el CSS (fijaos en el punto inicial) */
.texto-destacado {
    color: blue;
    font-weight: bold;
}

.boton-primario {
    background-color: green;
}
Copied!

La gran ventaja de las clases es que son altamente reutilizables. Podéis tener cien elementos distintos con la clase boton-primario, y todos compartirán el mismo aspecto.

Selector de ID

El selector de ID (Identificador) se utiliza para apuntar a un elemento único y exclusivo dentro de toda la página.

EL ID es un atributo especial que puede tener un elemento HTML, con la condición de que no puede haber dos elementos con el mismo id dentro de la página web ^(es unico)

Para llamarlo desde CSS, utilizamos el símbolo de la almohadilla o hashtag (#).

<nav id="menu-principal">...</nav>
Copied!
/* En el CSS (fijaos en la almohadilla) */
#menu-principal {
    background-color: black;
}
Copied!

En la vida real es el menos usado, por amplia diferencia. La condición de que el ID tenga que ser único es demasiado restrictiva (imagina ponerselo a un botón, todos los botones tendrías que tener su ID).

Combinando selectores

Muchas veces no nos va a servir con uno de los selectores, vamos a necesitar combinarlos. CSS nos permite hacer combinaciones muy potentes.

Si queréis afectar a un elemento solo cuando está dentro de otro, usamos un espacio. Es la combinación más importante y empleada.

/* Esto solo pinta de rojo los enlaces que estén DENTRO de un elemento con la clase .tarjeta */
.tarjeta a {
    color: red;
}
Copied!

A diferencia de la descendencia (que afecta a cualquier elemento dentro, sin importar lo profundo que esté), el hijo directo afecta solo a los elementos que están inmediatamente un nivel por debajo.

/* Esto pinta de azul los párrafos que son hijos directos de .contenedor, 
   pero NO afectará a un párrafo que esté dentro de un <div> dentro de .contenedor */
.contenedor > p {
    color: blue;
}

Copied!

Este combinador se usa para seleccionar un elemento que está inmediatamente después de otro, siempre y cuando ambos compartan el mismo elemento padre (es decir, que estén al mismo nivel).

/* Esto aplicará un margen superior solo al PRIMER párrafo que vaya 
   justo después de un <h2>. Ideal para separar el primer texto del título. */
h2 + p {
    margin-top: 20px;
}

Copied!

Es parecido al hermano adyacente, pero menos estricto. Selecciona todos los elementos que van después de otro al mismo nivel (compartiendo padre), sin importar si están justo al lado o si hay otros elementos entre medias.

/* Esto pondrá el texto en gris a TODOS los párrafos que vayan después 
   de una imagen, siempre que estén en el mismo nivel dentro del HTML */
img ~ p {
    color: gray;
}

Copied!

La especificidad

¿Quién gana cuando hay conflicto? Aquí entra en juego el concepto de Especificidad. Es el sistema matemático que usa el navegador para decidir qué regla tiene más peso cuando hay un empate técnico.

Aquí viene uno de los mayores problemas por el que la gente le cuesta entender CSS. ¿Qué pasa si escribimos reglas contradictorias para un mismo elemento?

La regla general es simple, gana el selector más especifico. El orden de peso, de menor a mayor, es el siguiente:

  1. Etiquetas (p, div) valen 1 punto.
  2. Clases (.clase) valen 10 puntos.
  3. IDs (#id) valen 100 puntos.
  4. Estilos en línea (style="..." en el HTML) valen 1000 puntos.

Realmente no suman exactamente puntos. Estrictamente la especificidad se denominan (0 0 1), (0 1 0) y (1 0 0) respesctivamente. Pero básicamente, es lo mismo.

Por ejemplo, imaginemos que tenemos este HTML:

#comprar tiene más peso que .primary, y este más peso que button. Con que exista uno que tiene más peso que el otro (en el widget, que esté activado), el que tenga más especificidad gana.

Dentro de la misma especificidad, se suman. Es decir, si tuvieramos:

  • Un selector que combina dos clases (especificidad 0 2 0)
  • Ganaría a un selector con una clase, (especificidad 0 1 0)
  • Pero ambos perderían ante un selector de ID (especificidad 1 0 0)