Texto y contenido: encabezados, entidades, listas y citas
Texto y contenido: encabezados, entidades, listas y citas
En el capitulo 2 aprendiste a pintar: colores en hexadecimal, rgb() y hsl(), unidades absolutas y relativas, y los selectores que permiten apuntar a un elemento concreto del documento. Tenias una pagina con fondo negro y texto gris, pero el contenido dentro de <body> seguia siendo un puñado de lineas sueltas.
Este capitulo llena ese vacio. Vamos a ver como el navegador convierte el texto plano que escribes en un archivo .html en el texto que se dibuja en pantalla, por que los saltos de linea que presionas con la tecla Enter desaparecen, como escribir la letra ñ, el signo ¿ o un emoji sin que se rompa nada, y cual es el conjunto completo de etiquetas que HTML ofrece para estructurar texto: encabezados, parrafos, listas, citas y una coleccion de elementos en linea que aportan significado ademas de apariencia.
Al terminar vas a tener una pagina de contenido real, no un ejercicio de colores, y vas a entender por que HTML distingue entre <b> y <strong> aunque en pantalla se vean iguales.
El punto de partida: por que el texto suelto no funciona
Empecemos con el caso mas simple posible. Crea un archivo texto.html con este contenido y abrelo en el navegador.
<!DOCTYPE html>
<html>
<head>
<title>Prueba de texto</title>
<style>
body {
color: #999999;
background-color: #000000;
}
</style>
</head>
<body>
?Que' tal como esta'n?
Ojala que le este'n entendiendo.
</body>
</html>
Al abrirlo pasan dos cosas que no esperabas:
- Las dos lineas salen pegadas en una sola. El navegador ignoro el Enter que separaba las frases y las junto con un solo espacio en el medio.
- Los acentos y el signo de interrogacion de apertura no aparecen, o aparecen como simbolos raros del tipo
¿Qué.
Los dos problemas tienen causas distintas y soluciones distintas. El primero es el algoritmo de colapso de espacios en blanco. El segundo es la codificacion de caracteres. Vamos uno por uno.
Como el navegador trata los espacios en blanco
En HTML, los siguientes caracteres se consideran espacio en blanco (whitespace):
| Caracter | Nombre | Como se produce |
|---|---|---|
| Espacio (U+0020) | Barra espaciadora |
\t | Tabulacion (U+0009) | Tecla Tab |
\n | Salto de linea (U+000A) | Tecla Enter en Linux y macOS |
\r | Retorno de carro (U+000D) | Parte del Enter en Windows |
\f | Avance de pagina (U+000C) | Poco frecuente hoy |
La regla por defecto, que en CSS se expresa como white-space: normal, dice: cualquier secuencia de uno o mas caracteres de espacio en blanco se colapsa en un unico espacio, y los espacios al inicio y al final de una linea renderizada se descartan.
Eso significa que estos tres bloques producen exactamente la misma salida visual:
<p>Hola mundo</p>
<p>Hola
mundo</p>
<p>
Hola
mundo
</p>
Los tres se dibujan como Hola mundo. El motivo de diseño es practico: el codigo fuente HTML se escribe con indentacion para que un humano lo lea, y esa indentacion no debe filtrarse al resultado. Si el navegador respetara cada espacio, indentar tu HTML cambiaria el diseño de la pagina.
Este es el recorrido que hace el texto desde el archivo hasta la pantalla:
flowchart TD
A["Archivo .html en disco<br/>secuencia de bytes"] --> B["Decodificacion<br/>bytes a caracteres Unicode"]
B --> C["Tokenizador HTML<br/>separa etiquetas de texto"]
C --> D["Resolucion de referencias<br/>&aacute; se convierte en a con tilde"]
D --> E["Nodo de texto en el DOM<br/>conserva TODOS los espacios"]
E --> F["Motor de layout<br/>aplica la propiedad white-space"]
F --> G{"white-space<br/>es normal?"}
G -->|Si| H["Colapsa espacios consecutivos<br/>a uno solo y recorta bordes"]
G -->|No, es pre| I["Respeta cada espacio<br/>y cada salto de linea"]
H --> J["Texto dibujado en pantalla"]
I --> J
El detalle importante es que el DOM si guarda los espacios originales. Si en el navegador abres la consola y escribes document.body.firstChild.textContent, vas a ver los saltos de linea y la indentacion tal como los escribiste. El colapso ocurre despues, en la fase de maquetado, y es una decision de CSS, no de HTML. Por eso se puede cambiar.
Controlar el colapso con white-space
La propiedad CSS white-space decide dos cosas: si los espacios se colapsan y si el texto se parte en varias lineas cuando no cabe.
| Valor | Espacios y tabs | Saltos de linea del codigo | Ajuste automatico de linea |
|---|---|---|---|
normal | Se colapsan | Se colapsan | Si |
nowrap | Se colapsan | Se colapsan | No |
pre | Se conservan | Se conservan | No |
pre-wrap | Se conservan | Se conservan | Si |
pre-line | Se colapsan | Se conservan | Si |
break-spaces | Se conservan | Se conservan | Si, incluso partiendo entre espacios |
Ejemplo ejecutable que muestra las diferencias lado a lado:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Comparador de white-space</title>
<style>
body {
background-color: #101014;
color: #e6e6e6;
font-family: system-ui, sans-serif;
padding: 2rem;
}
.caja {
border: 1px solid #3a3a48;
border-radius: 6px;
padding: 1rem;
margin-bottom: 1.5rem;
width: 22rem;
background-color: #1a1a22;
}
.caja h2 {
margin: 0 0 0.5rem 0;
font-size: 1rem;
color: #7fd1b9;
font-family: monospace;
}
.normal { white-space: normal; }
.nowrap { white-space: nowrap; overflow-x: auto; }
.pre { white-space: pre; overflow-x: auto; }
.prewrap { white-space: pre-wrap; }
.preline { white-space: pre-line; }
</style>
</head>
<body>
<div class="caja">
<h2>white-space: normal</h2>
<p class="normal">Primera linea con muchos espacios.
Segunda linea escrita despues de un Enter en el codigo.</p>
</div>
<div class="caja">
<h2>white-space: nowrap</h2>
<p class="nowrap">Primera linea con muchos espacios.
Segunda linea escrita despues de un Enter en el codigo.</p>
</div>
<div class="caja">
<h2>white-space: pre</h2>
<p class="pre">Primera linea con muchos espacios.
Segunda linea escrita despues de un Enter en el codigo.</p>
</div>
<div class="caja">
<h2>white-space: pre-wrap</h2>
<p class="prewrap">Primera linea con muchos espacios.
Segunda linea escrita despues de un Enter en el codigo.</p>
</div>
<div class="caja">
<h2>white-space: pre-line</h2>
<p class="preline">Primera linea con muchos espacios.
Segunda linea escrita despues de un Enter en el codigo.</p>
</div>
</body>
</html>
Guarda ese archivo, abrelo y compara las cinco cajas. Es la manera mas rapida de fijar el concepto.
La etiqueta <pre>
HTML trae un elemento que ya viene con white-space: pre aplicado desde la hoja de estilos por defecto del navegador: <pre>, de preformatted. Ademas usa una fuente monoespaciada.
<pre>
/\_/\
( o.o ) Este texto conserva
> ^ < cada espacio y cada salto.
</pre>
<pre> es el lugar natural para mostrar codigo fuente, salidas de terminal o diagramas de texto. Se combina muy a menudo con <code>:
<pre><code>function saludar(nombre) {
return "Hola, " + nombre;
}</code></pre>
Fijate en un detalle facil de pasar por alto: <pre> conserva el primer salto de linea de forma especial. La especificacion indica que un salto de linea inmediatamente despues de la etiqueta de apertura <pre> se descarta. Por eso el ejemplo anterior escribe <pre><code>function pegado y no en una linea nueva: asi evitas depender de esa regla y el resultado es el mismo en cualquier navegador.
Caracteres especiales, codificacion y entidades HTML
Ahora el segundo problema: los acentos.
El origen: bytes contra caracteres
Un archivo de texto en disco es una secuencia de bytes. Un byte guarda un numero entre 0 y 255. Para que ese numero se convierta en una letra hace falta una tabla de correspondencia: una codificacion.
- ASCII define solo 128 caracteres: letras sin acento de la A a la Z, digitos, signos de puntuacion basicos y caracteres de control. No incluye
á,ñ,¿ni€. - ISO-8859-1 (tambien llamada Latin-1) extiende ASCII hasta 256 caracteres y si incluye las vocales acentuadas del castellano, pero no alcanza para griego, cirilico, japones ni emojis.
- UTF-8 codifica todo Unicode, es decir, practicamente cualquier simbolo de cualquier idioma humano mas simbolos tecnicos y emojis. Usa entre 1 y 4 bytes por caracter y es totalmente compatible con ASCII en su primer byte.
Si tu editor guarda el archivo en UTF-8 (lo normal hoy) pero el navegador supone otra codificacion, cada byte se interpreta con la tabla equivocada y aparece la basura tipica: ñ en lugar de ñ, ¿ en lugar de ¿. Ese fenomeno se conoce como mojibake.
La solucion es declarar la codificacion explicitamente dentro de <head>, y hacerlo lo mas arriba posible:
<meta charset="utf-8">
Esta linea le dice al navegador: “los bytes de este documento estan codificados en UTF-8”. La especificacion exige que la declaracion aparezca dentro de los primeros 1024 bytes del documento, asi que la convencion es ponerla como primer elemento del <head>.
Que son las etiquetas <meta>
<meta> es un elemento vacio (no tiene etiqueta de cierre) que vive en <head> y aporta metadatos: informacion sobre el documento que no se muestra al usuario pero que consumen el navegador, los buscadores y las redes sociales.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Guia de texto y contenido en HTML.">
<meta name="author" content="Artiko">
<title>Prueba de texto</title>
</head>
<body>
<p>¿Que tal como estan?</p>
<p>Ojala que le esten entendiendo.</p>
</body>
</html>
Tres metadatos que conviene fijar de memoria:
| Declaracion | Para que sirve |
|---|---|
<meta charset="utf-8"> | Define la codificacion. Sin esto los acentos son loteria. |
<meta name="viewport" content="width=device-width, initial-scale=1"> | Hace que la pagina use el ancho real del telefono en vez de simular una pantalla de escritorio y encogerlo todo. |
<meta name="description" content="..."> | Texto que los buscadores suelen mostrar bajo el titulo del resultado. |
Y un cuarto elemento que no es <meta> pero cumple una funcion parecida: el atributo lang en <html>. lang="es" le indica al navegador el idioma del documento, lo que afecta a la separacion silabica automatica, a las comillas tipograficas y, sobre todo, a la pronunciacion de los lectores de pantalla.
Los cinco caracteres reservados
Aunque declares UTF-8, hay cinco caracteres que nunca puedes escribir tal cual dentro de contenido HTML, porque forman parte de la sintaxis del lenguaje:
| Caracter | Referencia con nombre | Decimal | Hexadecimal | Por que hay que escaparlo |
|---|---|---|---|---|
& | & | & | & | Inicia toda referencia de caracter |
< | < | < | < | Abre una etiqueta |
> | > | > | > | Cierra una etiqueta |
" | " | " | " | Delimita valores de atributo |
' | ' | ' | ' | Delimita valores de atributo |
Si quieres que en la pantalla aparezca el texto literal <p> como ejemplo de codigo, tienes que escribir <p>. Si escribes <p> el navegador crea un parrafo y no muestra nada.
Prueba este archivo:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Escapado de caracteres</title>
</head>
<body>
<p>Para crear un parrafo se usa la etiqueta <p>.</p>
<p>La empresa se llama Ninjas & Asociados.</p>
<p>El atributo se escribe title="Hola".</p>
<p>Comparacion: 5 < 10 > 3.</p>
</body>
</html>
En pantalla vas a leer los simbolos tal cual, sin que el navegador intente interpretarlos.
Las tres formas de escribir una referencia de caracter
Toda referencia de caracter empieza con & y termina con ;. Entre medio hay tres notaciones posibles:
flowchart LR
A["Ampersand<br/>&"] --> B{"Que sigue?"}
B -->|Una palabra| C["Referencia con nombre<br/>&aacute;"]
B -->|# y digitos| D["Referencia numerica decimal<br/>&#225;"]
B -->|#x y hexadecimal| E["Referencia numerica hexadecimal<br/>&#xE1;"]
C --> F["Punto de codigo Unicode<br/>U+00E1"]
D --> F
E --> F
F --> G["Caracter renderizado: a con tilde"]
Las tres formas producen el mismo caracter. Las referencias con nombre son mas legibles; las numericas funcionan para cualquier punto de codigo Unicode, incluso los que no tienen nombre asignado.
Tabla de referencia: castellano
| Caracter | Nombre | Decimal | Hexadecimal |
|---|---|---|---|
á | á | á | á |
é | é | é | é |
í | í | í | í |
ó | ó | ó | ó |
ú | ú | ú | ú |
Á | Á | Á | Á |
É | É | É | É |
ñ | ñ | ñ | ñ |
Ñ | Ñ | Ñ | Ñ |
ü | ü | ü | ü |
¿ | ¿ | ¿ | ¿ |
¡ | ¡ | ¡ | ¡ |
Tabla de referencia: simbolos frecuentes
| Caracter | Nombre | Decimal | Uso habitual |
|---|---|---|---|
| espacio duro | |   | Espacio que no permite un salto de linea en ese punto |
© | © | © | Aviso de derechos de autor en el pie de pagina |
® | ® | ® | Marca registrada |
™ | ™ | ™ | Marca comercial |
€ | € | € | Moneda |
– | – | – | Raya corta para rangos: 2024–2026 |
— | — | — | Raya larga para incisos |
… | … | … | Puntos suspensivos como un solo caracter |
« | « | « | Comilla angular de apertura |
» | » | » | Comilla angular de cierre |
“ | “ | “ | Comilla tipografica de apertura |
” | ” | ” | Comilla tipografica de cierre |
× | × | × | Multiplicacion o dimensiones: 1920 × 1080 |
° | ° | ° | Grados |
→ | → | → | Flecha derecha |
½ | ½ | ½ | Fraccion |
Espacios especiales y control de division
Hay un grupo de caracteres invisibles que resuelven problemas tipograficos concretos:
| Referencia | Nombre | Comportamiento |
|---|---|---|
| Espacio de no separacion | Ocupa un espacio y prohibe el salto de linea en ese punto |
  | Espacio fino de no separacion | Igual que el anterior pero mas estrecho |
