Skip to content
This page has been auto-translated and may contain errors.View in English

Listas ​

docs.scrimba.com

Una cantidad sorprendente de una página web es en realidad una lista: menús de navegación, resultados de búsqueda, cuadrículas de productos, los ingredientes de una receta, los pasos para restablecer una contraseña. Cuando el contenido es un conjunto de elementos relacionados, HTML tiene un elemento que lo indica, y usarlo hace que el navegador, y cualquier persona que lea con software de asistencia, sepa que esos elementos van juntos.

Listas no ordenadas ​

Cuando el orden de los elementos no importa, usas una lista no ordenada. Piensa en una lista de compras: leche, pan, huevos. No importa cuál escribas primero, son un grupo de cosas agrupadas.

Se construye con dos etiquetas. La etiqueta <ul> envuelve toda la lista, y cada elemento va dentro de su propia etiqueta <li> ("list item", elemento de lista):

html
<ul>
  <li>Leche</li>
  <li>Pan</li>
  <li>Huevos</li>
</ul>

El navegador muestra cada elemento en su propia línea con una viñeta delante. Tú no agregaste las viñetas ni los saltos de línea, el navegador lo hace porque le dijiste que esto es una lista.

Una lista no ordenada es un grupo de elementos donde la secuencia no tiene ningún significado. El elemento <ul> es el contenedor, y cada hijo directo es un elemento <li> que contiene un elemento:

html
<ul>
  <li>Envío gratis en compras superiores a $40</li>
  <li>Devoluciones dentro de 30 días</li>
  <li>Garantía de dos años</li>
</ul>

Una regla que hay que tener clara: lo único permitido como hijo directo de <ul> es <li>. No pones un <p> o un <div> directamente dentro del <ul>. Si quieres un párrafo o un enlace dentro de un elemento, va dentro del <li>, que puede contener cualquier contenido que quieras.

Las viñetas y la sangría son el estilo predeterminado del navegador. El significado vive en el elemento mismo. Cuando llegues a CSS podrás cambiarlas o quitarlas libremente, y la lista sigue siendo una lista por debajo.

Una lista no ordenada marca un conjunto de elementos cuya secuencia no es relevante. <ul> es el contenedor y cada elemento es un <li>; los únicos hijos directos permitidos de <ul> son elementos <li> (y elementos de soporte de script como <template>), así que poner un <div> suelto entre el <ul> y sus elementos es inválido y el parser no lo tratará como parte de la lista.

html
<ul>
  <li>Envío gratis en compras superiores a $40</li>
  <li>Devoluciones dentro de 30 días</li>
  <li>Garantía de dos años</li>
</ul>

El marcador de viñeta y la sangría son valores predeterminados de presentación de la hoja de estilos integrada del navegador y no tienen ningún peso semántico; list-style: none los elimina sin cambiar lo que significa el elemento. Esa separación importa porque el significado vive en el elemento, la viñeta es solo pintura. El software de asistencia (el término general para herramientas como los lectores de pantalla, que leen la página en voz alta para personas que no pueden verla) lee la estructura, no el marcador: anuncia que empieza una lista y cuántos elementos tiene. Volveremos a lo que te da ese anuncio en el Deep Dive sobre anidamiento.

JunoListas no ordenadas Usa <ul> para una lista donde el orden no importa, y envuelve cada elemento en su propio <li>. El navegador agrega las viñetas y los saltos de línea por ti, así que nunca las escribes a mano. A mí me tomó un tiempo confiar en eso, seguía queriendo agregar los puntos yo mismo.
JunoListas no ordenadas<ul> es el contenedor, y sus únicos hijos directos son elementos <li>. Cualquier cosa más elaborada, un enlace, un párrafo, va dentro del <li>, nunca suelta dentro del <ul>. Las viñetas son un estilo predeterminado que puedes cambiar después, así que elige el elemento por su significado, no por su apariencia.
JunoListas no ordenadas<ul> solo acepta <li> como hijo directo, así que un <div> suelto ahí adentro es marcado inválido. La viñeta viene de la hoja de estilos del navegador, no de la semántica, así que list-style: none quita el punto y conserva la lista. Esa distinción es justo la razón por la que un lector de pantalla puede seguir contando los elementos aunque tu CSS oculte los marcadores.

Listas ordenadas y sus atributos ​

A veces el orden es lo más importante. Los pasos de una receta, las posiciones en una carrera, instrucciones que sigues una después de otra. Para eso usas una lista ordenada, que numera los elementos por ti.

