Una mirada a algunas formas útiles y creativas de aplicar diseño a una lista.
¿Qué te viene a la mente cuando piensas en una lista? El ejemplo más obvio es una lista de compras, la más simple de las listas, una colección de elementos sin un orden en particular. Sin embargo, usamos listas de todo tipo en la Web. ¿Una colección de próximos conciertos en un lugar? Es muy probable que sea una lista. ¿Un proceso de reserva de varios pasos? Probablemente sea una lista. ¿Una galería de imágenes? Incluso eso podría considerarse una lista de imágenes con leyendas.
En este artículo, analizaremos los diferentes tipos de listas HTML disponibles en la Web y cuándo usarlos, incluidos algunos atributos que quizás no conozcas. También veremos algunas formas útiles y creativas de aplicarles diseño con CSS.
Cuándo usar una lista
Se debe usar un elemento de lista HTML cuando los elementos se deben agrupar semánticamente. Las tecnologías de accesibilidad (como los lectores de pantalla) le notificarán al usuario que hay una lista y la cantidad de elementos. Si piensas, por ejemplo, en una cuadrícula de productos en un sitio de compras, sería muy útil conocer esta información. Por lo tanto, usar un elemento de lista podría ser una buena opción.
Mostrar lista de tipos
En lo que respecta al marcado, tenemos tres elementos de lista diferentes disponibles:
- Lista sin ordenar
- Lista ordenada
- Lista de descripciones
La elección depende del caso de uso.
Lista sin ordenar (ul)
El elemento de lista sin ordenar (<ul>
) es más útil cuando los elementos de la lista no corresponden a ningún orden en particular. De forma predeterminada, se mostrará como una lista con viñetas. Un ejemplo es una lista de compras, en la que el orden no importa.
Un ejemplo más común en la Web es un menú de navegación. Cuando crees un menú, te recomendamos que unas el ul
en un elemento nav
y que identifiques el menú con una etiqueta para ayudar a las tecnologías de accesibilidad. También deberíamos identificar la página actual en el menú, lo que podemos hacer con el atributo aria-current
:
<nav aria-label="Main">
<ul>
<li>
<a href="/page-1" aria-current="page">Menu item 1</a>
</li>
<li>
<a href="/page-2">Menu item 2</a>
</li>
<li>
<a href="/page-2">Menu item 2</a>
</li>
…
</ul>
</nav>
En este artículo sobre la estructura de los menús, se describen varias recomendaciones para garantizar que todos puedan acceder a nuestros menús de navegación.
Lista ordenada (ol)
Un elemento de lista ordenada (<ol>
) es la mejor opción cuando el orden de los elementos es importante, como un proceso de varios pasos. De forma predeterminada, los elementos de la lista se numeran. Un ejemplo podría ser un conjunto de instrucciones en el que se deben completar los pasos en orden.
Tanto los elementos <ol>
como <ul>
solo pueden contener elementos <li>
como elementos secundarios directos.
Lista de descripciones (dl)
Una lista de descripciones contiene términos (elementos <dt>
) y descripciones (<dd>
). Cada término puede ir acompañado de más de una descripción. Los posibles casos de uso podrían incluir un glosario de términos o, tal vez, el menú de un restaurante. De forma predeterminada, las listas de descripciones no se muestran con ningún marcador, aunque los navegadores suelen indentar el elemento <dd>
.
En HTML, se permite agrupar términos con sus descripciones correspondientes mediante un <div>
. Esto puede ser útil para aplicar diseño, como veremos más adelante.
<!-- This is valid -->
<dl>
<dt>Term 1</dt>
<dd>This is the first description of the first term in the list</dd>
<dd>This is the second description of the first term in the list</dd>
<dt>Term 2</dt>
<dd>This is the description of the second term in the list</dd>
</dl>
<!-- This is also valid -->
<dl>
<div>
<dt>Term 1</dt>
<dd>This is the first description of the first term in the list</dd>
<dd>This is the second description of the first term in the list</dd>
</div>
<div>
<dt>Term 2</dt>
<dd>This is the description of the second term in the list</dd>
</div>
</dl>
Aplica diseño de lista simple
Uno de los usos más simples de una lista es dentro de un bloque de texto del cuerpo. Con mucha frecuencia, estas listas simples no necesitan un estilo elaborado, pero es posible que queramos personalizar los marcadores de una lista ordenada o desordenada hasta cierto punto, por ejemplo, con un color de marca o usando una imagen personalizada para nuestras viñetas. Podemos hacer mucho con list-style
y el pseudoelemento ::marker
.
::marker
Además de aplicar un estilo básico a los marcadores de lista, podemos crear viñetas cíclicas. Aquí, usamos tres URLs de imagen diferentes para el valor content
del pseudoelemento ::marker
, lo que agrega la sensación de estar escrito a mano a nuestro ejemplo de lista de compras (en lugar de usar una sola imagen para todo):
::marker {
content: url("/marker-1.svg") ' ';
}
li:nth-child(3n)::marker {
content: url("/marker-2.svg") ' ';
}
li:nth-child(3n - 1)::marker {
content: url("/marker-3.svg") ' ';
}
Contadores personalizados
Para algunas listas ordenadas, es posible que deseemos usar el valor del contador, pero agregarle otro valor. Podemos usar el contador list-item
como valor para la propiedad content
de nuestro marcador y adjuntar cualquier otro contenido:
::marker {
content: counter(list-item) '🐈 ';
}
Nuestros contadores aumentan automáticamente en uno, pero podemos permitir que aumenten en un valor diferente si lo deseamos. Para ello, configura la propiedad counter-increment
en el elemento de la lista. Por ejemplo, esto incrementará nuestros contadores en tres cada vez:
li {
counter-increment: list-item 3;
}
Hay mucho más que podríamos analizar con los contadores. En el artículo Listas, marcadores y contadores de CSS, se explican algunas de las posibilidades con más detalle.
Limitaciones del diseño de ::marker
A veces, es posible que deseemos tener más control sobre la posición y el estilo de nuestros marcadores. Por ejemplo, no es posible posicionar el marcador con flexbox o cuadrícula, lo que puede ser una desventaja si necesitas alguna otra alineación. ::marker
expone una cantidad limitada de propiedades CSS para aplicar estilos. Si nuestro diseño requiere algo más que un estilo básico, es mejor usar otro pseudoelemento.
Aplica diseño a listas que no parecen listas
A veces, es posible que deseemos aplicar un diseño a nuestras listas de una manera totalmente diferente del diseño predeterminado. Este suele ser el caso de un menú de navegación, por ejemplo, en el que generalmente queremos quitar todos los marcadores y mostrar nuestra lista horizontalmente con flexbox. Una práctica común es establecer la propiedad list-style
en none
. Esto significa que ya no se podrá acceder al pseudoelemento de marcador en el DOM.
Marcadores personalizados con ::before
Aplicar diseño al pseudoelemento ::before
era una forma común de crear marcadores de listas personalizadas antes de que apareciera ::marker
. Pero, incluso ahora, puede permitirnos tener más flexibilidad, cuando la necesitemos, para aplicar diseños de listas visualmente complejos.
Al igual que con ::marker
, podemos agregar nuestros propios estilos de viñetas personalizados con el atributo content
. A diferencia del uso de ::marker
, debemos realizar un posicionamiento manual, ya que no obtenemos los beneficios automáticos que ofrece list-style-position
. Sin embargo, podemos ubicarlo con bastante facilidad en flexbox, lo que abre una gran cantidad de posibilidades de alineación. Por ejemplo, podríamos alternar la posición del marcador:
Si aplicamos diseño a una lista ordenada con el elemento ::before
, también es posible que deseemos usar contadores para agregar nuestros marcadores numéricos.
li::before {
counter-increment: list-item;
content: counter(list-item);
}
El uso de ::before
en lugar de ::marker
nos permite tener acceso completo a las propiedades de CSS para aplicar estilos personalizados, así como permitir animaciones y transiciones, para las que la compatibilidad es limitada en ::marker
.
Enumera los atributos
Los elementos de listas ordenadas aceptan algunos atributos opcionales, que pueden ayudarnos en una variedad de casos de uso.
Listas inversas
Si tenemos una lista de los 10 mejores álbumes del año pasado, podríamos contar con una cuenta regresiva del 10 al 1. Podríamos usar contadores personalizados para eso y aumentarlos de forma negativa. O bien, simplemente podríamos usar el atributo reversed
en el código HTML. En general, tiene sentido semántico usar el atributo reversed
en lugar de incrementar negativamente el contador en CSS, a menos que los contadores sean puramente de presentación. Si no se carga el CSS, seguirás viendo los números contando hacia abajo correctamente en el código HTML. Además, debemos considerar cómo interpretaría la lista un lector de pantalla.
Mira esta demostración de los 10 álbumes más populares de 2021. Si los contadores se incrementaron únicamente con CSS, alguien que acceda a la página con un lector de pantalla podría concluir que los números se contaron de forma ascendente, por lo que el número 10 en realidad era el número uno.
En la demostración, puedes ver que, cuando usamos el atributo reversed
, nuestros marcadores ya tienen el valor correcto, sin ningún esfuerzo adicional de nuestra parte. Sin embargo, si creamos marcadores de listas personalizadas con el pseudoelemento ::before
, debemos ajustar nuestros contadores. Solo necesitamos indicarle a nuestro contador de elementos de lista que aumente de forma negativa:
li::before {
counter-increment: list-item -1;
content: counter(list-item);
}
Esto será suficiente en Firefox, pero en Chrome y Safari, los marcadores contarán desde cero hasta -10. Para solucionarlo, agregamos el atributo start
a la lista.
Cómo dividir listas
El atributo start
nos permite especificar el valor numérico con el que debe comenzar la lista. Una forma en que esto puede ser útil es cuando deseas dividir una lista en grupos.
Reforzamos nuestro ejemplo de los 10 álbumes principales. Quizás queremos ver la cuenta regresiva de los mejores 20 álbumes, pero en grupos de 10. Entre los dos grupos, hay otro contenido de la página.
Tendremos que crear dos listas separadas en nuestro código HTML, pero ¿cómo podemos asegurarnos de que los contadores sean correctos? Con nuestro marcado actual, ambas listas contarán desde 10 hasta 1, lo que no es lo que queremos. Sin embargo, en nuestro código HTML, podemos especificar un valor de atributo start
. Si agregamos un valor de start
de 20 a nuestra primera lista, los marcadores se actualizarán nuevamente automáticamente.
<ol reversed start="20">
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
Diseño de lista de varias columnas
El diseño de varias columnas puede ser adecuado para nuestras listas, como puedes ver en las demostraciones anteriores. Si configuramos un ancho de columna, podemos asegurarnos de que nuestra lista sea responsiva automáticamente y se extienda en dos o más columnas solo cuando haya espacio suficiente. También podemos establecer un espacio entre las columnas y, para agregar un elemento decorativo adicional, agregar una column-rule con diseño (con una abreviatura similar a la propiedad border
):
ol {
columns: 25rem;
column-gap: 7rem;
column-rule: 4px dotted turquoise;
}
Cuando usamos columnas, a veces podemos terminar con pausas poco atractivas en los elementos de la lista, lo que no siempre es el efecto que queremos.
Podemos evitar estas pausas forzadas con break-inside: avoid
en nuestros elementos de lista:
li {
break-inside: avoid;
}
Propiedades personalizadas
Las propiedades personalizadas de CSS abren una gran variedad de posibilidades para aplicar estilos a las listas. Si conocemos el índice del elemento de la lista, podemos usarlo para calcular los valores de la propiedad. Lamentablemente, en la actualidad, no hay forma de determinar el índice del elemento (de una manera utilizable, en cualquier caso) solo en CSS. Los contadores solo nos permiten usar su valor en la propiedad content
y no permiten cálculos.
Sin embargo, podemos establecer el índice del elemento dentro del atributo style
en nuestro código HTML, lo que puede hacer que los cálculos sean más factibles, en especial si usamos un lenguaje de plantillas. En este ejemplo, se muestra cómo lo configuraríamos con Nunjucks:
<ol style="--length: items|length">
</ol>
Splitting.js es una biblioteca que realiza una función similar en el lado del cliente.
Con el valor de la propiedad personalizada, podemos mostrar la progresión a través de una lista de varias maneras. Una forma podría ser una barra de progreso para una lista de pasos. En este ejemplo, usamos un seudoelemento con un gradiente lineal para crear una barra para cada elemento que muestra qué tan avanzado está el usuario en la lista.
li::before {
--stop: calc(100% / var(--length) * var(--i));
--color1: deeppink;
--color2: pink;
content: '';
background: linear-gradient(to right, var(--color1) var(--stop), var(--color2) 0);
}
También podríamos ajustar el tono a medida que avanza la lista con la función de color hsl()
. Podemos calcular el valor hue
con nuestra propiedad personalizada.
Estilo de la lista de descripciones
Como se mencionó antes, podemos elegir unir los términos y sus definiciones dentro de una div
en una dl
para brindarnos más opciones de estilo. Por ejemplo, es posible que deseemos mostrar nuestra lista como una cuadrícula. Si estableces display: grid
en la lista sin un wrapper div
alrededor de cada grupo, nuestros términos y descripciones se colocarán en diferentes celdas de la cuadrícula. A veces, esto es útil, como en el siguiente ejemplo, que muestra un menú de tartas con sus descripciones.
Podemos definir una cuadrícula en la lista y asegurarnos de que los términos y las descripciones siempre se alineen en columnas, con el ancho de la columna determinado por el término más largo.
Por otro lado, si queremos agrupar términos de forma clara con sus descripciones en formato de tarjeta, un wrapper <div>
es muy útil.
Recursos
- Listas: Una introducción a las listas y ::marker
- Marcadores personalizados con ::marker
- Listas de CSS con contadores