Curso de HTML y CSS desde cero, en español

HTML y CSS son los dos lenguajes con los que se hace cualquier página web. HTML dice qué es cada cosa (esto es un título, esto un párrafo, esto un enlace) y CSS dice cómo se ve (de qué color, de qué tamaño, dónde va). No hace falta saber programar ni instalar nada raro: con un editor de texto y el navegador que ya tienes puedes empezar ahora. Este curso parte de cero y llega hasta una página completa que se adapta al celular, y cada ejemplo trae su resultado en vivo justo debajo para que veas lo que hace el código.

La ruta: ocho lecciones

Están pensadas para leerse en orden. Las dos primeras están en esta misma página y las demás tienen la suya. Cada lección tiene un recuadro «El error típico» con un tropiezo frecuente al empezar, retos al final y, bajo los ejemplos, un enlace para abrirlos en el editor y cambiarlos. Al final hay un test de 24 preguntas en el que tienes que adivinar qué se ve.

Lección 1. Tu primera página

Una página web es un archivo de texto con la extensión .html. El navegador lo lee de arriba abajo y lo dibuja en la pantalla. Además del HTML, casi todas las páginas usan otros dos lenguajes, y conviene saber desde el principio qué hace cada uno:

HTML dice qué es cada cosa, CSS cómo se ve y JavaScript qué hace; el curso trata de HTML y CSSTres lenguajes, tres trabajosHTMLqué es cada cosa<h1>Mi blog</h1>CSScómo se veh1 { color: navy; }JavaScriptqué haceboton.onclick = …Este curso es de los dos primeros.
HTML da la estructura, CSS la apariencia y JavaScript el comportamiento. Esquema: decodigo.com.

Este curso trata de los dos primeros. JavaScript tiene su propio curso de JavaScript, que conviene empezar cuando ya te muevas bien con HTML y CSS.

Etiquetas y elementos

HTML marca el texto con etiquetas: palabras entre los signos < y >. Casi todas van en pareja, una que abre y otra que cierra, con una barra: <p> abre un párrafo y </p> lo cierra. Lo que queda entre las dos es el contenido, y el conjunto se llama elemento. Algunas etiquetas llevan además atributos: datos extra con la forma nombre="valor" dentro de la etiqueta de apertura.

Partes del elemento <a href="/blog">Blog</a>: la etiqueta de apertura con el atributo href, el contenido Blog y la etiqueta de cierreLas partes de un elemento<a href="/blog">Blog</a>aperturacontenidocierreatributo: nombre=“valor”todo junto: el elemento a (un enlace)
Un enlace: el atributo href dice a dónde lleva y el contenido es el texto que se ve. Esquema: decodigo.com.
<h1>Recetas de la abuela</h1>
<p>Un párrafo con una palabra <strong>importante</strong>.</p>
<p>Otro párrafo con un <a href="/blog">enlace al blog</a>.</p>

Fíjate en tres cosas del resultado: el título h1 sale grande y en negritas sin que nadie se lo haya pedido, cada párrafo empieza en su propia línea y la palabra dentro de strong sale en negritas. Son los estilos por omisión del navegador; con CSS los cambiarás todos.

Unos pocos elementos no tienen contenido ni etiqueta de cierre: se llaman elementos vacíos. Los más comunes son <img> (una imagen), <br> (un salto de línea), <hr> (una línea de separación), <meta>, <link> e <input>. Verás que en algunos sitios se escriben como <br />, con la barra al final: es una costumbre heredada de XHTML, y en HTML da igual ponerla o no.

Los elementos se meten unos dentro de otros

Un elemento puede contener otros: un párrafo que contiene un enlace, una lista que contiene sus puntos. La regla es que se cierran en el orden contrario al que se abrieron, como unas cajas que se meten una dentro de otra: la última que abriste es la primera que cierras.

El error típico: cerrar las etiquetas en desorden

<p>Esto es <strong>muy importante</p></strong>

El navegador no se queja: intenta adivinar lo que querías y casi siempre lo consigue, así que el error pasa desapercibido hasta que la página se ve rara. El validador del W3C sí lo detecta:

Nu Html Checker (validador del W3C)línea 1: error: End tag “p” seen, but there were open elements.
línea 1: error: Unclosed element “strong”.
línea 1: error: No “strong” element in scope but a “strong” end tag seen.

Lo correcto es cerrar primero el strong, que se abrió después: <p>Esto es <strong>muy importante</strong></p>. Puedes revisar cualquier página en validator.w3.org pegando su código.