Funciona exactamente igual que una lista no ordenada, pero el contenedor es <ol> en lugar de <ul>:

html
<ol>
  <li>Precalienta el horno a 180°C</li>
  <li>Mezcla la harina y el azúcar</li>
  <li>Vierte en el molde y hornea por 25 minutos</li>
</ol>

Ahora el navegador pone 1, 2, 3 delante de los elementos en lugar de viñetas. Si más adelante agregas un paso en el medio, los números se renumeran solos. Tú nunca escribes los números, y ese es justamente el punto de usar <ol>.

Una lista ordenada es para elementos cuya secuencia tiene significado. La misma estructura que <ul>, cambiando el contenedor a <ol>, y el navegador numera cada <li> automáticamente. Como los números se generan, insertar o quitar un elemento renumera el resto sin que tengas que hacer nada.

<ol> tiene tres atributos que vale la pena conocer. start establece el número desde el que empieza la lista:

html
<ol start="4">
  <li>Bate los huevos</li>
  <li>Incorpora la harina</li>
</ol>

Esa lista va de 4 a 5. Es útil cuando una lista continúa después de que algún otro contenido la haya partido en dos.

type cambia el estilo de numeración: 1 para números (el predeterminado), A o a para letras, I o i para números romanos.

html
<ol type="a">
  <li>Reúne tus pruebas</li>
  <li>Escribe el resumen</li>
</ol>

Esa lista va con a, b en lugar de 1, 2. Y reversed cuenta hacia abajo, lo cual sirve para una cuenta regresiva o un top cinco leído de abajo hacia arriba:

html
<ol reversed>
  <li>Bronce</li>
  <li>Plata</li>
  <li>Oro</li>
</ol>

Una lista ordenada marca elementos cuya secuencia tiene significado; <ol> numera cada <li> con valores generados, así que los ordinales nunca son contenido que escribes tú y se mantienen correctos aunque los elementos se muevan.

Tres atributos controlan la numeración. start establece el primer ordinal como un entero, sin importar el estilo de visualización, de modo que start="4" en una lista con números romanos empieza en iv. type establece el estilo del marcador: 1, A, a, I, o i. reversed (un atributo booleano, lo que significa que su sola presencia es el valor, sin nada que asignarle) cuenta hacia abajo desde la cantidad de elementos hasta 1.

html
<ol type="I" start="4" reversed>
  <li>Fundamentos</li>
  <li>Lanzamiento</li>
  <li>Revisión</li>
</ol>

Hay una distinción que el estilo puede ocultar. type solo cambia cómo se dibuja el marcador; el valor que se anuncia al software de asistencia y el que usa start siempre es el entero subyacente. Así que una lista con estilo de letras sigue siendo, por debajo, las posiciones 1, 2, 3. Cuando el ordinal es parte del contenido mismo, como una cláusula legal numerada para citarla, es mejor dejar que <ol> sea el dueño del número en vez de escribirlo directamente en el texto, porque un "3." escrito a mano dentro de un <li> no se va a renumerar y un lector de pantalla lo leerá dos veces: una como el marcador generado y otra como el texto. Un control más que vale la pena conocer: el atributo value en un <li> individual anula el número de ese elemento en particular, y la lista sigue contando desde ahí.

JunoListas ordenadas y sus atributos Recurre a <ol> cuando el orden importa, como en los pasos de una receta, y el navegador numera los elementos por ti. Agrega o quita un paso y los números se arreglan solos, así que nunca escribes 1. o 2. a mano. Los mismos elementos <li> de antes, solo con un contenedor distinto.
JunoListas ordenadas y sus atributos<ol> te da tres atributos útiles: start para empezar desde un número distinto de 1, type para usar letras o números romanos en lugar de cifras, y reversed para contar hacia abajo. Todos siguen dejando que el navegador genere los números, que es justamente la razón por la que usas una lista ordenada.
JunoListas ordenadas y sus atributostype solo cambia el estilo del marcador; el valor que hay detrás, el que usa start y el que lee el software de asistencia, siempre es el entero. Así que no escribas a mano "3." dentro de un <li>, o no se va a renumerar y un lector de pantalla dirá el número dos veces. Deja que <ol> se encargue del conteo, y usa value en un solo <li> cuando necesites ajustar un elemento en particular.

Listas de descripción ​

Hay un tercer tipo de lista para cuando cada elemento es realmente un par: una palabra y su significado, una etiqueta y su valor. Un glosario es el ejemplo más claro, cada término seguido de lo que significa.

