Lists
Lists are used to present a series of items in a specific order. They can be used to display a list of items, a list of tasks, or a list of options. Lists can be used inside content blocks like cards, paragraphs, or even inside other lists. They can also be nested lists inside each list item.
Unordered Lists
Unordered lists are used to present a list of items in no particular order. They can be used to display a list of items, a list of tasks, or a list of options.
An example of a bullet list is given below. You can see how the list items work with these particular items.
- Item 1 is really long and should be wrapped. You can see how the wrapping works with this particular item.
- Item 2
- Item 3
- Item 4
- Item 5
- Item 6
<div class="text-base text-zinc-900 md:text-lg dark:text-gray-100"> <p class="text-md mx-4 mb-6 w-full max-w-2xl text-start leading-normal"> An example of a bullet list is given below. You can see how the list items work with these particular items. </p> <ul class="mx-10 mb-6 max-w-2xl list-outside list-disc space-y-2 marker:text-zinc-500" > <li> Item 1 is really long and should be wrapped. You can see how the wrapping works with this particular item. </li> <li>Item 2</li> <li>Item 3</li> <li>Item 4</li> <li>Item 5</li> <li>Item 6</li> </ul></div>
---interface Props { description: string; listItems: string[];}
const { description, listItems } = Astro.props as Props;
/** Usage in an Astro component: * --- import Ulist from './Ulist.astro'; const list = ['Item 1', 'Item 2', 'Item 3']; const description = 'Your description here'; ---
<Ulist description={description} listItems={list} />
**/---
<div class="text-base text-zinc-900 md:text-lg dark:text-gray-100"> <p class="text-md mx-4 mb-6 w-full max-w-2xl text-start leading-normal"> {description} </p> <ul class="mx-10 mb-6 max-w-2xl list-outside list-disc space-y-2 marker:text-zinc-500" > {listItems.map((item) => <li>{item}</li>)} </ul></div>
Ordered Lists
Ordered lists are great for presenting a series of items in a particular order. It’s a great way to organize information which needs to be presented in a step-by-step manner.
An example of a bullet list is given below. You can see how the list items work with these particular items.
-
Item 1 is really long and should be wrapped. You can see how the wrapping works with this particular item.
Item 2
Item 3
Item 4
Item 5
Item 6
<div class="text-base text-zinc-900 md:text-lg dark:text-gray-100"> <p class="text-md mx-4 mb-6 w-full max-w-2xl text-start leading-normal"> An example of a bullet list is given below. You can see how the list items work with these particular items. </p> <ol class="mx-10 mb-6 max-w-2xl list-outside list-decimal space-y-2 marker:text-zinc-700 dark:marker:text-gray-100" > <li> <p class="ml-2"> Item 1 is really long and should be wrapped. You can see how the wrapping works with this particular item. </p> </li> <li><p class="ml-2">Item 2</p></li> <li><p class="ml-2">Item 3</p></li> <li><p class="ml-2">Item 4</p></li> <li><p class="ml-2">Item 5</p></li> <li><p class="ml-2">Item 6</p></li> </ol></div>
---interface Props { description: string; listItems: string[];}
const { description, listItems } = Astro.props as Props;
/** Usage in an Astro component: --- import Olist from './Ulist.astro'; const list = ['Item 1', 'Item 2', 'Item 3']; const description = 'Your description here'; --- <Olist description={description} listItems={list} />**/---
<div class="text-base text-zinc-900 md:text-lg dark:text-gray-100"> <p class="text-md mx-4 mb-6 w-full max-w-2xl text-start leading-normal"> {description} </p> <ol class="mx-10 mb-6 max-w-2xl list-outside list-decimal space-y-2 marker:text-zinc-700 dark:marker:text-gray-100" > { listItems.map((item) => ( <li> <p class="ml-2">{item}</p> </li> )) } </ol></div>
Custom Marked Lists
A custom list marker adds an svg inline in the list. Useful for adding a custom icon to the list.
List
- Item 1 is really long and should be wrapped. You can see how the it works with this particular item.
- Item 2
- Item 3
<div class="text-base text-zinc-900 md:text-lg dark:text-gray-100"> <p class="text-md mx-4 mb-6 w-full max-w-2xl text-start leading-normal"> List </p> <ul class="mx-4 mb-6 max-w-2xl list-outside list-none space-y-3"> <li class="flex flex-row items-start leading-snug"> <svg xmlns="http://www.w3.org/2000/svg" width="24" role="img" height="24" viewBox="0 0 24 24" class="mr-3 flex-shrink-0 text-green-700 dark:text-green-400" aria-labelledby="title-list-item-1" > <title id="title-list-item-1">Tick</title> <path fill="currentColor" d="M9 16.17L4.83 12l-1.42 1.41L9 19L21 7l-1.41-1.41z"></path> </svg> <span >Item 1 is really long and should be wrapped. You can see how the it works with this particular item.</span > </li> <li class="flex flex-row items-start leading-snug"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" role="img" viewBox="0 0 24 24" class="mr-3 flex-shrink-0 text-red-700 dark:text-red-500" aria-labelledby="title-list-item-2" > <title id="title-list-item-2">Cross</title> <path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z" ></path> </svg> <span>Item 2</span> </li><li class="flex flex-row items-start leading-snug"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" class="mr-3 flex-shrink-0 text-green-700 dark:text-green-400" aria-labelledby="title-list-item-3" > <title id="title-list-item-3">Tick</title> <path fill="currentColor" d="M9 16.17L4.83 12l-1.42 1.41L9 19L21 7l-1.41-1.41z"></path> </svg> <span>Item 3</span> </li> </ul></div>
---const generateUniqueId = () => { const timestamp = Date.now().toString().slice(-6); const randomNum = Math.floor(Math.random() * 10000) .toString() .padStart(4, "0"); return timestamp + randomNum;};
const componentId = generateUniqueId();// The above code generates a unique ID for the component for ARIA attributes. The above code can be delegated to a global component which will return the unqiue ID.interface Props { description: string; list: Array<{ listItem: string; type: "tick" | "cross" | string }>;}// You can add more types of list markers if you want based on your use case by adding them to the type property.
const { description, list } = Astro.props as Props;/** Usage in an Astro component: --- import Clist from './Ulist.astro'; const list = [ { listItem: 'Item 1 is really long and should be wrapped. You can see how the wrapping works with this particular item.', type: 'tick' }, { listItem: 'Item 2', type: 'cross' }, { listItem: 'Item 3', type: 'tick' }, ] const description = 'Your description here'; --- <Clist description={description} list={list} />**/---
<div class="text-base text-zinc-900 md:text-lg dark:text-gray-100"> <p class="text-md mx-4 my-6 w-full max-w-2xl text-start leading-normal"> {description} </p> <ul class="mx-4 mb-6 max-w-2xl list-outside list-none space-y-3"> { list.map((item, index) => ( <li class="flex flex-row items-start leading-snug"> {item.type === "tick" && ( <svg xmlns="http://www.w3.org/2000/svg" width="24" role="img" height="24" viewBox="0 0 24 24" class="mr-3 flex-shrink-0 text-green-700 dark:text-green-400" aria-labelledby={`${componentId}-item-${index}`} > <title id={`${componentId}-item-${index}`}>{item.type}</title> <path fill="currentColor" d="M9 16.17L4.83 12l-1.42 1.41L9 19L21 7l-1.41-1.41z" /> </svg> )} {item.type === "cross" && ( <svg xmlns="http://www.w3.org/2000/svg" width="24" role="img" height="24" viewBox="0 0 24 24" class="mr-3 flex-shrink-0 text-red-700 dark:text-red-500" aria-labelledby={`${componentId}-item-${index}`} > <title id={`${componentId}-item-${index}`}>{item.type}</title> <path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z" /> </svg> )} <span>{item.listItem}</span> </li> )) } </ul></div>
Accessibility Testing Status
Component | NVDA | Windows Narrator | WAVE | Axe | IBM Equal Access |
---|---|---|---|---|---|
Unordered List | Yes | Yes | Yes | Yes | Yes |
Ordered List | Yes | Yes | Yes | Yes | Yes |
Custom Marked List | Yes | Yes | Yes | Yes | Yes |
Since we use the <ul>
element for the unordered list and <ol>
element for the ordered list, the component is accessible out of the box. However, the custom list marker uses an accessible <svg>
element by giving it the role of img
and aria-labelled by title
.