Curso de CSS
Todos los cursos

Ejercicio: Proyecto: landing page responsiva

  • ⏱ 90 minutos
  • 📶 Nivel: principiante

Objetivo

Dar estilo completo a una landing page: cabecera pegajosa, hero con degradado, tarjetas con Grid, galería adaptable, formulario, modo oscuro y animaciones accesibles. El comprobador valida el resultado móvil real y que escribiste las reglas de escritorio.

La página de partida

Este es el HTML de la landing (semántico y accesible). No lo modifiques: tu trabajo es todo el CSS.

pagina.html
<a class="saltar" href="#principal">Saltar al contenido</a>
<header class="cabecera">
  <a class="marca" href="#">Café Aurora</a>
  <nav class="menu" aria-label="Principal">
    <a href="#carta">Carta</a>
    <a href="#galeria">Galería</a>
    <a href="#contacto">Contacto</a>
  </nav>
</header>
<main id="principal">
  <section class="hero">
    <h1 class="hero__titulo">El mejor café de la ciudad, recién tostado</h1>
    <p class="hero__texto">Granos de origen, tostado artesanal y un rincón tranquilo para trabajar o conversar.</p>
    <a class="boton" href="#contacto">Reservar una mesa</a>
  </section>
  <section class="ventajas" id="carta">
    <article class="ventaja"><h2>Origen único</h2><p>Trabajamos con pequeños productores.</p></article>
    <article class="ventaja"><h2>Tostado diario</h2><p>Cada mañana, en nuestro propio taller.</p></article>
    <article class="ventaja"><h2>Para llevar</h2><p>Bolsas de 250 g o 1 kg, molidas a tu gusto.</p></article>
  </section>
  <section class="galeria" id="galeria" aria-label="Galería">
    <div class="foto">1</div><div class="foto">2</div><div class="foto">3</div>
    <div class="foto">4</div><div class="foto">5</div><div class="foto">6</div>
  </section>
  <section class="contacto" id="contacto">
    <h2>Escríbenos</h2>
    <form class="form">
      <label for="correo">Tu correo</label>
      <input id="correo" type="email" placeholder="tu@correo.com">
      <button class="boton" type="submit">Enviar</button>
    </form>
  </section>
</main>
<footer class="pie"><p>© 2026 Café Aurora</p><p>Calle del Sol 12</p></footer>
✏️ Prueba tu CSS aquí (opcional)

Pasos

Marca cada paso a medida que lo completes. Tu avance se guarda en este navegador.

💡 Pista 1: ¿cómo oculto el enlace para saltar?

.saltar { position: absolute; left: -999px; } y .saltar:focus { left: 8px; top: 8px; }. Así queda fuera de la pantalla hasta recibir el foco con Tab.

💡 Pista 2: el comprobador prueba a 400px

Eso significa que debes ver el diseño móvil: una columna, sin desplazamiento horizontal. Las medidas de escritorio se comprueban leyendo que escribiste las media queries.

🔎 Comprueba tu trabajo

Pega tu código y pulsa Comprobar. La revisión ocurre en tu navegador; nada se envía a ningún sitio. Cada punto en rojo incluye una pista.

    ✅ Ver una solución completa de ejemplo

    Intenta resolverlo antes de mirar. Tu versión puede ser distinta y también correcta.

    estilos.css
    :root {
      --fondo: #fffaf5;
      --superficie: #ffffff;
      --texto: #2b1d14;
      --acento: #b45309;
      --borde: #ecdccc;
      --radio: 14px;
      --sombra: 0 1px 2px rgb(0 0 0 / .06), 0 10px 28px rgb(43 29 20 / .12);
    }
    :root[data-tema="oscuro"] {
      --fondo: #17110d;
      --superficie: #231a14;
      --texto: #f5ebe0;
      --acento: #f59e0b;
      --borde: #3a2c22;
      color-scheme: dark;
    }
    
    *, *::before, *::after { box-sizing: border-box; }
    body { margin: 0; background: var(--fondo); color: var(--texto); font: 1.0625rem/1.65 system-ui, sans-serif; }
    img, svg { max-width: 100%; height: auto; }
    
    :focus-visible { outline: 3px solid var(--acento); outline-offset: 3px; }
    .saltar { position: absolute; left: -999px; top: 0; padding: .6rem 1rem; background: var(--acento); color: #fff; z-index: 100; }
    .saltar:focus { left: 8px; top: 8px; }
    
    .cabecera {
      position: sticky; top: 0; z-index: 10;
      display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: .5rem;
      padding: .75rem 1rem;
      background: var(--superficie);
      border-bottom: 1px solid var(--borde);
    }
    .marca { font-weight: 800; color: var(--acento); text-decoration: none; }
    .menu { display: flex; gap: 1rem; }
    .menu a { color: var(--texto); text-decoration: none; }
    
    .hero {
      min-height: 60vh;
      display: grid; place-content: center; gap: 1rem; text-align: center;
      padding: 3rem 1rem;
      background: linear-gradient(rgb(0 0 0 / .45), rgb(0 0 0 / .45)), linear-gradient(135deg, #b45309, #7c2d12);
      color: #fff;
    }
    .hero__titulo { margin: 0; font-size: clamp(1.8rem, 1rem + 5vw, 3.5rem); line-height: 1.1; text-wrap: balance; }
    
    .boton {
      display: inline-block; justify-self: center;
      padding: .75rem 1.5rem; border: 0; border-radius: var(--radio);
      background: var(--acento); color: #fff; font: inherit; font-weight: 700; text-decoration: none; cursor: pointer;
      transition: transform .2s, box-shadow .2s;
    }
    .boton:hover { transform: translateY(-2px); box-shadow: var(--sombra); }
    
    .ventajas { display: grid; gap: 1rem; padding: 2rem 1rem; }
    .ventaja {
      background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--radio); padding: 1.25rem;
      transition: transform .25s, box-shadow .25s;
    }
    .ventaja:hover { transform: translateY(-4px); box-shadow: var(--sombra); }
    .ventaja h2 { margin-top: 0; }
    
    .galeria { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .75rem; padding: 0 1rem 2rem; }
    .foto {
      aspect-ratio: 1; display: grid; place-items: center; border-radius: var(--radio); color: #fff; font-weight: 700;
      background: linear-gradient(135deg, var(--acento), #7c2d12);
    }
    
    .contacto { padding: 2rem 1rem; max-width: 36rem; margin-inline: auto; }
    .form { display: grid; gap: .75rem; }
    .form input { padding: .7rem; border: 1px solid var(--borde); border-radius: 10px; font: inherit; background: var(--superficie); color: var(--texto); }
    
    .pie { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .5rem; padding: 1.5rem 1rem; border-top: 1px solid var(--borde); }
    
    @media (min-width: 700px) {
      .ventajas { grid-template-columns: repeat(3, 1fr); padding-inline: 2rem; }
      .cabecera { padding-inline: 2rem; }
    }
    
    @media (prefers-color-scheme: dark) {
      :root:not([data-tema="claro"]) {
        --fondo: #17110d; --superficie: #231a14; --texto: #f5ebe0; --acento: #f59e0b; --borde: #3a2c22;
        color-scheme: dark;
      }
    }
    
    @media (prefers-reduced-motion: reduce) {
      * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
    }

    💡 🏁 Reto extra (opcional)

    Rediseña la landing con otra paleta (por ejemplo, verde y crema) cambiando solo las variables de :root. Si todo está bien hecho, no necesitas tocar nada más.