Esto es una lista de descripción, y usa tres etiquetas. <dl> envuelve todo, <dt> contiene cada término, y <dd> contiene la descripción que le corresponde:

html
<dl>
  <dt>HTML</dt>
  <dd>El lenguaje que describe la estructura de una página.</dd>
  <dt>CSS</dt>
  <dd>El lenguaje que describe cómo se ve la página.</dd>
</dl>

El navegador muestra cada descripción con sangría debajo de su término, de modo que la relación entre ambos se ve de un vistazo. Piensa en "dt" como la palabra que estás definiendo y en "dd" como la definición.

Cuando cada elemento es un emparejamiento en lugar de algo independiente, una lista de descripción funciona mejor que <ul> o <ol>. Se construye con tres elementos: <dl> es el contenedor, <dt> es un término, y <dd> es la descripción asociada a él.

html
<dl>
  <dt>Autora</dt>
  <dd>Valentina Rojas</dd>
  <dt>Publicado</dt>
  <dd>14 de marzo de 2024</dd>
  <dt>Tiempo de lectura</dt>
  <dd>6 minutos</dd>
</dl>

Ese ejemplo muestra el segundo gran uso más allá de los glosarios: metadatos de clave/valor, un conjunto de etiquetas y sus valores. La agrupación es flexible. Un <dt> puede ir seguido de varios elementos <dd> cuando un término tiene más de una descripción, y varios elementos <dt> pueden compartir un mismo <dd> cuando varios términos significan lo mismo. Recurre a un <dl> siempre que tu contenido sea naturalmente "esto, y su detalle", y recurre a <ul> o <ol> cuando los elementos existen por sí mismos.

Una lista de descripción asocia nombres con valores. <dl> es el contenedor; <dt> es un término (el nombre); <dd> es una descripción (el valor). La estructura que entienden el navegador y el software de asistencia es una secuencia de grupos, donde un grupo es uno o más elementos <dt> seguidos de uno o más elementos <dd>.

html
<dl>
  <dt>Almacenamiento</dt>
  <dt>Capacidad</dt>
  <dd>256 GB SSD</dd>

  <dt>Color</dt>
  <dd>Grafito</dd>
  <dd>Plata</dd>
</dl>

Esa flexibilidad es justamente el punto: varios términos pueden compartir una descripción, y un término puede tener varias descripciones. Hay dos usos prácticos que destacan. El primero es contenido de término y definición, como un glosario. El segundo son metadatos de clave/valor, una tabla de especificaciones o un conjunto de detalles de una publicación, donde cada etiqueta se empareja con su valor; un <dl> deja claro que "estos son pares de nombre/valor" de una forma que una pila de <div>s nunca logra. Nota la curiosidad del nombre: <dt> y <dd> históricamente significaban "definition term" y "definition description" (término de definición y descripción de definición), pero la especificación moderna los amplió deliberadamente para cubrir cualquier asociación de nombre/valor, no solo definiciones de diccionario. Si tu contenido es una lista plana de elementos equivalentes sin ningún emparejamiento, <dl> es la herramienta equivocada y <ul> es la honesta.

JunoListas de descripción Una lista de descripción es para pares: un término y su significado. Usa <dl> alrededor de todo, <dt> para cada término, y <dd> para la descripción que le sigue. Un glosario es la imagen que debes tener en mente, palabra y definición, palabra y definición.
JunoListas de descripción Recurre a <dl> cuando cada elemento es un emparejamiento, un término y su detalle o una etiqueta y su valor, y no un conjunto de elementos equivalentes. La agrupación se adapta según lo necesites: un <dt> puede tener varios <dd>, y varios <dt> pueden compartir un mismo <dd>. Los metadatos de clave/valor, como autor y fecha, son donde más se justifica su uso más allá de los glosarios.
JunoListas de descripción<dl> significa pares de nombre/valor, y la especificación amplió <dt> y <dd> más allá de las definiciones de diccionario, hacia cualquier etiqueta con su valor, así que los metadatos también entran en juego. Varios términos pueden compartir un valor y un término puede tener varios valores, algo que una pared de <div>s nunca podría expresar. Si los elementos son equivalentes y no hay nada que emparejar, eso es un <ul>, no un <dl>.

Anidamiento de listas ​

Las listas pueden ir dentro de otras listas. Un menú puede tener "Bebidas" con opciones calientes y frías debajo, y cada una de esas con sus propias opciones. Poner una lista dentro de otra se llama anidamiento.

