📚 Guía Completa de Selectores CSS

De básico a avanzado - Con ejemplos interactivos

1. Selectores Básicos

Los selectores básicos son la base de CSS. Permiten seleccionar elementos de forma simple y directa.

1.1 Selector Universal (*)

* { margin: 0; padding: 0; } /* Selecciona TODOS los elementos */
<!-- HTML del ejemplo --> <div> <p>Todos los elementos tienen borde punteado</p> <span>Incluyendo este span</span> </div>

Todos los elementos tienen borde punteado

Incluyendo este span

1.2 Selector de Elemento (Tipo)

p { color: blue; } /* Selecciona todos los elementos <p> */
<!-- HTML del ejemplo --> <p>Este es un párrafo</p> <p>Este es otro párrafo</p> <div>Este es un div (no se aplica)</div>

Este es un párrafo

Este es otro párrafo

Este es un div (no se aplica)

1.3 Selector de Clase (.clase)

.destacado { background: yellow; font-weight: bold; } /* Selecciona elementos con class="destacado" */
<!-- HTML del ejemplo --> <p>Párrafo normal</p> <p class="destacado">Párrafo destacado</p> <div class="destacado">Div destacado</div>

Párrafo normal

Párrafo destacado

Div destacado

1.4 Selector de ID (#id)

#unico { background: red; color: white; } /* Selecciona el elemento con id="unico" */
<!-- HTML del ejemplo --> <div id="unico">Este elemento tiene un ID único</div>
Este elemento tiene un ID único
Importante: Los IDs deben ser únicos en la página. Usa clases para estilos reutilizables.

1.5 Selector de Agrupación (,)

h1, h2, h3 { color: blue; } /* Selecciona h1, h2 Y h3 */
<!-- HTML del ejemplo --> <h1>Título 1</h1> <h2>Título 2</h2> <h3>Título 3</h3> <p>Párrafo normal</p>

Título 1

Título 2

Título 3

Párrafo normal

2. Selectores Combinados

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

2.1 Selector Descendiente (espacio)

div p { color: red; } /* Selecciona todos los <p> dentro de un <div> (a cualquier nivel) */
<!-- HTML del ejemplo --> <div> <p>Este párrafo está dentro de un div (será rojo)</p> <section> <p>Este párrafo también está dentro del div, aunque anidado (será rojo)</p> </section> </div> <p>Este párrafo NO está dentro de un div (no se aplica)</p>

Este párrafo está dentro de un div (será rojo)

Este párrafo también está dentro del div, aunque anidado (será rojo)

Este párrafo NO está dentro de un div (no se aplica)

2.2 Selector de Hijo Directo (>)

div > p { background: blue; } /* Selecciona solo los <p> que son hijos DIRECTOS de <div> */
<!-- HTML del ejemplo --> <div> <p>Este párrafo es hijo directo del div (fondo azul)</p> <section> <p>Este párrafo NO es hijo directo del div (no se aplica)</p> </section> <p>Este también es hijo directo (fondo azul)</p> </div>

Este párrafo es hijo directo del div (fondo azul)

Este párrafo NO es hijo directo del div (no se aplica)

Este también es hijo directo (fondo azul)

2.3 Selector de Hermano Adyacente (+)

h3 + p { background: green; } /* Selecciona el <p> que viene INMEDIATAMENTE después de un <h3> */
<!-- HTML del ejemplo --> <h3>Título de ejemplo</h3> <p>Este párrafo viene justo después del h3 (fondo verde)</p> <p>Este párrafo NO viene inmediatamente después del h3 (no se aplica)</p>

Título de ejemplo

Este párrafo viene justo después del h3 (fondo verde)

Este párrafo NO viene inmediatamente después del h3 (no se aplica)

2.4 Selector de Hermanos Generales (~)

h3 ~ p { border-left: 4px solid purple; } /* Selecciona TODOS los <p> que son hermanos de <h3> y vienen después */
<!-- HTML del ejemplo --> <h3>Título de ejemplo</h3> <p>Primer párrafo después del h3 (borde morado)</p> <div>Un div intermedio</div> <p>Segundo párrafo después del h3 (borde morado)</p> <p>Tercer párrafo después del h3 (borde morado)</p>

Título de ejemplo

Primer párrafo después del h3 (borde morado)

Un div intermedio

Segundo párrafo después del h3 (borde morado)

Tercer párrafo después del h3 (borde morado)

3. Selectores de Atributo

Permiten seleccionar elementos basándose en sus atributos y valores.

3.1 Tipos de Selectores de Atributo

[atributo] /* Tiene el atributo */ [atributo="valor"] /* Valor exacto */ [atributo^="valor"] /* Comienza con */ [atributo$="valor"] /* Termina con */ [atributo*="valor"] /* Contiene */ [atributo~="valor"] /* Contiene palabra completa */ [atributo|="valor"] /* Comienza con valor seguido de guion */
<!-- HTML del ejemplo --> <p><a href="https://www.ejemplo.com">Enlace HTTPS (verde)</a></p> <p><a href="documento.pdf">Enlace a PDF (rojo)</a></p> <p><a href="https://www.google.com">Enlace a Google (fondo naranja)</a></p> <p><input type="text" placeholder="Input tipo text (borde azul)"></p> <p><input type="email" placeholder="Input tipo email (borde rojo)"></p> <p><input type="text" disabled value="Deshabilitado"></p>

4. Pseudo-clases de Estado

Seleccionan elementos basándose en su estado actual.

4.1 Estados de Enlaces

a:link /* Enlace no visitado */ a:visited /* Enlace visitado */ a:hover /* Al pasar el ratón */ a:active /* Al hacer clic */
<!-- HTML del ejemplo --> <a href="#">Pasa el ratón sobre este enlace</a>

Pasa el ratón sobre este enlace

Nota: El orden importa: :link, :visited, :hover, :active (LVHA)

4.2 Estados de Formularios

input:focus /* Cuando tiene el foco */ input:disabled /* Cuando está deshabilitado */ input:enabled /* Cuando está habilitado */ input:checked /* Checkbox/radio marcado */
<!-- HTML del ejemplo --> <input type="text" placeholder="Haz clic aquí para ver :focus"> <input type="text" disabled value="Campo deshabilitado"> <input type="checkbox" id="check1"> <label for="check1">Márcame</label>

4.3 Estado Hover en Botones

button:hover { background: green; transform: scale(1.05); }
<!-- HTML del ejemplo --> <button>Pasa el ratón sobre mí</button>

5. Pseudo-clases Estructurales

Seleccionan elementos basándose en su posición en el DOM.

5.1 Posición entre Hermanos (child)

:first-child /* Primer hijo */ :last-child /* Último hijo */ :nth-child(n) /* Enésimo hijo */ :nth-child(even) /* Hijos pares */ :nth-child(odd) /* Hijos impares */
<!-- HTML del ejemplo --> <ul> <li>Primer elemento (fondo azul)</li> <li>Segundo elemento (par - fondo gris claro)</li> <li>Tercer elemento (impar - fondo gris oscuro)</li> <li>Cuarto elemento (par - fondo gris claro)</li> <li>Último elemento (fondo rojo)</li> </ul>
  • Primer elemento (fondo azul)
  • Segundo elemento (par - fondo gris claro)
  • Tercer elemento (impar - fondo gris oscuro)
  • Cuarto elemento (par - fondo gris claro)
  • Último elemento (fondo rojo)
Nota: Pasa el ratón sobre los elementos para ver el efecto hover.

5.2 Posición por Tipo (of-type)

p:first-of-type /* Primer <p> */ p:last-of-type /* Último <p> */ p:nth-of-type(2) /* Segundo <p> */ div:only-child /* Único hijo */ p:empty /* Elemento vacío */
<!-- HTML del ejemplo --> <div> <h3>Título</h3> <p>Primer párrafo (azul, grande)</p> <p>Segundo párrafo</p> <p>Último párrafo (cursiva, gris)</p> <p></p> <!-- Párrafo vacío (fondo rojo) --> </div>

Título

Primer párrafo (azul, grande)

Segundo párrafo

Último párrafo (cursiva, gris)

6. Pseudo-clases Avanzadas

Selectores más complejos para casos específicos.

6.1 Negación (:not)

p:not(.especial) { color: gray; } /* Selecciona todos los <p> EXCEPTO los que tienen class="especial" */
<!-- HTML del ejemplo --> <p>Párrafo normal (gris)</p> <p class="especial">Párrafo especial (naranja)</p> <p>Otro párrafo normal (gris)</p>

Párrafo normal (gris)

Párrafo especial (naranja)

Otro párrafo normal (gris)

6.2 Coincidencia (:is)

:is(h1, h2, h3) { color: blue; } /* Equivalente a: h1, h2, h3 { color: blue; } */
<!-- HTML del ejemplo --> <h1>Título 1</h1> <h2>Título 2</h2> <h3>Título 3</h3> <p>Párrafo normal</p>

Título 1

Título 2

Título 3

Párrafo normal

Ventaja: :is() es útil para simplificar selectores complejos y reducir repetición.

4. Pseudo-clases de Estado

Seleccionan elementos basándose en su estado actual.

4.1 Estados de Enlaces

a:link /* Enlace no visitado */ a:visited /* Enlace visitado */ a:hover /* Al pasar el ratón */ a:active /* Al hacer clic */
<!-- HTML del ejemplo --> <a href="#">Pasa el ratón sobre este enlace</a>

Pasa el ratón sobre este enlace

Nota: El orden importa: :link, :visited, :hover, :active (LVHA)

4.2 Estados de Formularios

input:focus /* Cuando tiene el foco */ input:disabled /* Cuando está deshabilitado */ input:enabled /* Cuando está habilitado */ input:checked /* Checkbox/radio marcado */
<!-- HTML del ejemplo --> <input type="text" placeholder="Haz clic aquí para ver :focus"> <input type="text" disabled value="Campo deshabilitado"> <input type="checkbox" id="check1"> <label for="check1">Márcame</label>

4.3 Estado Hover en Botones

button:hover { background: green; transform: scale(1.05); }
<!-- HTML del ejemplo --> <button>Pasa el ratón sobre mí</button>

5. Pseudo-clases Estructurales

Seleccionan elementos basándose en su posición en el DOM.

5.1 Posición entre Hermanos (child)

:first-child /* Primer hijo */ :last-child /* Último hijo */ :nth-child(n) /* Enésimo hijo */ :nth-child(even) /* Hijos pares */ :nth-child(odd) /* Hijos impares */
<!-- HTML del ejemplo --> <ul> <li>Primer elemento (fondo azul)</li> <li>Segundo elemento (par - fondo gris claro)</li> <li>Tercer elemento (impar - fondo gris oscuro)</li> <li>Cuarto elemento (par - fondo gris claro)</li> <li>Último elemento (fondo rojo)</li> </ul>
  • Primer elemento (fondo azul)
  • Segundo elemento (par - fondo gris claro)
  • Tercer elemento (impar - fondo gris oscuro)
  • Cuarto elemento (par - fondo gris claro)
  • Último elemento (fondo rojo)
Nota: Pasa el ratón sobre los elementos para ver el efecto hover.

5.2 Posición por Tipo (of-type)

p:first-of-type /* Primer <p> */ p:last-of-type /* Último <p> */ p:nth-of-type(2) /* Segundo <p> */ div:only-child /* Único hijo */ p:empty /* Elemento vacío */
<!-- HTML del ejemplo --> <div> <h3>Título</h3> <p>Primer párrafo (azul, grande)</p> <p>Segundo párrafo</p> <p>Último párrafo (cursiva, gris)</p> <p></p> <!-- Párrafo vacío (fondo rojo) --> </div>

Título

Primer párrafo (azul, grande)

Segundo párrafo

Último párrafo (cursiva, gris)

6. Pseudo-clases Avanzadas

Selectores más complejos para casos específicos.

6.1 Negación (:not)

p:not(.especial) { color: gray; } /* Selecciona todos los <p> EXCEPTO los que tienen class="especial" */
<!-- HTML del ejemplo --> <p>Párrafo normal (gris)</p> <p class="especial">Párrafo especial (naranja)</p> <p>Otro párrafo normal (gris)</p>

Párrafo normal (gris)

Párrafo especial (naranja)

Otro párrafo normal (gris)

6.2 Coincidencia (:is)

:is(h1, h2, h3) { color: blue; } /* Equivalente a: h1, h2, h3 { color: blue; } */
<!-- HTML del ejemplo --> <h1>Título 1</h1> <h2>Título 2</h2> <h3>Título 3</h3> <p>Párrafo normal</p>

Título 1

Título 2

Título 3

Párrafo normal

Ventaja: :is() es útil para simplificar selectores complejos y reducir repetición.

6.3 Pseudo-clase :has() (El "Selector Padre")

La pseudo-clase :has() es una de las características más potentes y esperadas de CSS. Permite seleccionar un elemento si contiene otro elemento específico (o si le sigue otro elemento).

Aunque a menudo se le llama "selector padre" (porque permite estilar al padre basándose en sus hijos), es mucho más versátil. Funciona como un condicional: "Aplica estos estilos SI se cumple esta condición".

Casos de uso comunes:
  • Estilar una tarjeta (.card) de forma diferente si contiene una imagen (.card:has(img)).
  • Cambiar el estilo de un formulario o label si un input es inválido (form:has(input:invalid)).
  • Estilar un contenedor si alguno de sus hijos tiene el foco (.container:has(:focus)).
  • Seleccionar un elemento basándose en su hermano siguiente (h1:has(+ p)).
div:has(p) { border: 2px solid red; } /* Selecciona divs que CONTIENEN párrafos */
<!-- HTML del ejemplo --> <div id="has-target"> <p>Este div tiene un párrafo dentro.</p> </div> <div>Este div NO tiene párrafo.</div>

Este div tiene un párrafo dentro.

Este div NO tiene párrafo.

6.4 Pseudo-clase :where() y :is()

Tanto :where() como :is() se utilizan para agrupar selectores y reducir la repetición de código. Sin embargo, tienen una diferencia crucial en cuanto a la especificidad.

Diferencias Clave:
  • :is(a, b, c): Toma la especificidad del selector más específico de la lista.
  • :where(a, b, c): Siempre tiene especificidad 0.

¿Cuándo usar :where()? Es ideal para crear estilos base o "defaults" en librerías o resets CSS. Al tener especificidad 0, cualquier otro estilo que escribas después sobrescribirá fácilmente estos estilos sin necesidad de usar !important o selectores más complejos.

:where(h1, h2, h3) { color: green; } /* :where tiene especificidad 0. Fácil de sobrescribir. */
<!-- HTML del ejemplo --> <h1>Título 1</h1> <h2>Título 2</h2> <h3>Título 3</h3>

Título 1

Título 2

Título 3

7. Pseudo-elementos

Los pseudo-elementos permiten estilizar partes específicas de un elemento.

7.1 Contenido Generado (::before y ::after)

::before /* Inserta contenido antes */ ::after /* Inserta contenido después */
<!-- HTML del ejemplo --> <p class="con-before">Párrafo con ::before</p> <p class="con-after">Párrafo con ::after</p>

Párrafo con ::before (flecha al inicio)

Párrafo con ::after (check al final)

7.2 Estilización de Texto (::first-line y ::first-letter)

::first-line /* Primera línea */ ::first-letter /* Primera letra */
<!-- HTML del ejemplo --> <p>Este es un párrafo de ejemplo que demuestra el uso de pseudo-elementos...</p>

Este es un párrafo de ejemplo que demuestra el uso de pseudo-elementos. La primera línea aparece en negrita y con un color diferente. Además, la primera letra es mucho más grande y flota a la izquierda del texto, creando un efecto de letra capital.

7.3 Otros Pseudo-elementos

::selection /* Texto seleccionado */ ::marker /* Marcador de lista */ ::placeholder /* Placeholder de input */
<!-- HTML del ejemplo --> <p>Selecciona este texto para ver ::selection</p> <ul> <li>Item con ::marker personalizado</li> </ul> <input type="text" placeholder="Placeholder estilizado">

Selecciona este texto para ver ::selection

  • Item 1 con ::marker personalizado
  • Item 2 con ::marker personalizado

8. Especificidad y Prioridad

Cuando múltiples reglas CSS apuntan al mismo elemento, la especificidad determina cuál se aplica.

8.1 Cálculo de Especificidad

La especificidad se calcula como: (inline, IDs, clases/atributos/pseudo-clases, elementos/pseudo-elementos)

* 0,0,0,0
p 0,0,0,1
.clase 0,0,1,0
#id 0,1,0,0
div p 0,0,0,2
div.clase p 0,0,1,2
#id .clase p 0,1,1,1
style="..." 1,0,0,0

8.2 Buenas Prácticas

Recomendaciones:
  • Evita usar IDs para estilos (usa clases)
  • Evita !important (excepto en casos muy específicos)
  • Mantén la especificidad baja para facilitar el mantenimiento
  • Usa clases semánticas y reutilizables
  • Organiza tu CSS de menos a más específico

9. Tabla de Referencia Rápida

Categoría Selector Sintaxis Descripción
Básicos Universal * Todos los elementos
Elemento p Elementos de tipo específico
Clase .clase Elementos con class="clase"
ID #id Elemento con id="id"
Agrupación h1, h2 Múltiples selectores
Combinados Descendiente A B B dentro de A (cualquier nivel)
Hijo directo A > B B hijo directo de A
Hermano adyacente A + B B inmediatamente después de A
Hermanos generales A ~ B Todos los B después de A
Atributo Existe [attr] Tiene el atributo
Igual [attr="val"] Valor exacto
Contiene [attr*="val"] Contiene el valor
Estado Hover :hover Al pasar el ratón
Focus :focus Cuando tiene el foco
Checked :checked Input marcado
Disabled :disabled Input deshabilitado
Estructurales Primer hijo :first-child Primer elemento hijo
Último hijo :last-child Último elemento hijo
Enésimo hijo :nth-child(n) Enésimo elemento hijo
Primer tipo :first-of-type Primer elemento del tipo
Vacío :empty Elemento sin hijos
Avanzados Negación :not(selector) No coincide con selector
Coincidencia :is(s1, s2) Coincide con alguno
Has :has(sel) Si contiene selector
Where :where(sel) Coincidencia (esp. 0)
Pseudo-elementos Antes ::before Contenido antes del elemento
Después ::after Contenido después del elemento
Primera línea ::first-line Primera línea de texto
Primera letra ::first-letter Primera letra
Selección ::selection Texto seleccionado
Volver a CSS
Volver a CSS