Maquetación Web Dinámica / Pseudo-clases y pseudo-elementos: el arsenal secreto
Reto: checklist interactivo sin una línea de JS
El cierre del módulo es una demostración de poder: una lista de tareas interactiva — ítems que se tachan, contador de progreso, estado de "completado" con celebración — construida SOLO con HTML y CSS. Hace tres años esto requería JavaScript; hoy es :checked + :has() bien combinados.
Reto
Checklist interactivo: cero JavaScript
Qué debes construir
Una lista de preparación de viaje (o el tema que quieras) con esta conducta:
<section class="checklist">
<h3>Antes del viaje</h3>
<label class="item"><input type="checkbox"><span>Pasaporte vigente</span></label>
<label class="item"><input type="checkbox"><span>Reservar hotel</span></label>
<label class="item"><input type="checkbox"><span>Empacar maleta</span></label>
<label class="item"><input type="checkbox"><span>Cargar el celular</span></label>
<p class="celebracion">¡Todo listo! Buen viaje ✈</p>
</section>body { font-family: system-ui; padding: 20px; background: #f8fafc; }
.checklist { background: white; border: 1px solid #e2e8f0; border-radius: 14px; padding: 20px; max-width: 320px; }
.checklist h3 { margin: 0 0 12px; color: #1e293b; font-size: 16px; }
.item { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 8px; cursor: pointer; font-size: 14px; color: #334155; }
.item:hover { background: #f1f5f9; }
.item:has(:checked) { background: #f5f3ff; }
.item:has(:checked) span { text-decoration: line-through; color: #94a3b8; }
.item input { accent-color: #6d28d9; width: 16px; height: 16px; }
.item:has(:focus-visible) { outline: 2px solid #a78bfa; outline-offset: 1px; }
.celebracion { display: none; margin: 12px 0 0; font-weight: 700; color: #15803d; font-size: 14px; text-align: center; }
.checklist:not(:has(input:not(:checked))) .celebracion { display: block; }
.checklist:not(:has(:checked)) h3::after { content: " — 0 de 4"; color: #94a3b8; font-weight: 400; font-size: 13px; }Requisitos:
- 4+ ítems, cada uno un
labelque envuelve su checkbox y su texto (el clic en TODO el ítem marca/desmarca — módulo 2, la pareja inseparable). - Ítem marcado: texto tachado y atenuado, fondo sutil del acento — vía
:has(:checked)en el label. - El checkbox con
accent-colorde la casa (¡una línea — investígala, es nueva para ti!). - Foco visible: el ÍTEM entero se resalta cuando su checkbox recibe foco
de teclado (
:has(:focus-visible)). - El gran final: cuando TODOS están marcados, aparece un mensaje de celebración — la sección entera reacciona al estado de todos sus hijos.
- Bonus: contador "N de 4" junto al título usando contadores CSS... o la honestidad de descubrir su límite (lee la Solución al terminar).
Reglas
- Cero JavaScript. Ni una línea. Todo es HTML semántico + CSS.
- Debe funcionar con teclado: Tab entre ítems, Espacio para marcar, foco siempre visible.
- Nada de ocultar los checkboxes nativos con opacity 0 y redibujarlos — esta vez estilízalos de verdad (accent-color) y que la accesibilidad quede intacta gratis.
40:00
Cuando estés listo, arranca el reloj.
Qué sigue
Módulo 9 cerrado: seleccionas por estado, posición, contenido y parentesco, decoras y dibujas con fantasmas — el arsenal secreto completo. El módulo 10 enciende el MOVIMIENTO: transformaciones y transiciones, la puerta de entrada a la animación profesional.