Selectores básicos y especificidad
Sintaxis de una regla CSS
Una regla CSS tiene dos partes: el selector (a qué elemento apunta) y el bloque de declaraciones (qué estilos aplica). Cada declaración es un par propiedad/valor separado por dos puntos y terminado en punto y coma:
selector {
propiedad: valor;
propiedad: valor;
}
h1 {
color: #333;
font-size: 2rem;
margin-bottom: 1rem;
}
Selector de elemento
El selector de elemento (también llamado selector de tipo) apunta a todas las instancias de una etiqueta HTML en el documento:
p { line-height: 1.6; }
h2 { font-size: 1.5rem; }
table { border-collapse: collapse; }
Es el selector más genérico: afecta a todos los elementos de ese tipo sin excepción. Útil para establecer estilos base, pero no para estilos específicos de un componente.
Selector de clase
El selector de clase apunta a todos los elementos que tengan ese valor en su atributo class. Se escribe con un punto delante del nombre:
.alerta { background: #fff3cd; border-left: 4px solid #ffc107; }
.btn-primario { background: #84ba3f; color: white; }
.texto-muted { color: #888; font-size: 0.875rem; }
<p class="alerta">Atención: revisa los datos.</p>
<button class="btn-primario">Guardar</button>
Un elemento puede tener varias clases separadas por espacios:
<p class="alerta texto-muted">Aviso secundario</p>
El selector puede combinarse con un tipo de elemento para restringir su alcance:
/* Solo los <p> con clase .alerta, no los <div> con .alerta */
p.alerta { padding: 0.75rem; }
/* Elemento con ambas clases a la vez */
p.alerta.texto-muted { opacity: 0.8; }
Las clases son la herramienta principal del CSS moderno. Son reutilizables, combinables y no imponen restricciones de unicidad.
Selector de ID
El selector de ID apunta al elemento que tenga ese valor en su atributo id. Se escribe con una almohadilla delante:
#cabecera-principal { background: #1a1a1a; }
#modal-confirmacion { position: fixed; z-index: 1000; }
<header id="cabecera-principal">...</header>
El id debe ser único en la página: solo puede haber un elemento con cada valor. Esa restricción, sumada a la alta especificidad del selector de ID (lo veremos en breve), hace que en CSS moderno se prefieran las clases para casi todo. Los IDs se reservan principalmente para anclas de navegación y para el trabajo con JavaScript.
Selector universal
El asterisco * selecciona todos los elementos del documento:
/* Reset del modelo de caja para todos los elementos */
*, *::before, *::after {
box-sizing: border-box;
}
/* Quitar márgenes y paddings por defecto */
* {
margin: 0;
padding: 0;
}
Tiene especificidad cero: cualquier otra regla lo sobreescribe. Su uso más habitual es precisamente en resets globales al inicio de la hoja de estilos.
Agrupación con coma
La coma agrupa selectores para aplicarles las mismas declaraciones sin repetir el bloque:
h1, h2, h3, h4 {
font-family: Georgia, serif;
line-height: 1.2;
}
input, textarea, select {
font-family: inherit;
font-size: 1rem;
}
Es azúcar sintáctico: equivale exactamente a escribir el bloque una vez por selector. Cada selector de la lista mantiene su especificidad propia.
Herencia
Algunas propiedades CSS se heredan automáticamente de padres a hijos. Si defines font-family en body, todos los elementos de la página usan esa fuente a menos que tengan su propia regla:
body {
font-family: 'Segoe UI', sans-serif;
color: #333;
line-height: 1.6;
}
Las propiedades que se heredan son principalmente las tipográficas: font-family, font-size, font-weight, color, line-height, text-align, list-style.
Las propiedades que no se heredan son las que afectan al modelo de caja y al layout: margin, padding, border, width, height, background, display, position. Tiene sentido: sería caótico que el padding del contenedor se propagara a todos sus hijos.
Puedes forzar la herencia explícitamente con inherit, o restablecer el valor inicial con initial:
/* Los controles de formulario no heredan la fuente por defecto; forzamos que sí */
input, button {
font-family: inherit;
}
/* Restablecer el color a su valor por defecto del navegador */
a.sin-color {
color: initial;
}
Especificidad
Cuando varias reglas apuntan al mismo elemento y la misma propiedad, el navegador necesita decidir cuál gana. Lo hace calculando la especificidad de cada selector: una puntuación que determina su "peso".
La especificidad se calcula en tres columnas independientes:
| Columna A | Columna B | Columna C |
|---|---|---|
Selectores de ID (#id) |
Clases (.clase), pseudoclases (:hover), atributos ([type]) |
Elementos (p, div), pseudoelementos (::before) |
La comparación se hace columna por columna de izquierda a derecha, como si fueran cifras de un número. La columna A siempre pesa más que cualquier valor en B o C:
p { color: blue; } /* 0-0-1 */
.destacado { color: green; } /* 0-1-0 */
p.destacado { color: red; } /* 0-1-1 */
#titular { color: purple; } /* 1-0-0 */
<p class="destacado" id="titular">¿De qué color soy?</p>
El párrafo es morado: el selector de ID (1-0-0) gana a todos los demás.
Si dos selectores tienen la misma especificidad, gana el que aparece más abajo en el CSS:
.btn { background: blue; }
.btn { background: green; } /* gana: misma especificidad, aparece después */
Los estilos inline (style="...") tienen una especificidad superior a cualquier selector de hoja de estilos, equivalente a (1-0-0-0) en una notación de cuatro columnas.
!important rompe el sistema: una declaración con !important gana sobre cualquier otra sin !important, sin importar la especificidad. Úsalo solo como último recurso, especialmente en reglas de accesibilidad (prefers-reduced-motion) o resets muy específicos.
La cascada y el orden
La "C" de CSS es Cascading: el navegador resuelve los conflictos en este orden de prioridad:
- Origen: las hojas de estilo del usuario (configuración del navegador) pueden sobreescribir las del autor. Las reglas del navegador (estilos por defecto) tienen el menor peso.
!important: gana sobre todo lo demás, independientemente del origen.- Especificidad: el selector más específico gana.
- Orden: entre selectores de igual especificidad, el que aparece más abajo en el CSS gana.
En la práctica, el origen rara vez es relevante en el desarrollo cotidiano. Lo que importa es entender especificidad y orden para diagnosticar por qué un estilo no se aplica como se esperaba.
Tu proyecto
Abre proyecto.html y añade una clase nav-principal al <nav>. Luego en estilos.css estiliza la navegación y añade una clase reutilizable para los elementos que quieras destacar:
<nav class="nav-principal">
<a href="#presentacion">Inicio</a>
<a href="#proyectos">Proyectos</a>
<a href="#contacto">Contacto</a>
</nav>
.nav-principal {
display: flex;
gap: 1.5rem;
margin-bottom: 2rem;
}
.nav-principal a {
color: #555;
text-decoration: none;
font-size: 0.9rem;
letter-spacing: 0.05em;
text-transform: uppercase;
}
Fíjate en el selector .nav-principal a: apunta solo a los enlaces dentro del nav, sin afectar a otros <a> de la página. Eso es especificidad en la práctica.
Recapitulación
- Una regla CSS = selector + bloque de declaraciones (propiedad: valor).
- Selector de elemento: apunta a todas las instancias de una etiqueta. Selector de clase (
.): reutilizable, combinable. Selector de ID (#): único por página, alta especificidad. - El selector universal (
*) apunta a todos los elementos, con especificidad cero. - La coma agrupa selectores para compartir declaraciones.
- La herencia propaga propiedades tipográficas de padres a hijos. Las propiedades de caja y layout no se heredan.
- La especificidad se calcula en tres columnas: IDs (A), clases/pseudoclases/atributos (B), elementos/pseudoelementos (C). A siempre pesa más que B o C.
- Entre selectores de igual especificidad, gana el que aparece más abajo. Los estilos inline superan a cualquier hoja de estilos.
!importantlo supera todo.
En la próxima lección: color en CSS: formatos, transparencia, fondos y la herramienta más importante a la hora de elegir colores, el contraste de accesibilidad.