Skip to content

2. Selectores y Especificidad

Los selectores CSS son patrones que nos permiten seleccionar elementos HTML para aplicarles estilos. Dominar los selectores es fundamental para escribir CSS eficiente y mantenible.


Los selectores básicos son la base de CSS y los más utilizados en el día a día.

Selecciona todos los elementos de un tipo específico.

/* Selecciona TODOS los párrafos */
p {
color: #333;
line-height: 1.6;
}
/* Selecciona TODOS los h1 */
h1 {
font-size: 2.5rem;
color: #2c3e50;
}
/* Selecciona TODAS las imágenes */
img {
max-width: 100%;
height: auto;
}
<h1>Título principal</h1>
<p>Este es un párrafo.</p>
<p>Este es otro párrafo.</p>
<img src="foto.jpg" alt="Foto">

Selecciona elementos que tienen un atributo class específico. Reutilizable en múltiples elementos.

/* Selecciona elementos con class="destacado" */
.destacado {
background-color: #fff3cd;
border-left: 4px solid #ffc107;
padding: 15px;
font-weight: bold;
}
/* Selecciona elementos con class="boton" */
.boton {
display: inline-block;
padding: 12px 24px;
background-color: #007bff;
color: white;
text-decoration: none;
border-radius: 6px;
transition: background-color 0.3s;
}
.boton:hover {
background-color: #0056b3;
}
<p class="destacado">Texto importante destacado</p>
<div class="destacado">También puedo ser un div</div>
<a href="#" class="boton">Soy un enlace</a>
<button class="boton">Soy un botón</button>

Selecciona un único elemento con un id específico. Debe ser único en la página.

/* Selecciona el elemento con id="encabezado-principal" */
#encabezado-principal {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 60px 20px;
text-align: center;
}
/* Selecciona el elemento con id="menu-navegacion" */
#menu-navegacion {
position: fixed;
top: 0;
width: 100%;
background: rgba(255, 255, 255, 0.95);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
z-index: 1000;
}
<header id="encabezado-principal">
<h1>Mi Sitio Web</h1>
</header>
<nav id="menu-navegacion">
<a href="#inicio">Inicio</a>
<a href="#servicios">Servicios</a>
</nav>

Selecciona TODOS los elementos de la página.

