Estilo de la lista de creatividades

Una mirada a algunas formas útiles y creativas de aplicar diseño a una lista.

Michelle Barker
Michelle Barker

¿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.

Una lista de compras de artículos como pan, leche y manzanas.

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.

Una lista en la que se detallan los pasos necesarios para preparar té con leche.

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.

Una lista de esquemas de página en columnas con un elemento que abarca las columnas en la mitad.

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.

Una demostración de cómo se divide el contenido entre dos columnas.

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