Cada ejercicio aparece seguido del archivo resuelto – no necesitas buscarlos aparte.
Valídalos en https://validator.w3.org y comprueba que no surjan errores.
1. Menú hamburguesa responsive
Objetivo: Flexbox, media queries y un pequeño script para mostrar/ocultar el menú en pantallas estrechas.
menu.html
(ejercicio + solución)
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Menú responsive</title>
<style>
*{box-sizing:border-box} body{margin:0;font-family:system-ui}
header{background:#222;color:#fff;padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between}
nav ul{list-style:none;margin:0;padding:0;display:flex;gap:1rem}
nav a{color:#fff;text-decoration:none}
button#burger{display:none;background:none;border:none;font-size:1.6rem;color:#fff;cursor:pointer}
@media (max-width:680px){
nav ul{flex-direction:column;display:none;background:#222;padding:1rem}
button#burger{display:block}
nav.open ul{display:flex}
}
</style>
</head>
<body>
<header>
<h1>Logo</h1>
<button id="burger" aria-label="Mostrar menú">☰</button>
<nav>
<ul>
<li><a href="#">Inicio</a></li>
<li><a href="#">Servicios</a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">Contacto</a></li>
</ul>
</nav>
</header>
<script>
const burger = document.getElementById('burger');
const nav = document.querySelector('nav');
burger.addEventListener('click',()=>nav.classList.toggle('open'));
</script>
</body>
</html>
2. Tarifa de precios con selector de plan
Objetivo: usar radio buttons ocultos y la pseudoclase :has()
(ya soportada por los navegadores modernos) para resaltar la tarjeta seleccionada sin JavaScript.
precios.html
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Planes de precios</title>
<style>
:root{--prim:#4f46e5}
body{font-family:system-ui;margin:2rem;display:flex;gap:1rem;flex-wrap:wrap}
.plan{border:2px solid #ccc;border-radius:8px;padding:1rem;width:200px;position:relative;transition:border .3s}
.plan h2{margin:.4rem 0}.plan p{margin:0 0 .6rem}.plan strong{font-size:1.8rem}
input[type=radio]{position:absolute;inset:0;opacity:0;cursor:pointer}
/* Plan activo */
.plan:has(input[type=radio]:checked){border-color:var(--prim)}
</style>
</head>
<body>
<h1>Elige tu plan</h1>
<label class="plan">
<input type="radio" name="plan" checked>
<h2>Básico</h2>
<strong>0 €</strong>
<p>5 proyectos<br>Soporte email</p>
</label>
<label class="plan">
<input type="radio" name="plan">
<h2>Pro</h2>
<strong>12 €</strong>
<p>25 proyectos<br>Soporte chat</p>
</label>
<label class="plan">
<input type="radio" name="plan">
<h2>Empresas</h2>
<strong>29 €</strong>
<p>Proyectos ilimitados<br>Soporte 24/7</p>
</label>
</body>
</html>
3. FAQ accesible con <details>
/ <summary>
y contador
Objetivo: practicar elementos interactivos nativos y un contador con CSS Counters.
faq.html
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>FAQ</title>
<style>
body{font-family:system-ui;max-width:700px;margin:2rem auto;counter-reset:faq}
details{border:1px solid #ddd;border-radius:6px;padding:.8rem;margin-bottom:1rem}
summary{cursor:pointer;font-weight:600;list-style:none}
summary::before{counter-increment:faq;content:"P" counter(faq) ": ";color:#4f46e5}
details[open]{background:#fafafa}
</style>
</head>
<body>
<h1>Preguntas frecuentes</h1>
<details>
<summary>¿Cómo creo una cuenta?</summary>
<p>Pulsa en “Registrarse”, introduce tu correo y confirma el email.</p>
</details>
<details>
<summary>¿Puedo cambiar de plan más tarde?</summary>
<p>Sí, desde tu zona de usuario – la facturación se prorratea automáticamente.</p>
</details>
<details>
<summary>¿Hay periodo de prueba?</summary>
<p>Ofrecemos 14 días gratuitos sin tarjeta de crédito.</p>
</details>
</body>
</html>
4. Formulario multi‑paso sin JavaScript
Objetivo: dividir un formulario en dos “pantallas” usando solo :target
y hidden
para controlar la visibilidad.
multi.html
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Formulario multi‑paso</title>
<style>
body{font-family:system-ui;margin:2rem}
section{max-width:400px}
[data-step]{display:none}
:target{display:block}
#paso1:not(:target),#paso2:target ~ #paso1{display:block}
#paso2:target{display:block}
nav{margin-top:1rem}
</style>
</head>
<body>
<h1>Alta de usuario</h1>
<section>
<form>
<!-- Paso 1 -->
<div id="paso1" data-step>
<label>Nombre
<input type="text" required>
</label><br>
<label>Email
<input type="email" required>
</label><br>
<nav><a href="#paso2">Siguiente ➔</a></nav>
</div>
<!-- Paso 2 -->
<div id="paso2" data-step>
<label>Contraseña
<input type="password" required minlength="6">
</label><br>
<label>País
<select required>
<option>España</option><option>México</option><option>Argentina</option>
</select>
</label><br>
<nav>
<a href="#paso1">◀ Atrás</a>
<button>Enviar</button>
</nav>
</div>
</form>
</section>
</body>
</html>
5. Tarjeta “flip” 3D con CSS
Objetivo: practicar transformaciones 3D, perspectiva y hover/focus accesible.
flip.html
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Tarjeta flip</title>
<style>
body{display:flex;justify-content:center;align-items:center;min-height:100vh;font-family:system-ui;background:#f0f4ff;margin:0}
.scene{width:260px;height:160px;perspective:800px}
.card{width:100
.scene:hover .card,.scene:focus-within .card{transform:rotateY(180deg)}
.face{position:absolute;inset:0;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:1.3rem;color:#fff;backface-visibility:hidden}
.front{background:#4f46e5}
.back{background:#059669;transform:rotateY(180deg);padding:1rem;text-align:center}
a.btn{display:inline-block;margin-top:1rem;padding:.4rem .8rem;border:1px solid #fff;border-radius:4px;color:#fff;text-decoration:none}
</style>
</head>
<body>
<div class="scene" tabindex="0">
<div class="card">
<div class="face front">Hover o Tab</div>
<div class="face back">
<p>Contenido<br>secreto</p>
<a href="#" class="btn">Leer más</a>
</div>
</div>
</div>
</body>
</html>
✔️ Cómo sacarles partido
- Lee la parte de instrucciones de cada ejercicio y luego examina el código resuelto: detecta qué etiquetas, propiedades o selectores podrías reutilizar en tu examen.
- Juega: cambia textos, colores o añade campos al formulario; observa cómo reacciona el CSS y si siguen valiendo los combos
:has()
,:target
, etc. - Valida con el servicio del W3C y depura los avisos.
- Integra los cinco archivos en un repositorio Git; así tendrás una “chuleta” online que puedes consultar desde cualquier sitio.