El esqueleto de una página

Los ejemplos de arriba son fragmentos. Una página completa tiene siempre la misma estructura, y la puedes copiar tal cual para empezar cualquier proyecto:

<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Mi primera página</title>
</head>
<body>
  <h1>Hola, mundo</h1>
  <p>Esta es mi primera página web.</p>
</body>
</html>

Línea por línea:

  • <!doctype html> le dice al navegador que es una página moderna. Sin esta línea entra en el «modo de compatibilidad» (quirks mode), que imita los errores de los navegadores de los noventa y hace que algunos estilos no se comporten como esperas.
  • <html lang="es"> envuelve todo y dice el idioma. Lo usan los lectores de pantalla para pronunciar bien y los traductores automáticos para saber de qué idioma partir.
  • <head> lleva datos sobre la página, que no se ven en ella: la codificación (utf-8, para que salgan bien la ñ y los acentos), el ajuste para celulares (viewport, lo verás en la lección 8) y el título que aparece en la pestaña y en los resultados de Google.
  • <body> lleva todo lo que se ve.

El navegador convierte ese texto en un árbol de elementos, el DOM (Document Object Model). Es lo que verás en las herramientas del navegador, y es también lo que CSS recorre para decidir a qué aplica cada regla.

Árbol del documento: html contiene head y body; head contiene meta y title; body contiene h1 y p, y p contiene un enlace aEl documento es un árbolhtmlheadbodymetatitleh1pahead: datos de la páginabody: lo que se ve
El árbol de un documento sencillo: cada elemento es hijo del que lo contiene. Esquema: decodigo.com.

Crear el archivo y abrirlo

  1. Abre un editor de texto. Sirve el Bloc de notas de Windows o TextEdit en la Mac (en modo «texto sin formato»), pero es mucho más cómodo uno para programar: Visual Studio Code es gratuito y el más usado.
  2. Pega el esqueleto de arriba y guárdalo como index.html, con codificación UTF-8 (es la opción por omisión en casi todos).
  3. Haz doble clic en el archivo: se abre en tu navegador. Cada vez que cambies algo, guarda y recarga la pestaña (F5 o Ctrl+R; en la Mac, Cmd+R).

El error típico: el archivo se llama index.html.txt

Windows oculta por omisión la extensión de los archivos. Si guardas desde el Bloc de notas sin cambiar el tipo, el archivo se llama en realidad index.html.txt y, al abrirlo, el navegador enseña el código en vez de la página. En el cuadro de «Guardar como» elige «Todos los archivos» en el tipo, o activa en el Explorador la opción Vista → Extensiones de nombre de archivo para verlo.

Si no quieres crear archivos todavía, todos los ejemplos de este curso se pueden abrir y cambiar en el editor de HTML y CSS de decodigo.com.

Las herramientas del navegador

Todos los navegadores traen unas herramientas para desarrolladores. Pulsa F12 (en la Mac, Cmd+Option+I; en Safari, primero hay que activarlas en Ajustes → Avanzado) o haz clic derecho sobre cualquier parte de una página y elige Inspeccionar. Verás el árbol de elementos a un lado y, al elegir uno, todas las reglas de CSS que se le aplican, de dónde viene cada una y cuáles quedaron tachadas porque otra ganó. Puedes cambiar cualquier valor ahí mismo y ver el efecto al instante (los cambios se pierden al recargar). Es la herramienta que más vas a usar.

Tu primer CSS

CSS se escribe como una lista de reglas. Cada regla tiene un selector (a qué elementos se aplica) y, entre llaves, una o varias declaraciones con la forma propiedad: valor;. Para empezar, lo más sencillo es ponerlo dentro de una etiqueta <style> en el head:

<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Mi primera página</title>
  <style>
    body {
      font-family: system-ui, sans-serif;
      max-width: 36rem;
      margin: 2rem auto;
      padding: 0 1rem;
    }
    h1 {
      color: #1e64af;
    }
  </style>
</head>
<body>
  <h1>Hola, mundo</h1>
  <p>Esta es mi primera página web, ahora con estilo.</p>
</body>
</html>

La regla de body cambia la letra, limita el ancho del texto a 36 rem (576 píxeles, porque 1 rem es el tamaño de letra base, 16 píxeles, en todos los navegadores) y lo centra con margin: 2rem auto. La de h1 pinta el título de azul. En la lección 6 verás cada una de estas propiedades con calma.