Lo importante para hacerlo bien: la lista interna va dentro de un <li>, no suelta entre elementos. Pones todo el <ul> (o <ol>) dentro del elemento de lista al que corresponde:

html
<ul>
  <li>Bebidas
    <ul>
      <li>Café</li>
      <li>Té</li>
    </ul>
  </li>
  <li>Bocadillos</li>
</ul>

"Café" y "Té" son parte de "Bebidas", así que su pequeña lista vive dentro del elemento "Bebidas". El navegador sangra la lista interna un poco más, para que puedas ver que le pertenece al elemento de arriba.

Para mostrar que algunos elementos pertenecen a otro elemento, anidas una lista dentro de otra. La regla que mantiene esto válido: una lista anidada es hija de un <li>, nunca hija directa del <ul> u <ol> externo. La lista interna se coloca dentro del elemento al que amplía.

html
<ul>
  <li>Frutas
    <ul>
      <li>Manzanas</li>
      <li>Plátanos</li>
    </ul>
  </li>
  <li>Verduras
    <ul>
      <li>Zanahorias</li>
      <li>Espinaca</li>
    </ul>
  </li>
</ul>

Puedes mezclar tipos al anidar, un <ol> dentro de un <ul> o al revés, y anidar tan profundo como el contenido realmente lo requiera. El lugar más común donde te vas a encontrar listas anidadas en código real es un menú de navegación con submenús: una lista de nivel superior con secciones, cada una con su propia lista de páginas dentro de su <li>.

El anidamiento es la forma de expresar jerarquía: una sublista se coloca dentro del <li> al que pertenece, nunca como hija directa del <ul> u <ol> padre. Hacerlo mal (un <ul> colocado directamente dentro de otro <ul>) es inválido, y no hay garantía de que la recuperación del parser coincida con lo que tenías en mente.

El anidamiento también es donde la estructura le sirve a las personas que no pueden ver la sangría. Un lector de pantalla anuncia una lista, la cantidad de elementos que tiene, y la profundidad de anidamiento a medida que entra en cada nivel: "lista, tres elementos", luego en una sublista "lista, dos elementos", y le avisa al usuario cuando vuelve a salir. Ese comentario continuo es el equivalente no visual de la sangría que tu ojo lee sin esfuerzo, y solo existe si el anidamiento es marcado real, en lugar de elementos separados a base de espaciado.

Eso nos lleva a la prueba de honestidad para cualquier lista. Un menú de navegación (el conjunto de enlaces que lleva a un visitante de una página a otra, la fila que suele estar en la parte superior de la mayoría de los sitios) es una lista de destinos, así que el marcado semánticamente correcto es un <ul> de enlaces, normalmente dentro de un elemento <nav> que identifica esa región como navegación. Usa una lista real cuando el contenido es un conjunto de elementos relacionados, sin importar cómo el CSS lo termine haciendo ver. No uses una cuando no lo sea: fingir espacios entre bloques no relacionados envolviéndolos en <li>s para aprovechar el espaciado de las listas le dice al software de asistencia "estas tres cosas son un grupo de tres" cuando no lo son. El marcador se puede ocultar y el diseño puede ser cualquier cosa; la elección entre <ul>, <ol>, o <dl> siempre debería responder a lo que el contenido honestamente es.

JunoAnidamiento de listas Para poner una lista dentro de otra, coloca la interna dentro del <li> al que pertenece, no suelta entre elementos. El navegador la sangra para que puedas ver que forma parte del elemento de arriba. Esa regla de "dentro del <li>" es lo único que hay que recordar aquí.
JunoAnidamiento de listas Una lista anidada siempre es hija de un <li>, nunca hija directa del <ul> u <ol> externo. Puedes mezclar un <ol> dentro de un <ul> y llegar tan profundo como realmente lo requiera el contenido. Con los menús de navegación con submenús es donde más te vas a topar con esto, así que vale la pena que te acostumbres desde ahora.
JunoAnidamiento de listas Pon la sublista dentro de su <li>, porque un lector de pantalla anuncia la cantidad de elementos y la profundidad de anidamiento, y esa estructura hablada es lo que reemplaza la sangría para alguien que no puede verla. Un menú de navegación realmente es una lista de enlaces, así que márcalo como tal; no envuelvas bloques no relacionados en <li>s para aprovechar el espaciado. Deja que el elemento diga lo que el contenido honestamente es, y dale el estilo que quieras después.