­ | Guion blando | Invisible; si la palabra necesita partirse, se parte ahi y aparece un guion |
‑ | Guion de no separacion | Guion visible que no permite partir la palabra |
<wbr> | Oportunidad de salto | Etiqueta, no entidad; marca un punto donde si se puede partir |
Ejemplo practico: quieres que 10 kg nunca quede con el numero al final de una linea y la unidad al principio de la siguiente.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Espacios que no se rompen</title>
<style>
body { font-family: Georgia, serif; padding: 2rem; }
.angosto { width: 12rem; border: 1px dashed #888; padding: 0.5rem; }
</style>
</head>
<body>
<div class="angosto">
<p>El paquete pesa 10 kg y mide 30 cm.</p>
<p>El paquete pesa 10 kg y mide 30 cm.</p>
<p>Palabra larga con guion blando:
electro­encefalo­grafista.</p>
<p>Ruta partible: /usuarios<wbr>/perfil<wbr>/configuracion<wbr>/avanzada</p>
</div>
</body>
</html>
Reduce el ancho de la ventana y observa como se comportan de forma distinta.
Emojis y puntos de codigo altos
Con <meta charset="utf-8"> puedes escribir emojis directamente en el archivo. Tambien puedes usar su referencia numerica:
<p>Directo: 🎮 🕹️ ⭐</p>
<p>Numerico decimal: 🎮 🕹 ⭐</p>
<p>Numerico hexadecimal: 🎮 🕹 ⭐</p>
Las tres lineas producen los mismos simbolos. Ten en cuenta que muchos emojis modernos son secuencias de varios puntos de codigo unidos por el caracter zero width joiner (‍), asi que escribirlos con referencias numericas se vuelve incomodo rapido. Escribirlos directos es lo practico.
Encabezados: <h1> a <h6>
Un encabezado es el titulo de una seccion. HTML ofrece seis niveles, de <h1> (el mas importante) a <h6> (el menos importante). Cuanto mayor es el numero, menor es la importancia y, por defecto, menor es el tamaño de letra.
<h1>Super Club Net</h1>
<h2>Catalogo de premios</h2>
<h3>Consolas</h3>
<h4>Portatiles</h4>
<h5>Accesorios de portatiles</h5>
<h6>Fundas</h6>
Aqui esta el punto que separa a quien escribe HTML de quien escribe HTML bien: los encabezados no son tamaños de letra, son una estructura de arbol. El navegador, los buscadores y los lectores de pantalla construyen a partir de ellos un indice del documento. Un usuario ciego navega una pagina saltando de encabezado en encabezado, igual que tu recorres un libro mirando el indice.
graph TD
H1["h1 Super Club Net"] --> H2A["h2 Catalogo de premios"]
H1 --> H2B["h2 Como canjear puntos"]
H1 --> H2C["h2 Preguntas frecuentes"]
H2A --> H3A["h3 Consolas"]
H2A --> H3B["h3 Juegos"]
H2A --> H3C["h3 Merchandising"]
H3A --> H4A["h4 Consolas de sobremesa"]
H3A --> H4B["h4 Consolas portatiles"]
H2B --> H3D["h3 Registro de codigos"]
H2B --> H3E["h3 Envio a domicilio"]
La regla practica que se deriva del diagrama:
- Un solo
<h1>por pagina: el titulo de lo que trata ese documento. - No saltes niveles hacia abajo. Despues de un
<h2>viene un<h3>, nunca un<h4>. - Si volviste a subir de nivel (por ejemplo, de
<h4>a<h2>), estas cerrando una rama y abriendo otra. Eso si es correcto. - Nunca elijas
<h4>porque “se ve del tamaño justo”. Para eso esta CSS.
Comparacion de las dos formas de encarar el problema:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Encabezados con jerarquia correcta</title>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 40rem;
margin: 0 auto;
padding: 2rem;
line-height: 1.6;
}
h1 { font-size: 2.25rem; border-bottom: 3px solid #e63946; padding-bottom: 0.3rem; }
h2 { font-size: 1.6rem; color: #1d3557; margin-top: 2rem; }
h3 { font-size: 1.2rem; color: #457b9d; }
/* El h4 se ve pequeno por CSS, no por elegir la etiqueta equivocada */
h4 { font-size: 1rem; text-transform: uppercase; letter-spacing: 0.08em; color: #6c757d; }
</style>
</head>
<body>
<h1>Super Club Net</h1>
<p>Programa de puntos para jugadores.</p>
<h2>Catalogo de premios</h2>
<p>Estos son los articulos disponibles esta temporada.</p>
<h3>Consolas</h3>
<p>Disponibles mientras haya stock.</p>
<h4>Portatiles</h4>
<p>Modelos con pantalla integrada.</p>
<h2>Como canjear puntos</h2>
<p>Ingresa el codigo impreso en el envase del producto.</p>
</body>
</html>
Hay un mito que conviene desmontar: durante un tiempo se hablo de un “algoritmo de esquema” (outline algorithm) que permitiria usar varios <h1> dentro de <section> y dejar que el navegador calculara el nivel real. Ese algoritmo nunca se implemento en ningun navegador ni en ningun lector de pantalla, y la especificacion actual recomienda explicitamente usar los numeros de encabezado correctos a mano. Escribe <h2> cuando quieras un nivel 2.
Parrafos y saltos de linea
La etiqueta <p>
Un parrafo se marca con <p>. Cada <p> genera un bloque independiente con margen vertical arriba y abajo, lo que produce la separacion visual entre parrafos.
<p>El Super Club Net nacio como un programa de fidelizacion para jugadores.</p>
<p>Cada producto traia un codigo que se registraba en el sitio web.</p>
Dos reglas de sintaxis importantes:
- Un
<p>no puede contener otro<p>. Tampoco puede contener elementos de bloque como<div>,<ul>,<h2>o<table>. Si escribes<p><div>Hola</div></p>, el navegador cierra el parrafo automaticamente antes del<div>y termina generando un tercer parrafo vacio. El resultado en el DOM no coincide con lo que escribiste. - La etiqueta de cierre
</p>es opcional en la especificacion, pero omitirla produce codigo fragil y confuso. Cierrala siempre.
Puedes verificar el punto 1 con esta prueba:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Anidamiento invalido</title>
</head>
<body>
<p>Texto <div>bloque dentro de parrafo</div> resto</p>
<script>
console.log(document.body.innerHTML);
</script>
</body>
</html>
Abre la consola del navegador y compara lo que imprime console.log con lo que escribiste. Vas a ver que el navegador reorganizo el arbol.
La etiqueta <br>
<br> inserta un salto de linea dentro del mismo bloque de texto. Es un elemento vacio: no lleva contenido ni etiqueta de cierre.
<p>
Camilo Castro<br>
Ninjas.cl<br>
Santiago, Chile
</p>
<br> es correcto cuando el salto forma parte del contenido en si: una direccion postal, los versos de un poema, la letra de una cancion. No es correcto usar <br><br> para separar dos ideas distintas: eso son dos parrafos, y para eso existe <p>. La diferencia importa porque un lector de pantalla anuncia el cambio de parrafo, mientras que un <br> doble solo produce silencio.
La etiqueta <hr>
<hr> representa una separacion tematica: el punto donde cambia el tema dentro de una seccion. Historicamente se dibujaba como una linea horizontal, y ese sigue siendo su estilo por defecto, pero su significado es semantico.
<h2>Consolas</h2>
<p>Listado de consolas disponibles.</p>
<hr>
<h2>Juegos</h2>
<p>Listado de juegos disponibles.</p>
Se puede reestilizar por completo:
hr {
border: 0;
height: 2px;
background: linear-gradient(to right, transparent, #e63946, transparent);
margin: 2.5rem 0;
}
Listas
HTML define tres tipos de lista, cada uno con su significado propio.
Listas no ordenadas: <ul>
Se usan cuando el orden de los elementos no cambia el sentido de la lista. Cada elemento va dentro de un <li> (list item).
<h2>Requisitos para participar</h2>
<ul>
<li>Tener una cuenta registrada</li>
<li>Haber comprado un producto participante</li>
<li>Ingresar el codigo antes de la fecha de cierre</li>
</ul>
Listas ordenadas: <ol>
Se usan cuando el orden si importa: pasos de un procedimiento, un ranking, una cronologia.
<h2>Como canjear un premio</h2>
<ol>
<li>Inicia sesion en tu cuenta</li>
<li>Entra a la seccion Catalogo</li>
<li>Elige un premio cuyo costo en puntos puedas cubrir</li>
<li>Confirma la direccion de envio</li>
<li>Espera el correo de confirmacion</li>
</ol>
<ol> acepta tres atributos que modifican la numeracion:
| Atributo | Valores | Efecto |
|---|---|---|
type | 1, a, A, i, I | Estilo del marcador: numeros, letras minusculas o mayusculas, romanos minusculos o mayusculos |
start | Un entero | Numero con el que empieza la lista |
reversed | Booleano | Cuenta hacia atras |
Y <li> acepta value para forzar el numero de un elemento concreto, lo que ademas renumera los siguientes.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Atributos de listas ordenadas</title>
<style>
body { font-family: system-ui, sans-serif; padding: 2rem; line-height: 1.7; }
section { margin-bottom: 2rem; }
h3 { font-family: monospace; color: #1d3557; }
</style>
</head>
<body>
<section>
<h3>type="I"</h3>
<ol type="I">
<li>Introduccion</li>
<li>Desarrollo</li>
<li>Conclusiones</li>
</ol>
</section>
<section>
<h3>start="10"</h3>
<ol start="10">
<li>Decimo elemento</li>
<li>Undecimo elemento</li>
<li>Duodecimo elemento</li>
</ol>
</section>
<section>
<h3>reversed</h3>
<ol reversed>
<li>Bronce</li>
<li>Plata</li>
<li>Oro</li>
</ol>
</section>
<section>
<h3>value en un li</h3>
<ol>
<li>Uno</li>
<li value="50">Cincuenta</li>
<li>Cincuenta y uno</li>
</ol>
</section>
</body>
</html>
Listas anidadas
Una lista puede contener otra lista, pero la lista hija debe ir dentro de un <li>, no suelta entre dos <li>. Este es el error de anidamiento mas comun del lenguaje.
<ul>
<li>Consolas
<ul>
<li>De sobremesa</li>
<li>Portatiles
<ul>
<li>Con pantalla retroiluminada</li>
<li>Sin pantalla retroiluminada</li>
</ul>
</li>
</ul>
</li>
<li>Juegos</li>
<li>Accesorios</li>
</ul>
Asi queda el arbol del DOM que produce ese fragmento:
graph TD
UL1["ul"] --> LI1["li: Consolas"]
UL1 --> LI2["li: Juegos"]
UL1 --> LI3["li: Accesorios"]
LI1 --> UL2["ul anidada"]
UL2 --> LI4["li: De sobremesa"]
UL2 --> LI5["li: Portatiles"]
LI5 --> UL3["ul anidada"]
UL3 --> LI6["li: Con pantalla retroiluminada"]
UL3 --> LI7["li: Sin pantalla retroiluminada"]
Los unicos hijos validos de un <ul> o un <ol> son <li>, y opcionalmente <script> y <template>. Todo lo demas va dentro de un <li>.
Listas de descripcion: <dl>, <dt>, <dd>
Sirven para pares de termino y descripcion: un glosario, una ficha tecnica, metadatos.
<dl>(description list) es el contenedor.<dt>(description term) es el termino.<dd>(description details) es la descripcion.
Un <dt> puede tener varios <dd> (un termino con varias definiciones) y varios <dt> pueden compartir un <dd> (varios sinonimos con la misma definicion).
<h2>Glosario</h2>
<dl>
<dt>Punto</dt>
<dd>Unidad de la moneda interna del programa.</dd>
<dt>Codigo</dt>
<dt>Clave de registro</dt>
<dd>Secuencia alfanumerica impresa en el envase que otorga puntos al canjearse.</dd>
<dt>Catalogo</dt>
<dd>Listado de premios disponibles.</dd>
<dd>Documento impreso que se enviaba por correo postal.</dd>
</dl>
Desde HTML5.2 tambien es valido envolver cada grupo en un <div> dentro del <dl>, lo que facilita darle estilo a cada par:
<dl>
<div class="par">
<dt>Punto</dt>
<dd>Unidad de la moneda interna del programa.</dd>
</div>
<div class="par">
<dt>Codigo</dt>
<dd>Secuencia alfanumerica impresa en el envase.</dd>
</div>
</dl>
.par {
display: grid;
grid-template-columns: 10rem 1fr;
gap: 0.5rem;
padding: 0.5rem 0;
border-bottom: 1px solid #ddd;
}
dt { font-weight: 700; }
dd { margin: 0; }
La etiqueta <menu>
<menu> es semanticamente equivalente a <ul> y se renderiza igual. La especificacion actual la describe como una lista no ordenada de comandos o herramientas interactivas: una barra de botones, por ejemplo. Si tu lista es de contenido, usa <ul>; si es de acciones, <menu> es una alternativa valida.
<menu>
<li><button type="button">Copiar</button></li>
<li><button type="button">Pegar</button></li>
<li><button type="button">Deshacer</button></li>
</menu>
Dar estilo a las listas con CSS
| Propiedad | Valores frecuentes | Efecto |
|---|---|---|
list-style-type | disc, circle, square, decimal, decimal-leading-zero, lower-alpha, upper-alpha, lower-roman, upper-roman, none | Forma del marcador |
list-style-position | outside (por defecto), inside | Si el marcador queda fuera o dentro de la caja del texto |
list-style-image | url(...), none | Imagen como marcador |
list-style | Atajo de las tres anteriores | Se escribe en una sola linea |
Ademas existe el pseudoelemento ::marker, que permite estilar el marcador sin quitarlo:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Estilos de lista</title>
<style>
body { font-family: system-ui, sans-serif; padding: 2rem; line-height: 1.8; }
.cuadrada { list-style-type: square; }
.romana { list-style-type: upper-roman; }
.marcador-color li::marker {
color: #e63946;
font-weight: 700;
}
.marcador-texto li::marker {
content: "▸ ";
color: #2a9d8f;
}
/* Lista sin marcadores, usada como navegacion horizontal */
.horizontal {
list-style: none;
padding: 0;
display: flex;
gap: 1rem;
}
.horizontal li {
background: #1d3557;
color: white;
padding: 0.4rem 0.9rem;
border-radius: 999px;
}
</style>
</head>
<body>
<ul class="cuadrada">
<li>Marcador cuadrado</li>
<li>Segundo elemento</li>
</ul>
<ol class="romana">
<li>Numeracion romana</li>
<li>Segundo elemento</li>
<li>Tercer elemento</li>
</ol>
<ol class="marcador-color">
<li>Numero en rojo y negrita</li>
<li>Segundo elemento</li>
</ol>
<ul class="marcador-texto">
<li>Marcador reemplazado por un triangulo</li>
<li>Segundo elemento</li>
</ul>
<ul class="horizontal">
<li>Inicio</li>
<li>Catalogo</li>
<li>Contacto</li>
</ul>
</body>
</html>
Un apunte de accesibilidad: cuando aplicas list-style: none a una lista, algunos navegadores dejan de anunciarla como lista a los lectores de pantalla. Si la lista es informativa y quieres conservar ese anuncio, añade role="list" al elemento <ul>.
Citas
<blockquote>: cita en bloque
Representa un fragmento citado de otra fuente que ocupa su propio bloque. Acepta el atributo cite, cuyo valor es la URL de origen. Ese atributo no se muestra en pantalla: esta pensado para maquinas.
<blockquote cite="https://ninjas.cl/books/superclubnet/">
<p>El contenido de una pagina no es solo texto: es texto con estructura.</p>
</blockquote>
Si quieres mostrar la atribucion de forma visible, la practica recomendada es envolver todo en <figure> y usar <figcaption>:
<figure>
<blockquote cite="https://ninjas.cl/books/superclubnet/">
<p>El contenido de una pagina no es solo texto: es texto con estructura.</p>
</blockquote>
<figcaption>
Camilo Castro, <cite>Super Club Net</cite>
</figcaption>
</figure>
Fijate en <cite>: marca el titulo de la obra, no el nombre de la persona. Es un error comun envolver el nombre del autor en <cite>.
<q>: cita en linea
Para una cita corta dentro de un parrafo. El navegador añade las comillas automaticamente, asi que no debes escribirlas tu.
<p>La consigna del programa era <q>juega, registra y canjea</q>, repetida en cada envase.</p>
Las comillas que inserta el navegador dependen del idioma declarado con lang, y se pueden personalizar con la propiedad CSS quotes:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Citas en linea</title>
<style>
body { font-family: Georgia, serif; padding: 2rem; line-height: 1.8; }
/* Comillas angulares, tipicas del castellano tipografico */
.angulares q {
quotes: "«" "»" "‹" "›";
}
blockquote {
margin: 1.5rem 0;
padding: 0.5rem 1.5rem;
border-left: 4px solid #e63946;
font-style: italic;
color: #333;
}
figcaption {
font-size: 0.9rem;
color: #666;
padding-left: 1.5rem;
}
cite { font-style: normal; font-weight: 600; }
</style>
</head>
<body>
<p>Comillas por defecto: <q>juega, registra y canjea</q>.</p>
<div class="angulares">
<p>Comillas angulares: <q>juega, <q>registra</q> y canjea</q>.</p>
</div>
<figure>
<blockquote cite="https://ninjas.cl/books/superclubnet/">
<p>El contenido de una pagina no es solo texto: es texto con estructura.</p>
</blockquote>
<figcaption>Camilo Castro, <cite>Super Club Net</cite></figcaption>
</figure>
</body>
</html>
Observa el ejemplo de comillas angulares: la cita anidada usa automaticamente el segundo par declarado en quotes. Ese comportamiento es lo que hace que <q> sea preferible a escribir las comillas a mano.
El catalogo de etiquetas en linea
Los elementos que siguen son inline: no crean un bloque nuevo, se integran dentro del flujo del texto. Casi todos tienen un estilo por defecto, pero su razon de existir es el significado que aportan.
Enfasis e importancia
| Etiqueta | Significado | Estilo por defecto |
|---|---|---|
<strong> | Importancia alta, urgencia o seriedad | Negrita |
<b> | Texto destacado por convencion tipografica, sin importancia extra | Negrita |
<em> | Enfasis que cambia el sentido de la frase al leerla en voz alta | Cursiva |
<i> | Voz alternativa: termino tecnico, palabra extranjera, pensamiento | Cursiva |
<mark> | Relevancia en el contexto actual, como un resaltador | Fondo amarillo |
<small> | Comentario al margen, letra chica legal | Tamaño menor |
<u> | Anotacion no textual: por ejemplo, un error ortografico marcado | Subrayado |
La diferencia entre <strong> y <b> no se ve en pantalla, se oye. Un lector de pantalla puede cambiar el enfasis de la voz al llegar a un <strong>; con <b> no lo hace. Lo mismo con <em> frente a <i>.
<p><strong>Atencion:</strong> los codigos vencen el 31 de diciembre.</p>
<p>El nombre cientifico es <i lang="la">Homo sapiens</i>.</p>
<p>No dije que fuera <em>facil</em>, dije que era posible.</p>
<p>Resultados para <mark>consola portatil</mark> en el catalogo.</p>
<p><small>Promocion valida solo en territorio nacional.</small></p>
Cambios en el texto
| Etiqueta | Significado | Atributos utiles |
|---|---|---|
<del> | Texto eliminado del documento | cite, datetime |
<ins> | Texto insertado en el documento | cite, datetime |
<s> | Texto que ya no es exacto o pertinente | Ninguno |
<p>Precio: <s>25.000 puntos</s> <ins datetime="2026-08-01">18.000 puntos</ins></p>
<p>La reunion es el <del datetime="2026-07-15">lunes</del> <ins>martes</ins>.</p>
<s> marca algo que dejo de ser cierto (un precio antiguo). <del> marca una edicion del documento, con fecha y motivo opcionales. Son cosas distintas aunque ambas se dibujen tachadas.
Terminos tecnicos y codigo
| Etiqueta | Que representa |
|---|---|
<code> | Fragmento de codigo fuente |
<kbd> | Pulsacion de teclas del usuario |
<samp> | Salida producida por un programa |
<var> | Nombre de una variable o de una incognita matematica |
<abbr> | Abreviatura o sigla; el atributo title da la forma completa |
<dfn> | El termino que se esta definiendo en esa frase |
<p>Para guardar el archivo presiona <kbd>Ctrl</kbd> + <kbd>S</kbd>.</p>
<p>Escribe <code>console.log("hola")</code> en la consola.</p>
<p>El programa responde <samp>Archivo guardado correctamente</samp>.</p>
<p>Si <var>x</var> vale 3, entonces <var>y</var> vale 9.</p>
<p>El <abbr title="Document Object Model">DOM</abbr> es la representacion en memoria de la pagina.</p>
<p><dfn>Entidad HTML</dfn> es la forma de escribir un caracter mediante una referencia con nombre.</p>
Estilar <kbd> para que parezca una tecla es un ejercicio clasico:
kbd {
font-family: ui-monospace, monospace;
font-size: 0.85em;
background: #f4f4f5;
border: 1px solid #c9c9cf;
border-bottom-width: 3px;
border-radius: 5px;
padding: 0.15em 0.45em;
color: #18181b;
}
Posicion vertical y datos maquinables
| Etiqueta | Uso |
|---|---|
<sub> | Subindice: H2O |
<sup> | Superindice: 103, 1er |
<time> | Fecha u hora; el atributo datetime la expresa en formato legible por maquinas |
<data> | Valor maquinable asociado a un texto; el atributo value lleva el dato |
<span> | Ningun significado; existe solo para poder aplicarle estilos o engancharlo desde JavaScript |
<p>La formula del agua es H<sub>2</sub>O.</p>
<p>La velocidad de la luz es 3 × 10<sup>8</sup> m/s.</p>
<p>El concurso cierra el <time datetime="2026-12-31">31 de diciembre de 2026</time>.</p>
<p>Producto <data value="SKU-40921">Consola portatil edicion limitada</data>.</p>
<p>Nivel: <span class="rango-oro">Oro</span></p>
<span> merece una aclaracion. Es el equivalente en linea de <div>: un contenedor generico sin semantica. Usalo cuando ninguna otra etiqueta describa lo que quieres marcar. Si lo que quieres es dar importancia, usa <strong>; si es un termino tecnico, usa <code> o <var>. <span> es el ultimo recurso, no el primero.
Direccion del texto y separacion silabica
| Etiqueta | Uso |
|---|---|
<bdi> | Aisla un fragmento cuya direccion (izquierda a derecha o derecha a izquierda) es desconocida, tipicamente contenido escrito por usuarios |
<bdo dir="rtl"> | Fuerza la direccion del texto que contiene |
<wbr> | Marca un punto donde el navegador puede partir una palabra larga |
<ruby>, <rt>, <rp> | Anotaciones de pronunciacion, usadas sobre todo en japones y chino |
<p>Usuario: <bdi>محمد</bdi> obtuvo 3400 puntos.</p>
<p><bdo dir="rtl">Este texto se dibuja al reves</bdo></p>
<ruby>漢<rp>(</rp><rt>kan</rt><rp>)</rp>字<rp>(</rp><rt>ji</rt><rp>)</rp></ruby>
Los elementos <rp> contienen parentesis que solo se muestran en navegadores que no soportan <ruby>, para que la pronunciacion siga siendo legible.
Etiquetas heredadas
Algunas etiquetas de texto siguen funcionando en los navegadores pero estan marcadas como obsoletas en la especificacion. Conviene reconocerlas al leer codigo antiguo y no usarlas en codigo nuevo:
| Etiqueta obsoleta | Que hacia | Que usar hoy |
|---|---|---|
<tt> | Texto de ancho fijo | <code>, <kbd> o CSS font-family: monospace |
<font> | Fijaba tipo, tamaño y color | CSS: font-family, font-size, color |
<center> | Centraba el contenido | CSS: text-align: center |
<big> | Aumentaba el tamaño | CSS: font-size |
<strike> | Tachaba el texto | <s> o <del> |
Control tipografico desde CSS
Las etiquetas dan estructura y significado; CSS decide como se ve. Estas son las propiedades de texto que mas se usan.
| Propiedad | Que controla | Ejemplo de valor |
|---|---|---|
font-family | La lista de fuentes, en orden de preferencia | Georgia, "Times New Roman", serif |
font-size | Tamaño de la letra | 1.125rem |
font-weight | Grosor del trazo | 400, 700, bold |
font-style | Cursiva o normal | italic |
line-height | Alto de linea, es decir el interlineado | 1.6 (sin unidad, recomendado) |
letter-spacing | Espacio entre letras | 0.02em |
word-spacing | Espacio entre palabras | 0.1em |
text-align | Alineacion horizontal | left, center, right, justify |
text-indent | Sangria de la primera linea | 2em |
text-transform | Cambio de caja | uppercase, lowercase, capitalize |
text-decoration | Subrayado, tachado, sobrelinea | underline wavy #e63946 |
text-shadow | Sombra del texto | 1px 1px 2px rgba(0,0,0,0.4) |
overflow-wrap | Si una palabra larga puede partirse para no desbordar | break-word, anywhere |
word-break | Regla estricta de corte de palabras | break-all, keep-all |
hyphens | Separacion silabica automatica | auto (requiere lang en el HTML) |
text-wrap | Estrategia de reparto de lineas | balance, pretty |
columns | Reparte el texto en columnas | 2 |
Dos aclaraciones que ahorran horas de depuracion:
line-heightsin unidad es distinto deline-heightcon unidad.line-height: 1.6significa “1.6 veces el tamaño de fuente de cada elemento”, y se recalcula en cada descendiente.line-height: 1.6remfija un valor absoluto que los hijos heredan aunque su fuente sea mas grande, y produce lineas montadas. Usa el valor sin unidad.hyphens: autono hace nada si no declaras el idioma. El navegador necesita el diccionario de separacion silabica correcto, y lo elige a partir del atributolangdel HTML.
Ejemplo completo que combina lo anterior:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tipografia aplicada</title>
<style>
:root {
--tinta: #1b1b1f;
--tinta-suave: #55555f;
--acento: #e63946;
--papel: #fdfcf7;
}
body {
background: var(--papel);
color: var(--tinta);
font-family: Georgia, "Times New Roman", serif;
font-size: 1.125rem;
line-height: 1.65;
max-width: 38rem;
margin: 0 auto;
padding: 3rem 1.5rem;
hyphens: auto;
}
h1 {
font-family: system-ui, sans-serif;
font-size: clamp(2rem, 5vw, 3rem);
line-height: 1.1;
letter-spacing: -0.02em;
text-wrap: balance;
margin-bottom: 0.25em;
}
.bajada {
font-size: 1.3rem;
color: var(--tinta-suave);
font-style: italic;
margin-top: 0;
}
/* Capitular: la primera letra del primer parrafo, grande */
.cuerpo > p:first-of-type::first-letter {
float: left;
font-size: 3.6em;
line-height: 0.8;
padding-right: 0.08em;
color: var(--acento);
font-weight: 700;
}
/* Versalitas en la primera linea */
.cuerpo > p:first-of-type::first-line {
font-variant-caps: small-caps;
letter-spacing: 0.04em;
}
.cuerpo p + p {
text-indent: 1.5em;
margin-top: 0;
}
.destacado {
text-align: center;
font-size: 1.5rem;
line-height: 1.35;
color: var(--acento);
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
padding: 1.2rem 0;
margin: 2.5rem 0;
text-wrap: balance;
}
.ruta {
font-family: ui-monospace, monospace;
font-size: 0.9rem;
background: #f0efe9;
padding: 0.6rem 0.8rem;
border-radius: 4px;
overflow-wrap: anywhere;
}
</style>
</head>
<body>
<h1>El programa que convirtio los envases en monedas</h1>
<p class="bajada">Como funcionaba el sistema de puntos y por que desaparecio.</p>
<div class="cuerpo">
<p>Durante mas de una decada, cada envase incluia una tarjeta con un codigo alfanumerico. Ese codigo se ingresaba en el sitio web y se transformaba en puntos acumulables, que despues se cambiaban por productos del catalogo.</p>
<p>El sistema dependia de tres piezas: la impresion del codigo, el formulario de registro y la base de datos que evitaba que un mismo codigo se canjeara dos veces.</p>
<p>Cuando la distribucion de juegos paso a ser mayoritariamente digital, la pieza fisica dejo de existir, y con ella el programa completo.</p>
</div>
<p class="destacado">Un codigo impreso era, en la practica, dinero con fecha de vencimiento.</p>
<p class="ruta">https://ejemplo.cl/catalogo/consolas/portatiles/edicion-limitada/registro-de-codigo</p>
</body>
</html>
Prueba a reducir el ancho de la ventana: overflow-wrap: anywhere evita que la URL larga desborde el contenedor, y text-wrap: balance reparte el titular en lineas de largo parecido en vez de dejar una palabra huerfana al final.
Ejemplo integrador: una pagina de contenido completa
Este archivo reune todo lo del capitulo en una pagina real. Copialo, guardalo como contenido.html y abrelo.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Ficha del programa Super Club Net: como funcionaba, glosario y preguntas frecuentes.">
<meta name="author" content="Artiko">
<title>Super Club Net — Ficha del programa</title>
<style>
:root {
--fondo: #0f1117;
--superficie: #181b24;
--borde: #2c3040;
--texto: #e8e8ee;
--texto-suave: #a0a4b8;
--acento: #f4a261;
--acento-2: #2a9d8f;
}
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--fondo);
color: var(--texto);
font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
font-size: 1.0625rem;
line-height: 1.65;
}
main {
max-width: 44rem;
margin: 0 auto;
padding: 3rem 1.25rem 5rem;
}
h1 {
font-size: clamp(1.9rem, 5vw, 2.8rem);
line-height: 1.15;
text-wrap: balance;
margin: 0 0 0.4em;
}
h2 {
font-size: 1.5rem;
margin-top: 2.8rem;
padding-bottom: 0.3rem;
border-bottom: 2px solid var(--borde);
color: var(--acento);
}
h3 {
font-size: 1.15rem;
color: var(--acento-2);
margin-top: 1.8rem;
}
.bajada {
color: var(--texto-suave);
font-size: 1.2rem;
margin-top: 0;
}
abbr[title] {
text-decoration: underline dotted var(--acento);
cursor: help;
}
kbd {
font-family: ui-monospace, monospace;
font-size: 0.85em;
background: var(--superficie);
border: 1px solid var(--borde);
border-bottom-width: 3px;
border-radius: 5px;
padding: 0.1em 0.45em;
}
code {
font-family: ui-monospace, monospace;
background: var(--superficie);
padding: 0.1em 0.35em;
border-radius: 4px;
font-size: 0.9em;
color: var(--acento);
}
mark {
background: var(--acento);
color: #1a1a1a;
padding: 0 0.2em;
border-radius: 3px;
}
blockquote {
margin: 0;
padding: 0.2rem 0 0.2rem 1.4rem;
border-left: 4px solid var(--acento-2);
font-style: italic;
color: var(--texto-suave);
}
figure { margin: 2rem 0; }
figcaption {
font-size: 0.9rem;
color: var(--texto-suave);
padding-left: 1.7rem;
margin-top: 0.5rem;
}
cite { font-style: normal; font-weight: 600; color: var(--texto); }
ol.pasos { padding-left: 1.4rem; }
ol.pasos li { margin-bottom: 0.6rem; }
ol.pasos li::marker {
color: var(--acento);
font-weight: 700;
}
ul.requisitos { list-style: square; padding-left: 1.4rem; }
ul.requisitos li::marker { color: var(--acento-2); }
dl.glosario { margin: 0; }
dl.glosario > div {
display: grid;
grid-template-columns: 11rem 1fr;
gap: 0.6rem;
padding: 0.7rem 0;
border-bottom: 1px solid var(--borde);
}
dl.glosario dt { font-weight: 700; color: var(--acento-2); }
dl.glosario dd { margin: 0; color: var(--texto-suave); }
@media (max-width: 34rem) {
dl.glosario > div { grid-template-columns: 1fr; gap: 0.15rem; }
}
hr {
border: 0;
height: 1px;
background: linear-gradient(to right, transparent, var(--borde), transparent);
margin: 3rem 0;
}
footer {
border-top: 1px solid var(--borde);
padding-top: 1.2rem;
font-size: 0.9rem;
color: var(--texto-suave);
}
</style>
</head>
<body>
<main>
<h1>Super Club Net</h1>
<p class="bajada">Programa de puntos canjeables que funciono entre 2003 y 2015.</p>
<p>El <dfn>Super Club Net</dfn> era un programa de fidelizacion: cada producto original incluia un codigo impreso que, al registrarse en el sitio web, se convertia en puntos. Los puntos se acumulaban en una cuenta y se cambiaban por articulos de un catalogo rotativo.</p>
<p><strong>El programa ya no esta activo.</strong> Esta ficha documenta como funcionaba, con fines historicos y didacticos.</p>
<h2>Como funcionaba el canje</h2>
<h3>Requisitos</h3>
<ul class="requisitos">
<li>Cuenta registrada con correo verificado</li>
<li>Producto original con tarjeta de codigo intacta</li>
<li>Registro del codigo antes de su fecha de vencimiento</li>
<li>Direccion de envio dentro del pais</li>
</ul>
<h3>Pasos</h3>
<ol class="pasos">
<li>Ingresa a tu cuenta con tu correo y contraseña.</li>
<li>Entra a la seccion <mark>Registrar codigo</mark>.</li>
<li>Escribe los 16 caracteres de la tarjeta y presiona <kbd>Enter</kbd>.</li>
<li>Verifica que el saldo aumento en la esquina superior derecha.</li>
<li>Abre el catalogo y elige un articulo cuyo costo puedas cubrir.</li>
<li>Confirma la direccion y espera el correo de despacho.</li>
</ol>
<p>Si el codigo ya estaba usado, la respuesta del sistema era <samp>Codigo no valido o ya canjeado</samp>. En terminos tecnicos, el servidor devolvia un estado <code>409 Conflict</code>.</p>
<hr>
<h2>Costos de ejemplo</h2>
<p>Los precios se expresaban en puntos, no en moneda. Algunos ejemplos del catalogo de 2010:</p>
<ol>
<li>Llavero de metal — 400 puntos</li>
<li>Poster impreso 60 × 90 cm — 900 puntos</li>
<li>Juego de mesa — <s>4.500 puntos</s> <ins datetime="2010-11-01">3.200 puntos</ins></li>
<li>Consola portatil edicion limitada — 42.000 puntos</li>
</ol>
<h2>Glosario</h2>
<dl class="glosario">
<div>
<dt>Punto</dt>
<dd>Unidad de la moneda interna. No tenia equivalencia oficial en dinero.</dd>
</div>
<div>
<dt>Codigo</dt>
<dd>Secuencia de 16 caracteres alfanumericos impresa en una tarjeta dentro del envase.</dd>
</div>
<div>
<dt>Catalogo</dt>
<dd>Listado de articulos disponibles. Se renovaba cada temporada.</dd>
</div>
<div>
<dt><abbr title="Stock Keeping Unit">SKU</abbr></dt>
<dd>Identificador unico de cada articulo del catalogo, del tipo <code>SKU-40921</code>.</dd>
</div>
</dl>
<h2>Cita</h2>
<figure>
<blockquote cite="https://ninjas.cl/books/superclubnet/">
<p>La idea era simple: convertir el envase, que normalmente se bota, en la puerta de entrada a un servicio en linea.</p>
</blockquote>
<figcaption>Nota de prensa, <cite>Archivo del programa</cite>, <time datetime="2004-05-12">12 de mayo de 2004</time></figcaption>
</figure>
<h2>Notas</h2>
<p>La formula de conversion aproximada era <var>p</var> = <var>v</var> × 10<sup>-2</sup>, donde <var>v</var> era el valor de venta del producto. <small>Este calculo es una reconstruccion a partir de material publico y no corresponde a documentacion oficial.</small></p>
<footer>
<p>© 2026 Artiko — Material didactico basado en el temario de <cite>Super Club Net</cite> de Camilo Castro, Ninjas.cl, bajo licencia CC BY-NC-SA 4.0.</p>
</footer>
</main>
</body>
</html>
Errores comunes
| Error | Causa | Solucion |
|---|---|---|
Los acentos salen como á o ¿ | El archivo esta guardado en UTF-8 pero falta <meta charset="utf-8"> o esta declarado despues de los primeros 1024 bytes | Poner <meta charset="utf-8"> como primer elemento dentro de <head> y confirmar que el editor guarda en UTF-8 sin BOM |
| Presiono Enter en el codigo y en pantalla no hay salto | white-space: normal colapsa los saltos de linea del codigo fuente | Usar <p> para separar ideas, <br> para saltos dentro del mismo bloque, o white-space: pre-line si el salto debe respetarse |
Escribo <p> como ejemplo y no aparece nada | El navegador interpreta < como apertura de etiqueta | Escapar con <p> |
El texto Ninjas & Asociados rompe la pagina o se come lo siguiente | El & inicia una referencia de caracter y el navegador intenta resolverla | Escribir & |
Uso <h4> porque <h2> se veia muy grande | Se esta eligiendo la etiqueta por su tamaño y no por su nivel jerarquico | Usar el nivel correcto y ajustar font-size en CSS |
Un <div> dentro de un <p> genera parrafos vacios inesperados | <p> solo admite contenido en linea; el navegador cierra el parrafo antes del bloque | Sacar el bloque fuera del parrafo, o usar <span> si solo se necesita un contenedor en linea |
| La lista anidada aparece desalineada o fuera de lugar | El <ul> hijo se escribio entre dos <li> en vez de dentro de un <li> | Meter la lista anidada dentro del <li> al que pertenece |
<ul class="sin-marcas"> deja de anunciarse como lista en un lector de pantalla | Algunos navegadores quitan el rol de lista cuando list-style es none | Añadir role="list" al elemento <ul> |
Las comillas de <q> salen duplicadas | Se escribieron comillas a mano ademas de las que inserta el navegador | Quitar las comillas manuales; personalizar las automaticas con la propiedad CSS quotes |
<cite> envuelve el nombre del autor | <cite> marca el titulo de la obra, no la persona | Poner el titulo en <cite> y el nombre como texto normal o dentro de <figcaption> |
| Las lineas de texto se montan unas sobre otras al agrandar la fuente | line-height se declaro con unidad (1.6rem) y no se recalcula al heredarse | Declarar line-height sin unidad: line-height: 1.6 |
hyphens: auto no separa nada | Falta el atributo lang en <html>, asi que el navegador no sabe que diccionario usar | Declarar <html lang="es"> |
| Una URL larga desborda su contenedor | Las URLs no tienen espacios y el navegador no encuentra donde partir la linea | Aplicar overflow-wrap: anywhere o insertar <wbr> en los puntos de corte deseados |
El primer salto de linea dentro de <pre> desaparece | La especificacion descarta un salto de linea inmediatamente posterior a <pre> | Empezar el contenido en la misma linea que la etiqueta de apertura |
El texto dentro de <pre> desborda a lo ancho | <pre> usa white-space: pre, que no permite ajuste automatico de linea | Usar overflow-x: auto en el <pre> o cambiar a white-space: pre-wrap |
Ejercicios propuestos
-
Auditoria de espacios. Crea un archivo con un
<p>que contenga cinco espacios seguidos, una tabulacion y dos saltos de linea. Abre la consola del navegador y comparaelement.textContent.lengthcon el numero de caracteres que ves en pantalla. Explica por escrito la diferencia. -
Tabla de entidades. Construye una pagina que muestre una tabla de al menos veinte caracteres especiales con cuatro columnas: el caracter renderizado, su referencia con nombre, su referencia decimal y su referencia hexadecimal. La columna de referencias debe mostrar el codigo literal, asi que necesitaras escapar cada
&con&. -
Indice generado. Escribe un articulo con un
<h1>, tres<h2>y al menos dos<h3>bajo cada<h2>. Al final del documento, construye a mano una lista anidada<ol>que refleje exactamente esa jerarquia. Dibuja el arbol resultante como diagrama antes de escribir el HTML. -
Cinco cajas de
white-space. Toma el comparador de la seccion correspondiente y añade una sexta caja conwhite-space: break-spaces. Documenta en que se diferencia depre-wrapusando una cadena con muchos espacios seguidos al final de una linea. -
Ficha tecnica con
<dl>. Crea la ficha de un producto con al menos ocho pares termino/descripcion. Incluye un caso de dos<dt>que compartan un<dd>y un caso de un<dt>con dos<dd>. Maquetala con CSS Grid en dos columnas en pantallas anchas y una columna en pantallas angostas. -
Semantica correcta. Toma este parrafo y marca cada fragmento con la etiqueta en linea adecuada: “Presiona Control mas S para guardar. El sistema responde Guardado. Si la variable n vale cero, se lanza una excepcion del tipo RangeError. El DOM se actualiza despues.”
-
Citas con atribucion. Construye una pagina con tres citas: una con
<q>dentro de un parrafo, una con<blockquote>simple, y una con<figure>mas<figcaption>y<cite>. Personaliza las comillas de<q>con la propiedadquotespara que use comillas angulares. -
Antes y despues. Busca una pagina cualquiera con el inspector del navegador y localiza tres elementos donde se haya usado
<div>o<span>para algo que tiene una etiqueta semantica propia. Reescribe ese fragmento con las etiquetas correctas y anota que cambia en el arbol de accesibilidad. -
Tipografia editorial. Reproduce el ejemplo de tipografia aplicada pero cambia la fuente a una monoespaciada, ajusta
line-height,letter-spacingymax-widthhasta que un parrafo tenga entre 60 y 75 caracteres por linea. Explica que valores usaste y por que. -
Reto de robustez. Escribe una pagina cuyo contenido incluya una URL de mas de 90 caracteres, una palabra tecnica de mas de 25 letras, una cifra con su unidad, y una lista de siglas. Aplica
overflow-wrap,­, y<abbr>de modo que la pagina se vea bien en un contenedor de 240 pixeles de ancho sin barras de desplazamiento horizontal.
Lo que viene
Ya sabes estructurar texto: darle jerarquia con encabezados, agruparlo en parrafos, enumerarlo en listas, citarlo con atribucion, escribir cualquier caracter de cualquier idioma y controlar con precision como se reparten las lineas. Ese es el 80 por ciento del contenido de la mayoria de las paginas web.
Falta un tipo de contenido que no encaja en ninguna de esas formas: los datos que tienen dos dimensiones, filas y columnas. En el capitulo 4 vamos a ver las tablas: la estructura completa con <table>, <thead>, <tbody>, <tfoot>, <th> y <td>, la combinacion de celdas con colspan y rowspan, los grupos de columnas, la accesibilidad de una tabla de datos, y como darles estilo con CSS usando border-collapse, :nth-child para el rayado alternado, encabezados fijos al desplazar y un patron responsive para que una tabla ancha siga siendo legible en un telefono.
El indice completo del curso esta en /tecnologias/superclubnet/00-indice/.