/* Reset básico: Elimina márgenes y padding de todos los elementos */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Aplicar fuente a todos los elementos */
* {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

5. Selector de múltiples elementos (agrupación)

Section titled “5. Selector de múltiples elementos (agrupación)”

Aplica los mismos estilos a varios selectores separados por comas.

/* Aplica a h1, h2, h3, h4, h5 y h6 */
h1, h2, h3, h4, h5, h6 {
font-family: 'Georgia', serif;
color: #2c3e50;
font-weight: 700;
margin-bottom: 1rem;
}
/* Aplica a varios elementos de navegación */
.nav-link, .menu-item, .breadcrumb-link {
text-decoration: none;
color: #007bff;
transition: color 0.3s;
}
.nav-link:hover, .menu-item:hover, .breadcrumb-link:hover {
color: #0056b3;
}

Los selectores combinados permiten seleccionar elementos basándose en su relación con otros elementos.

Selecciona elementos que están dentro de otro elemento (en cualquier nivel).

/* Selecciona todos los <p> dentro de <article> */
article p {
font-size: 1.1rem;
line-height: 1.8;
}
/* Selecciona todos los <a> dentro de <nav> */
nav a {
color: white;
text-decoration: none;
padding: 10px 15px;
}
/* Selecciona <span> dentro de <li> dentro de <ul> */
ul li span {
color: #666;
font-size: 0.9em;
}
<article>
<h2>Título del artículo</h2>
<p>Este párrafo será estilizado</p>
<div>
<p>Este párrafo también (está dentro de article)</p>
</div>
</article>
<p>Este párrafo NO será estilizado (fuera de article)</p>

Selecciona elementos que son hijos directos (primer nivel) de otro elemento.

/* Solo los <li> que son hijos DIRECTOS de <ul> */
ul > li {
list-style-type: square;
margin-bottom: 10px;
}
/* Solo los <p> que son hijos DIRECTOS de <div class="contenedor"> */
.contenedor > p {
background-color: #f0f0f0;
padding: 15px;
}
<ul>
<li>Item 1 ✅ (hijo directo)</li>
<li>Item 2 ✅ (hijo directo)</li>
<li>
Item 3 ✅ (hijo directo)
<ul>
<li>Subitem 3.1 ❌ (nieto, no hijo directo del ul principal)</li>
</ul>
</li>
</ul>

Selecciona el elemento que está inmediatamente después de otro elemento (mismo nivel).

/* El <p> que viene inmediatamente después de <h2> */
h2 + p {
font-size: 1.2rem;
color: #555;
margin-top: 0;
}
/* El <div> que viene inmediatamente después de <img> */
img + div {
margin-top: 20px;
text-align: center;
}
<h2>Título</h2>
<p>Este párrafo ✅ (inmediatamente después de h2)</p>
<p>Este párrafo ❌ (no es el inmediato siguiente)</p>
<h2>Otro título</h2>
<div>Este div ❌ (no es un p)</div>
<p>Este párrafo ❌ (hay un div en medio)</p>

Selecciona todos los elementos hermanos que vienen después de otro elemento.

/* Todos los <p> que vienen después de <h2> (mismo nivel) */
h2 ~ p {
color: #666;
}
/* Todos los <div> que vienen después de <img> */
img ~ div {
border-top: 1px solid #ddd;
padding-top: 15px;
}
<article>
<h2>Título</h2>
<p>Párrafo 1 ✅</p>
<div>Un div en medio</div>
<p>Párrafo 2 ✅</p>
<p>Párrafo 3 ✅</p>
</article>

Seleccionan elementos basándose en sus atributos HTML.

/* Elementos con el atributo "title" */
[title] {
cursor: help;
border-bottom: 1px dotted #999;
}
/* Elementos con atributo type="text" */
[type="text"] {
border: 2px solid #007bff;
padding: 8px;
border-radius: 4px;
}
/* Enlaces con atributo target */
[target] {
background-color: #fff3cd;
padding: 2px 6px;
}
/* Exactamente igual */
[type="submit"] {
background-color: #28a745;
color: white;
padding: 10px 20px;
border: none;
cursor: pointer;
}
[class="destacado"] {
font-weight: bold;
}
<input type="submit" value="Enviar">
<input type="button" value="Cancelar">
/* Estilizar enlaces externos */
a[href^="http"]:not([href*="midominio.com"]) {
color: #e74c3c;
}
a[href^="http"]:not([href*="midominio.com"])::after {
content: " 🔗";
font-size: 0.8em;
}
/* Estilizar inputs según su tipo */
input[type="email"],
input[type="tel"],
input[type="url"] {
background-color: #f0f8ff;
border-left: 3px solid #007bff;
}
/* Archivos descargables con iconos */
a[href$=".pdf"]::before { content: "📄 "; }
a[href$=".doc"]::before,
a[href$=".docx"]::before { content: "📝 "; }
a[href$=".zip"]::before { content: "📦 "; }

Las pseudoclases seleccionan elementos en un estado específico o posición.

/* :hover - Cuando el cursor está sobre el elemento */
.boton:hover {
background-color: #0056b3;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
/* :active - Cuando el elemento está siendo clickeado */
.boton:active {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
/* :focus - Cuando el elemento tiene el foco */
input:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
}
/* :visited - Enlaces ya visitados */
a:visited {
color: #6f42c1;
}
/* Primer hijo de su padre */
li:first-child {
font-weight: bold;
color: #007bff;
}
p:first-child {
margin-top: 0;
}
<ul>
<li>Item 1 ✅ (primer hijo)</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
/* :checked - Checkbox o radio seleccionado */
input[type="checkbox"]:checked {
accent-color: #28a745;
}
input[type="checkbox"]:checked + label {
color: #28a745;
font-weight: bold;
}
/* :disabled - Elemento deshabilitado */
input:disabled {
background-color: #e9ecef;
cursor: not-allowed;
opacity: 0.6;
}
/* :enabled - Elemento habilitado */
input:enabled {
background-color: white;
}
/* :required - Campo obligatorio */
input:required {
border-left: 3px solid #ffc107;
}
/* :valid - Campo con valor válido */
input:valid {
border-color: #28a745;
}
/* :invalid - Campo con valor inválido */
input:invalid {
border-color: #dc3545;
}
/* :placeholder-shown - Cuando se muestra el placeholder */
input:placeholder-shown {
font-style: italic;
}
/* :not() - Negación */
li:not(.especial) {
color: #666;
}
button:not(:disabled):hover {
background-color: #0056b3;
}
/* :empty - Elementos vacíos */
p:empty {
display: none;
}
/* :only-child - Único hijo */
li:only-child {
list-style: none;
text-align: center;
}
/* :root - Elemento raíz (html) */
:root {
--color-primario: #007bff;
--color-secundario: #6c757d;
}

Los pseudoelementos crean elementos virtuales para estilizar partes específicas de un elemento. Se escriben con :: (doble dos puntos).

Insertan contenido antes o después del contenido de un elemento.

/* ::before - Antes del contenido */
.nota::before {
content: "📌 ";
font-size: 1.2em;
margin-right: 8px;
}
/* ::after - Después del contenido */
.enlace-externo::after {
content: " 🔗";
font-size: 0.8em;
color: #007bff;
}
/* Ejemplo: Comillas decorativas */
blockquote::before {
content: """;
font-size: 4rem;
color: #007bff;
position: absolute;
top: -20px;
left: -10px;
opacity: 0.3;
}
blockquote::after {
content: """;
font-size: 4rem;
color: #007bff;
position: absolute;
bottom: -40px;
right: -10px;
opacity: 0.3;
}
<p class="nota">Este es un mensaje importante</p>
<a href="https://ejemplo.com" class="enlace-externo">Visitar sitio</a>
<blockquote>
La vida es como andar en bicicleta. Para mantener el equilibrio,
debes seguir adelante.
</blockquote>

Ejemplos prácticos con ::before y ::after

Section titled “Ejemplos prácticos con ::before y ::after”
/* Agregar iconos sin HTML adicional */
.email::before {
content: "✉️ ";
}
.telefono::before {
content: "📱 ";
}
.ubicacion::before {
content: "📍 ";
}
.descarga::after {
content: " ⬇️";
}
/* ::first-letter - Primera letra */
p::first-letter {
font-size: 3em;
font-weight: bold;
color: #007bff;
float: left;
line-height: 0.8;
margin-right: 8px;
}
/* ::first-line - Primera línea */
p::first-line {
font-weight: bold;
color: #2c3e50;
text-transform: uppercase;
}
/* ::selection - Texto seleccionado */
::selection {
background-color: #007bff;
color: white;
}
/* ::placeholder - Placeholder de inputs */
input::placeholder {
color: #999;
font-style: italic;
opacity: 0.7;
}
/* ::marker - Marcador de listas */
li::marker {
color: #007bff;
font-size: 1.5em;
}

La especificidad determina qué estilos se aplican cuando hay conflictos. Es como un sistema de puntos.

  1. Inline styles 1000 puntos

    <p style="color: red;">Texto</p>
  2. IDs 100 puntos

    #encabezado { color: blue; }
  3. Clases, atributos, pseudoclases 10 puntos

    .destacado { color: green; }
    [type="text"] { color: green; }
    :hover { color: green; }
  4. Elementos y pseudoelementos 1 punto

    p { color: black; }
    ::before { color: black; }
/* Especificidad: 0-0-0-1 = 1 punto */
p {
color: black;
}
/* Especificidad: 0-0-1-0 = 10 puntos */
.texto {
color: blue;
}
/* Especificidad: 0-1-0-0 = 100 puntos */
#principal {
color: red;
}
/* Especificidad: 1-0-0-0 = 1000 puntos */
<p style="color: green;">
<p id="principal" class="texto" style="color: green;">
¿De qué color será? 🤔
</p>

Resultado: 🟢 Verde (inline gana con 1000 puntos)

SelectorInlineIDsClases/Attrs/PseudoElementosTotal
p00011
.clase001010
#id0100100
style=""10001000
p.clase001111
div p.clase001212
#id .clase p0111111
div#id.clase p::before0112112
/* Mismo nivel de especificidad: El último gana */
p { color: red; }
p { color: blue; } /* ✅ Este se aplica */
/* !important sobrescribe todo (¡evitar!) */
p { color: red !important; } /* ✅ Este gana */
p { color: blue; }
/* Especificidad vs orden */
.texto { color: red; } /* 10 puntos */
p { color: blue; } /* 1 punto */
/* ✅ Gana .texto (mayor especificidad) */
/* ❌ Evitar: Especificidad muy alta */
#contenedor #articulo div.texto p {
color: red;
}
/* ✅ Mejor: Especificidad baja y reutilizable */
.articulo-texto {
color: red;
}
/* ❌ Evitar: !important innecesario */
.boton {
background: blue !important;
}
/* ✅ Mejor: Aumentar especificidad correctamente */
.contenedor .boton {
background: blue;
}
/* ✅ Usar clases específicas */
.boton-primario { background: blue; }
.boton-secundario { background: gray; }

🐝