En cuanto la página tenga más de una página, conviene sacar el CSS a un archivo aparte, por ejemplo estilos.css, y enlazarlo desde el head de todas. Así cambias el diseño de todo el sitio en un solo lugar:

<link rel="stylesheet" href="estilos.css">

Existe una tercera forma, el atributo style en un elemento (<p style="color: red">). Úsala solo para pruebas rápidas: mezcla el diseño con el contenido y, como verás en la lección 5, le gana a casi cualquier otra regla, lo que la vuelve difícil de cambiar después.

Retos de la lección 1

Reto 1. Escribe una página completa, con su esqueleto, cuyo título de pestaña sea «Sobre mí» y que tenga un h1 con tu nombre y un párrafo que diga de dónde eres.

Ver la solución
<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Sobre mí</title>
</head>
<body>
  <h1>Ana López</h1>
  <p>Soy de Guadalajara, Jalisco.</p>
</body>
</html>

Reto 2. Encuentra los dos errores de este fragmento: <p>Hola <em>mundo</p> seguido de <p>Adiós<p>. Pista: uno es de orden y el otro de cierre.

Ver la solución

El em no se cierra antes que el párrafo, y el segundo párrafo usa <p> donde iba </p>. Lo correcto:

<p>Hola <em>mundo</em></p>
<p>Adiós</p>

