Apuntes DAM
Volver al inicio

Ejercicios de HTML y CSS resueltos

Los 2 ejercicios de HTML y CSS de la web en una sola hoja: cada uno con su enunciado, los datos que necesitas (código de partida, ejemplos de entrada y salida o la base de datos) y, al final, la solución explicada.

Descargar el PDF

Ejercicios largos

1. Landing de una cafetería: Flexbox, Grid y diseño adaptable

Difícil · 90 minutos · apuntesdam.com/ejercicios/css/landing-de-una-cafeteria

Café Molino abre su web y el diseñador ya ha entregado el HTML de la página de inicio: una cabecera con el logo y el menú, una portada con el titular y el botón de reservas, y la carta con los platos. Falta todo el CSS, y el formulario de reservas lo hizo un becario sin pensar en la accesibilidad.

La mayoría de las visitas llegarán desde el móvil, así que el diseño se piensa primero para pantallas estrechas y se amplía con media queries (mobile first). Las pruebas de cada apartado comprueban la página a varios anchos, como lo haría un cliente al girar el móvil o abrirla en el ordenador.

Los apartados construyen la misma hoja de estilos poco a poco: cada uno empieza con lo hecho en el anterior y añade una parte nueva.

Requisitos

  • Cada apartado se corrige por separado con pruebas que se ejecutan dentro de la página (algunas a varios anchos de pantalla). Debajo del editor tienes el resultado en directo.

  • Los apartados de CSS empiezan con la solución del anterior ya escrita: así la página va creciendo. Puedes hacer los apartados en cualquier orden, pero conviene seguirlo.

  • Respeta los nombres de las clases del HTML y los valores que pide cada apartado (separaciones, colores, tamaños): las pruebas miden la página.

Página de partida (html)
<header class="cabecera">  <a class="logo" href="#">Café Molino</a>  <nav class="menu" aria-label="Principal">    <a href="#carta">Carta</a>    <a href="#local">El local</a>    <a href="#reservas">Reservas</a>  </nav></header><main>  <section class="hero">    <h1>Café de especialidad en el centro</h1>    <p>Tostamos nuestro propio grano cada semana.</p>    <a class="boton" href="#reservas">Reserva tu mesa</a>  </section>  <section id="carta" class="carta">    <article class="plato"><h2>Espresso</h2><p class="precio">1,80 €</p></article>    <article class="plato"><h2>Flat white</h2><p class="precio">2,90 €</p></article>    <article class="plato agotado"><h2>Cold brew</h2><p class="precio">3,20 €</p></article>    <article class="plato"><h2>Tarta de queso</h2><p class="precio">4,50 €</p></article>    <article class="plato"><h2>Croissant</h2><p class="precio">2,10 €</p></article>    <article class="plato agotado"><h2>Bizcocho de limón</h2><p class="precio">3,00 €</p></article>  </section></main>

Apartados

  • La cabecera: con Flexbox, el logo a la izquierda y el menú a la derecha en la misma línea, centrados en vertical, con 16px de relleno arriba y abajo y 24px a los lados; los enlaces del menú en fila con 24px de separación. En pantallas de menos de 600px, el menú pasa debajo del logo.

  • La carta (.carta): una rejilla con CSS Grid, 24px de relleno y 20px de separación entre platos; una columna en el móvil, dos columnas iguales a partir de 600px y tres a partir de 900px. Cada .plato con un borde de 1px, las esquinas redondeadas 8px y 16px de relleno.

  • Colores y tipografía: define en :root las variables --cafe: #6b3e26 y --crema: #fff8f0, usa --crema como fondo de la página y haz que el h1 crezca con la pantalla con clamp(1.75rem, 5vw, 3rem). El .boton es una píldora: inline-block, relleno de 12px arriba y abajo y 20px a los lados, esquinas de 999px, fondo --cafe, texto blanco y sin subrayado.

  • Los platos con la clase agotado se ven al 60 % de opacidad y llevan una etiqueta «Agotado» en la esquina superior derecha, hecha solo con CSS mediante ::after: posición absoluta a 8px del borde superior y del derecho (el plato tiene que ser su referencia), fondo #b00020 y texto blanco.

  • El formulario de reservas no es accesible: no tiene etiquetas, los tipos de campo no ayudan en el móvil y el botón es un div. Rehaz su HTML: cada campo con su <label for>; nombre y correo obligatorios con autocomplete (name y email) y el correo de tipo email; personas de tipo number entre 1 y 8; fecha de tipo date y obligatoria; el turno con dos radios (comida y cena, cada uno con su id y su label) dentro de un <fieldset> con la <legend> «Turno»; y un <button type="submit"> «Reservar». Conserva los id nombre, email, personas y fecha.

2. Página de un evento accesible: HTML semántico y ARIA

Medio · 60 minutos · apuntesdam.com/ejercicios/css/pagina-de-un-evento-accesible

El instituto organiza unas jornadas de software libre y alguien hizo la página a toda prisa con div y span. Se ve bien, pero una persona que navega con teclado o con un lector de pantalla no puede usarla: el menú no se puede enfocar, no hay encabezados para saltar de sección en sección, las imágenes no tienen texto alternativo y la tabla del programa es una cuadrícula sin sentido.

Las pautas WCAG 2.2 (nivel AA, el que exige la ley a las webs públicas) piden que todo funcione con teclado, que la estructura se pueda leer sin verla y que los controles anuncien su nombre y su estado. Casi todo se consigue con el elemento HTML adecuado; ARIA solo hace falta para lo que el HTML no tiene, como el estado abierto o cerrado de un menú.

Requisitos

  • Cada apartado se corrige por separado con pruebas que se ejecutan dentro de la página (algunas a varios anchos de pantalla). Debajo del editor tienes el resultado en directo.

  • Conserva las clases y los textos visibles de la página: las pruebas buscan los elementos por ellos.

Página de partida (html)
<div class="cabecera">  <img src="logo.svg" class="logo">  <div class="menu">    <span onclick="location='#programa'">Programa</span>    <span onclick="location='#entradas'">Entradas</span>  </div></div><div class="contenido">  <div class="titulo">Jornadas de Software Libre 2026</div>  <img src="cartel.jpg">  <img src="separador.png">  <div class="subtitulo">Programa</div>  <table>    <tr><td>Hora</td><td>Charla</td><td>Sala</td></tr>    <tr><td>10:00</td><td>Linux en el aula</td><td>A</td></tr>    <tr><td>11:30</td><td>Accesibilidad web</td><td>B</td></tr>  </table>  <a href="programa.pdf">Pincha aquí</a></div>

Apartados

  • Rehaz el HTML de la página: un enlace «Saltar al contenido» (clase saltar) como primer elemento, que lleve al main (con id principal); la cabecera en un header, el menú en un nav con aria-label="Principal" y sus opciones como enlaces (#programa y #entradas); el contenido en main; el título como h1 y «Programa» como h2 con id programa; el logo con el alt «Jornadas de Software Libre», el cartel con un alt que describa su información (fechas y lugar) y el separador, que es decorativo, con alt=""; la tabla con un caption y su primera fila con th scope="col"; y el enlace al PDF con un texto que diga qué es y que es un PDF (sin «aquí»).

  • En el móvil, el menú se despliega con un botón. El HTML ya es correcto (un button con aria-expanded y aria-controls, y el nav con hidden); escribe el JavaScript: al pulsar el botón, el menú se muestra u oculta (atributo hidden) y aria-expanded pasa a "true" o "false"; con el menú abierto, la tecla Escape lo cierra y devuelve el foco al botón.