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.
🎯 Selectores básicos
Section titled “🎯 Selectores básicos”Los selectores básicos son la base de CSS y los más utilizados en el día a día.
1. Selector de elemento (tipo)
Section titled “1. Selector de elemento (tipo)”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">✅ Todos los h1 tendrán font-size: 2.5rem✅ Todos los p tendrán color: #333✅ Todas las img tendrán max-width: 100%2. Selector de clase (.clase)
Section titled “2. Selector de clase (.clase)”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>/* Ambos elementos con class="destacado" tendrán el mismo estilo */.destacado { background-color: #fff3cd; /* ... */}
/* Ambos elementos con class="boton" se verán igual */.boton { padding: 12px 24px; /* ... */}3. Selector de ID (#id)
Section titled “3. Selector de ID (#id)”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>✅ Un ID debe ser único en la página✅ Tiene mayor especificidad que las clases⚠️ No se puede reutilizar⚠️ Dificulta la reutilización de estilos4. Selector universal (*)
Section titled “4. Selector universal (*)”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;}🔗 Selectores combinados
Section titled “🔗 Selectores combinados”Los selectores combinados permiten seleccionar elementos basándose en su relación con otros elementos.
1. Selector descendiente (espacio)
Section titled “1. Selector descendiente (espacio)”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>article ├── h2 ├── p ✅ (seleccionado) └── div └── p ✅ (seleccionado - descendiente indirecto)
p ❌ (no seleccionado - no está dentro de article)2. Selector hijo directo (>)
Section titled “2. Selector hijo directo (>)”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>/* Descendiente: Todos los niveles */ul li { color: blue; }/* ✅ Item 1, Item 2, Item 3, Subitem 3.1 */
/* Hijo directo: Solo primer nivel */ul > li { color: red; }/* ✅ Item 1, Item 2, Item 3 ❌ Subitem 3.1 */3. Selector hermano adyacente (+)
Section titled “3. Selector hermano adyacente (+)”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>h2p ✅ (seleccionado - hermano adyacente)p ❌ (no adyacente a h2)
h2div ❌ (no es p)p ❌ (no es adyacente a h2)4. Selector hermanos generales (~)
Section titled “4. Selector hermanos generales (~)”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>/* Hermano adyacente (+): Solo el inmediato */h2 + p { color: red; }/* ✅ Solo Párrafo 1 */
/* Hermanos generales (~): Todos los siguientes */h2 ~ p { color: blue; }/* ✅ Párrafo 1, Párrafo 2, Párrafo 3 */📋 Selectores de atributos
Section titled “📋 Selectores de atributos”Seleccionan elementos basándose en sus atributos HTML.
Sintaxis básica
Section titled “Sintaxis básica”/* 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;}Variantes de selectores de atributos
Section titled “Variantes de selectores de atributos”/* 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"> ❌/* Contiene la palabra completa (separada por espacios) */[class~="activo"] { background-color: #007bff; color: white;}<div class="menu activo"> ✅<div class="activo-menu"> ❌ (no es palabra completa)<div class="menu activo destacado"> ✅/* Empieza con... */[href^="https"] { color: green;}
[href^="http://"] { color: orange;}
[class^="btn-"] { padding: 10px 15px; border-radius: 4px;}<a href="https://ejemplo.com"> ✅ verde<a href="http://ejemplo.com"> ✅ naranja<button class="btn-primary"> ✅<button class="btn-secondary"> ✅/* Termina con... */[href$=".pdf"] { background: url('pdf-icon.png') no-repeat left center; padding-left: 25px;}
[src$=".jpg"], [src$=".png"] { border: 2px solid #ddd; border-radius: 8px;}<a href="documento.pdf"> ✅<a href="archivo.doc"> ❌<img src="foto.jpg"> ✅<img src="imagen.png"> ✅/* Contiene la subcadena en cualquier parte */[href*="youtube"] { color: red; font-weight: bold;}
[class*="col-"] { float: left; padding: 15px;}<a href="https://www.youtube.com/watch"> ✅<a href="https://youtu.be/abc123"> ✅<div class="col-md-6"> ✅<div class="col-lg-4"> ✅/* Empieza con la palabra seguida de guion o es exacta */[lang|="es"] { font-family: 'Arial', sans-serif;}<p lang="es"> ✅<p lang="es-MX"> ✅<p lang="es-ES"> ✅<p lang="en"> ❌Ejemplos prácticos
Section titled “Ejemplos prácticos”/* 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: "📦 "; }🎨 Pseudoclases
Section titled “🎨 Pseudoclases”Las pseudoclases seleccionan elementos en un estado específico o posición.
Pseudoclases de interacción
Section titled “Pseudoclases de interacció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;}Pseudoclases estructurales
Section titled “Pseudoclases estructurales”/* 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>/* Último hijo de su padre */li:last-child { border-bottom: none;}
.menu-item:last-child { margin-right: 0;}<ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3 ✅ (último hijo)</li></ul>/* Elementos pares */tr:nth-child(even) { background-color: #f8f9fa;}
/* Elementos impares */tr:nth-child(odd) { background-color: white;}
/* Cada tercer elemento */li:nth-child(3n) { color: #e74c3c;}
/* Elemento específico (el 5to) */li:nth-child(5) { font-weight: bold;}
/* Los primeros 3 elementos */li:nth-child(-n+3) { color: #28a745;}<ul> <li>Item 1 ✅ (impar, primeros 3)</li> <li>Item 2 ✅ (par, primeros 3)</li> <li>Item 3 ✅ (impar, múltiplo de 3, primeros 3)</li> <li>Item 4 ✅ (par)</li> <li>Item 5 ✅ (impar, específico)</li> <li>Item 6 ✅ (par, múltiplo de 3)</li></ul>/* Segundo párrafo de su tipo */p:nth-of-type(2) { font-size: 1.2rem; color: #007bff;}
/* Cada imagen impar */img:nth-of-type(odd) { float: left; margin-right: 20px;}<div> <h2>Título</h2> <p>Párrafo 1</p> <p>Párrafo 2 ✅ (segundo p)</p> <div>Otro elemento</div> <p>Párrafo 3</p></div>Pseudoclases de formulario
Section titled “Pseudoclases de formulario”/* :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;}Otras pseudoclases útiles
Section titled “Otras pseudoclases útiles”/* :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;}✨ Pseudoelementos
Section titled “✨ Pseudoelementos”Los pseudoelementos crean elementos virtuales para estilizar partes específicas de un elemento. Se escriben con :: (doble dos puntos).
::before y ::after
Section titled “::before y ::after”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>📌 Este es un mensaje importante
Visitar sitio 🔗
" La vida es como andar en bicicleta... "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: " ⬇️";}/* Badge de "nuevo" */.producto-nuevo::after { content: "NUEVO"; background-color: #28a745; color: white; padding: 2px 8px; border-radius: 12px; font-size: 0.7em; margin-left: 10px; font-weight: bold;}
/* Badge de descuento */.con-descuento::before { content: "-50%"; background-color: #dc3545; color: white; padding: 4px 8px; border-radius: 4px; position: absolute; top: 10px; right: 10px;}/* Separador entre items */.breadcrumb li::after { content: " / "; color: #6c757d; margin: 0 8px;}
.breadcrumb li:last-child::after { content: "";}
/* Línea decorativa */.titulo-seccion::before { content: ""; display: block; width: 50px; height: 4px; background-color: #007bff; margin-bottom: 15px;}/* Tooltip simple */.tooltip { position: relative; cursor: help;}
.tooltip::after { content: attr(data-tooltip); position: absolute; bottom: 125%; left: 50%; transform: translateX(-50%); background-color: #333; color: white; padding: 8px 12px; border-radius: 6px; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity 0.3s; font-size: 0.9em;}
.tooltip:hover::after { opacity: 1;}<span class="tooltip" data-tooltip="Información adicional"> Pasa el mouse aquí</span>Otros pseudoelementos
Section titled “Otros pseudoelementos”/* ::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;}🎯 Especificidad y orden de aplicación
Section titled “🎯 Especificidad y orden de aplicación”La especificidad determina qué estilos se aplican cuando hay conflictos. Es como un sistema de puntos.
Cálculo de especificidad
Section titled “Cálculo de especificidad”-
Inline styles 1000 puntos
<p style="color: red;">Texto</p> -
IDs 100 puntos
#encabezado { color: blue; } -
Clases, atributos, pseudoclases 10 puntos
.destacado { color: green; }[type="text"] { color: green; }:hover { color: green; } -
Elementos y pseudoelementos 1 punto
p { color: black; }::before { color: black; }
Ejemplos de cálculo
Section titled “Ejemplos de cálculo”/* 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)
/* 0-0-1-1 = 11 puntos */p.destacado { color: blue;}
/* 0-0-2-0 = 20 puntos */.contenedor .destacado { color: red;}
/* 0-1-1-0 = 110 puntos */#articulo .destacado { color: green;}<div id="articulo" class="contenedor"> <p class="destacado">¿De qué color será?</p></div>Resultado: 🟢 Verde (#articulo .destacado tiene 110 puntos)
/* 0-0-0-2 = 2 puntos */div p { color: black;}
/* 0-0-1-1 = 11 puntos */div p.importante { color: blue;}
/* 0-0-2-1 = 21 puntos */.contenedor p.importante { color: red;}
/* 0-1-0-1 = 101 puntos */#main p { color: green;}Orden de aplicación:
#main p→ 101 puntos ✅ GANA.contenedor p.importante→ 21 puntosdiv p.importante→ 11 puntosdiv p→ 2 puntos
Tabla de especificidad
Section titled “Tabla de especificidad”| Selector | Inline | IDs | Clases/Attrs/Pseudo | Elementos | Total |
|---|---|---|---|---|---|
p | 0 | 0 | 0 | 1 | 1 |
.clase | 0 | 0 | 1 | 0 | 10 |
#id | 0 | 1 | 0 | 0 | 100 |
style="" | 1 | 0 | 0 | 0 | 1000 |
p.clase | 0 | 0 | 1 | 1 | 11 |
div p.clase | 0 | 0 | 1 | 2 | 12 |
#id .clase p | 0 | 1 | 1 | 1 | 111 |
div#id.clase p::before | 0 | 1 | 1 | 2 | 112 |
Reglas de cascada
Section titled “Reglas de cascada”/* 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) */Buenas prácticas de especificidad
Section titled “Buenas prácticas de 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; }