Reto 3. A la página del reto 1 ponle un fondo gris muy claro (#f5f8fb) y el texto del párrafo en gris oscuro (#33475b). Necesitas dos reglas: una para body con la propiedad background y otra para p con color.

Ver la solución
<h1>Ana López</h1>
<p>Soy de Guadalajara, Jalisco.</p>
body {
  background: #f5f8fb;
}

p {
  color: #33475b;
}

Lección 2. Texto, enlaces e imágenes

Con lo de la lección 1 ya puedes escribir una página. Ahora toca llenarla: títulos, párrafos, listas, enlaces e imágenes son el 90 % del HTML de cualquier sitio.

Títulos y párrafos

Hay seis niveles de título, de <h1> a <h6>. No son tamaños de letra, son niveles de un índice: el h1 es el título de la página (uno solo), los h2 son sus secciones, los h3 las subsecciones de cada h2, y así. Google y los lectores de pantalla los usan para entender cómo está organizado el texto; muchas personas ciegas navegan una página saltando de título en título. Si quieres un título más chico, cámbialo con CSS, no bajando de nivel.

<h1>Guía de Oaxaca</h1>
<h2>Qué comer</h2>
<p>Tlayudas, mole negro y chapulines.</p>
<h3>Dónde comprar mezcal</h3>
<p>En los palenques de Santiago Matatlán.</p>
<h2>Qué visitar</h2>
<p>Monte Albán y Hierve el Agua.</p>

Sin CSS, el navegador da a cada nivel su tamaño: medido en Chrome, Firefox y Safari, el h1 sale a 32 píxeles, el h2 a 24, el h3 a 18.72 y el texto normal a 16.

HTML no respeta los saltos de línea ni los espacios seguidos que escribas: todos los espacios, tabuladores y saltos se juntan en un solo espacio. Por eso cada párrafo va en su propio <p>, y por eso puedes sangrar el código como quieras sin que cambie el resultado.

<p>Estas    palabras
    están      muy
separadas    en el código.</p>
<p>Y esta línea<br>se parte con br.</p>

Usa <br> solo cuando el salto forma parte del contenido, como en una dirección postal o un poema. Para separar bloques, usa párrafos y deja el espacio entre ellos al CSS.

Resaltar texto

Dentro de un párrafo puedes marcar palabras sueltas. Cada etiqueta dice por qué se resalta, no solo cómo se ve:

  • <strong>importancia: algo que el lector no debe pasar por alto. Sale en negritas.
  • <em>énfasis, el que harías con la voz al leer en voz alta. Sale en cursivas.
  • <mark>texto marcado, como con un resaltador, por ejemplo lo que coincide con una búsqueda.
  • <code>un fragmento de código. Sale en letra monoespaciada.
  • <small>letra chica: avisos legales, aclaraciones.
  • <b> e <i>negritas y cursivas sin significado especial: un nombre de producto, una palabra en otro idioma.
<p><strong>Atención:</strong> la tienda cierra el <em>domingo</em>.</p>
<p>Escribe <code>git status</code> para ver los cambios.</p>
<p>Resultados para «mole»: Receta de <mark>mole</mark> poblano.</p>

Listas

Hay dos tipos de lista: <ul> (unordered list), con viñetas, cuando el orden no importa, y <ol> (ordered list), numerada, cuando sí importa, como en los pasos de una receta. Cada punto va en un <li>, y una lista puede contener otra dentro de un punto:

<h2>Ingredientes</h2>
<ul>
  <li>2 tazas de harina</li>
  <li>1 huevo</li>
  <li>Especias:
    <ul>
      <li>canela</li>
      <li>clavo</li>
    </ul>
  </li>
</ul>

<h2>Pasos</h2>
<ol>
  <li>Mezcla la harina con el huevo.</li>
  <li>Añade las especias.</li>
  <li>Hornea 20 minutos.</li>
</ol>

La lista de dentro va dentro del <li> de «Especias», antes de su </li>. Un <ul> solo puede tener hijos <li>; ponerlo suelto entre dos puntos es un error que el validador marca.

Enlaces

El elemento <a> (de anchor, «ancla») convierte su contenido en un enlace. El atributo href dice a dónde lleva, y puede ser de varias clases:

  • Absolutohttps://es.wikipedia.org/wiki/HTML: la dirección completa, para ir a otro sitio.
  • Relativocontacto.html o blog/articulo.html: un archivo de tu sitio, contado desde la página actual.
  • Desde la raíz/blog: empieza por la barra, se cuenta desde el principio del dominio, esté donde esté la página.
  • A una sección#precios: salta al elemento con id="precios" de la misma página.
  • Correo y teléfonomailto:hola@ejemplo.mx abre el correo; tel:+525512345678 marca en el celular.
<p><a href="https://es.wikipedia.org/wiki/HTML">HTML en Wikipedia</a></p>
<p><a href="#precios">Ir a los precios</a></p>
<p><a href="mailto:hola@ejemplo.mx">Escríbenos</a></p>

<h2 id="precios">Precios</h2>
<p>Desde $99.00 MXN al mes.</p>

En el resultado en vivo los enlaces a otros sitios no navegan: el marco te dice a dónde llevarían. El de «Ir a los precios» sí funciona, porque salta dentro de la misma página.

Las rutas relativas son las que más confunden al principio. Se cuentan desde la carpeta del archivo en el que está el enlace, y ../ significa «sube una carpeta»:

Carpeta mi-sitio con index.html, blog/articulo.html e img/foto.jpg. Desde articulo.html la foto es ../img/foto.jpg; desde index.html es img/foto.jpgRutas relativas: desde dóndemi-sitio/index.htmlblog/articulo.htmlimg/foto.jpgEn articulo.html:../img/foto.jpg../ sube a mi-sitio/y de ahí entra a img/En index.html la misma foto esimg/foto.jpg
La misma foto se escribe distinto según la página desde la que la enlaces. Esquema: decodigo.com.

Para abrir un enlace en otra pestaña se añade target="_blank". Úsalo con moderación: quien lee puede decidir eso por su cuenta (con la rueda del ratón o manteniendo pulsado), y abrir pestañas sin avisar desorienta, sobre todo a quien usa un lector de pantalla.

Imágenes

La etiqueta <img> es un elemento vacío con dos atributos obligatorios en la práctica: src, la dirección de la imagen, y alt, un texto que la sustituye cuando no se puede ver. Conviene añadir también width y height con su tamaño real en píxeles: así el navegador le reserva el hueco antes de descargarla y el texto no da un salto cuando por fin aparece.

<img src="https://decodigo.com/wp-content/uploads/2026/10/decodigo_placa_raspberry-pi-5.jpg"
     alt="Placa Raspberry Pi 5 vista desde arriba"
     width="640" height="420">
<p>El texto de abajo no se mueve cuando carga la foto.</p>
img {
  max-width: 100%;
  height: auto;
}

La regla de CSS max-width: 100% con height: auto hace que la imagen se encoja en pantallas angostas sin deformarse. La vas a usar en todos tus proyectos.

Cómo escribir el alt:

  • Describe lo que aporta la imagen en ese contexto, no «imagen de…»: el lector de pantalla ya anuncia que es una imagen.
  • Si la imagen es un enlace o un botón, el alt dice a dónde lleva o qué hace: alt="Inicio" en el logotipo.
  • Si es decorativa y no aporta nada, déjalo vacío, alt="", pero ponlo: sin el atributo, algunos lectores leen en voz alta el nombre del archivo.

El error típico: la imagen no aparece

<img src="Fotos/Playa.JPG">
Nu Html Checker (validador del W3C)línea 1: error: An “img” element must have an “alt” attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images.

Aquí hay dos problemas. El validador marca el primero: falta el alt. El segundo no lo ve nadie hasta subir la página: en tu computadora con Windows o Mac, Fotos/Playa.JPG y fotos/playa.jpg son el mismo archivo, pero casi todos los servidores web usan Linux, que distingue mayúsculas de minúsculas. Funciona en tu equipo y sale rota en internet. La costumbre más segura: nombres de archivo en minúsculas, sin espacios ni acentos (fotos/playa-cancun.jpg).

Para una imagen con pie de foto, envuélvela en <figure> con un <figcaption>. Y para elegir el formato: JPEG o WebP para fotos, PNG o WebP para capturas e imágenes con transparencia, SVG para logotipos e iconos (es un dibujo vectorial: se ve nítido a cualquier tamaño). AVIF comprime todavía más que WebP y ya funciona en los navegadores actuales.

Caracteres especiales y comentarios

Como < abre una etiqueta, para escribirlo como texto se usa una entidad: &lt;. Con UTF-8 puedes escribir directamente la ñ, los acentos, «comillas» o €, así que en la práctica solo necesitas tres o cuatro:

<p>5 &lt; 8 y 9 &gt; 2</p>
<p>Tom &amp; Jerry</p>
<p>Precio:&nbsp;$1,299.00 (el espacio duro no deja que se parta la línea)</p>
<!-- Esto es un comentario: no se ve en la página. -->
<p>© 2026 Mi sitio</p>

Los comentarios, entre <!-- y -->, sirven para dejar notas en el código. No salen en la página, pero cualquiera puede leerlos con «Ver código fuente», así que nunca guardes ahí contraseñas ni datos privados.

Retos de la lección 2

Reto 4. Haz una lista numerada con tres películas y, dentro del segundo punto, una lista con viñetas de dos actores.

Ver la solución
<ol>
  <li>Roma</li>
  <li>Amores perros
    <ul>
      <li>Gael García Bernal</li>
      <li>Emilio Echevarría</li>
    </ul>
  </li>
  <li>Y tu mamá también</li>
</ol>

Reto 5. Estás en blog/articulo.html (mira el esquema de las rutas). Escribe un enlace que vuelva a index.html con una ruta relativa, y otro que haga lo mismo desde la raíz del sitio.

Ver la solución
<a href="../index.html">Volver al inicio</a>
<a href="/index.html">Volver al inicio</a>

El primero sube una carpeta con ../. El segundo empieza por / y se cuenta desde el dominio; funciona igual desde cualquier página, pero solo una vez publicado en un servidor (al abrir el archivo con doble clic, la raíz es la del disco).

Reto 6. Escribe el alt de un logotipo que enlaza a la página de inicio, y el de una línea decorativa que separa dos secciones.

Ver la solución
<a href="/"><img src="https://decodigo.com/wp-content/uploads/2026/10/decodigo_placa_raspberry-pi-5.jpg" alt="Inicio" width="64" height="42"></a>
<img src="https://decodigo.com/wp-content/uploads/2026/10/decodigo_placa_raspberry-pi-5.jpg" alt="" width="200" height="4">

El del logotipo dice a dónde lleva el enlace; el de la línea decorativa va vacío para que el lector de pantalla lo ignore.

Cómo está hecho este curso

Cada fragmento de HTML de este curso pasó por el Nu Html Checker 26.11.4, el validador oficial del W3C, en un contenedor limpio; los mensajes de error que ves están copiados de esa ejecución (salen en inglés porque el validador no tiene otra versión). Cada resultado se pintó además en Chromium, Firefox y WebKit, los motores de Chrome, Firefox y Safari, y las cifras que da el texto (tamaños, colores) se midieron en los tres. Debajo de casi todos los ejemplos está el resultado en vivo y un enlace para abrirlo en el editor de HTML y CSS. Logotipos de HTML5 (W3C) y CSS3 (Rudloff) en la imagen de la página: Wikimedia Commons, CC BY 3.0.

¿Buscas una receta concreta en vez de una lección? En HTML y CSS hay ejemplos resueltos: centrar un elemento, un menú que se adapta al celular, una galería con Grid, modo oscuro… Y cuando quieras que tus páginas hagan cosas, sigue con el curso de JavaScript.