Saltar al contenido

📚 Entrena HTML + CSS (+ un toque de JS) – 5 nuevos ejercicios con su solución incluida

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

  1. 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.
  2. 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.
  3. Valida con el servicio del W3C y depura los avisos.
  4. Integra los cinco archivos en un repositorio Git; así tendrás una “chuleta” online que puedes consultar desde cualquier sitio.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Información básica sobre protección de datos Ver más

  • Responsable: Tomas Gonzalez.
  • Finalidad:  Moderar los comentarios.
  • Legitimación:  Por consentimiento del interesado.
  • Destinatarios y encargados de tratamiento:  No se ceden o comunican datos a terceros para prestar este servicio.
  • Derechos: Acceder, rectificar y suprimir los datos.
  • Información Adicional: Puede consultar la información detallada en la Política de Privacidad.

¿Atascado con tu proyecto? Presupuesto GRATIS

X
error: Content is protected !!
Este sitio web utiliza cookies, si necesitas más información puedes visitar nuestra política de privacidad    Ver
Privacidad