PLAINFINCH learn by building

Lists

You will be able to choose and build the right kind of list for your content.

Should I use ul or ol?

Ask one question: would reordering the items change the meaning? If yes, use ol, the ordered list. Recipe steps, rankings, directions and installation steps are ordered. If no, use ul, the unordered list. Ingredients, features, tags and a bird club's list of local reserves are unordered.

Each item goes in an li. The only children allowed directly inside ul or ol are li elements, plus script and template. The bullets and numbers are default styles you can change with CSS. The element choice is about meaning, and screen readers use it to announce "list, 5 items" before the first one.

<ul>
  <li>Strong white flour</li>
  <li>Water</li>
  <li>Salt</li>
</ul>
<ol>
  <li>Mix the dough.</li>
  <li>Prove for two hours.</li>
  <li>Bake at 230&deg;C.</li>
</ol>
FigureTwo code panels side by side. The ul of bread ingredients, flour, water and salt, renders with bullets; the ol of method steps, mix, prove and bake, renders numbered 1 to 3. The question is whether reordering changes the meaning.Two code panels side by side. The ul of bread ingredients, flour, water and salt, renders with bullets; the ol of method steps, mix, prove and bake, renders numbered 1 to 3. The question is whether reordering changes the meaning.
Ask whether swapping two items would change the meaning. Ingredients can go in any order, so they sit in a ul with bullets. The baking steps cannot, so they go in an ol and the browser numbers them for you.

How do start, reversed and type change numbering?

Three attributes on ol control the numbers. The start attribute sets the first number, which helps when a list continues after a figure or a heading. The reversed attribute counts down, which suits top-ten countdowns. The type attribute picks the marker style.

Use type when the marker itself is part of the content, as in a contract that refers to clause (b) or an exam that says "answer question iv". For purely visual changes, use CSS list-style-type, which also offers many more styles, including Greek letters and Japanese numbering.

<ol reversed>
  <li>Third place: Goldcrest</li>
  <li>Second place: Wren</li>
  <li>Winner: Robin</li>
</ol>
  • start="5" begins counting at 5.
  • reversed counts down from the number of items, or from start if you set it.
  • type="1" gives numbers (the default), "a" lowercase letters, "A" uppercase letters, "i" lowercase Roman numerals and "I" uppercase Roman numerals.

What does the value attribute on li do?

In an ordered list, value on an li sets that item's number, and the items after it continue from there. Use it when a gap in numbering means something, such as legal clauses where clause 4 was repealed and clause 5 keeps its number. It has no effect inside ul.

Do not use value to work around a list split by other markup. If a recipe has a photo between steps 3 and 4, it is usually cleaner to put the photo inside step 3's li and keep one list.

<ol>
  <li>Membership is open to all.</li>
  <li>Fees are due in April.</li>
  <li value="5">Meetings are monthly.</li>
</ol>

How do I nest one list inside another?

A sublist goes inside an li, after that item's text. It never sits directly inside the parent ul or ol; the validator rejects that, and screen readers lose track of which item the sublist belongs to. You can mix types, placing an ol inside a ul item or the other way round.

Screen readers announce the nesting, saying something like "list, 2 items, nesting level 1". That helps people follow the structure, so keep nesting shallow. Three levels is a practical limit before the page becomes hard to follow by ear or by eye.

<ul>
  <li>Fruit
    <ul>
      <li>Apples</li>
      <li>Pears</li>
    </ul>
  </li>
  <li>Bread</li>
</ul>

When is a description list the right choice?

The dl element holds groups of terms and descriptions: glossaries, metadata like Author and Published, product specs, the details of an event. The dt element is the term and the dd element is the description. One term can have several descriptions, and several terms can share one description.

You may wrap each group in a single div inside the dl, which makes styling each pair as a card or grid row much easier. That div is allowed only as a direct child of dl holding dt and dd elements.

Screen reader support for dl is uneven. Some announce "description list" and the item count; others read the terms and descriptions as plain text. The structure still helps, and the content should read clearly either way.

<dl>
  <div>
    <dt>Date</dt>
    <dd><time datetime="2026-11-14">14 November</time></dd>
  </div>
  <div>
    <dt>Meet at</dt>
    <dd>Kirkstall Abbey car park</dd>
  </div>
</dl>

Why do my lists stop being announced as lists in Safari?

Setting list-style: none on a ul makes Safari with VoiceOver drop the list role. WebKit made this choice on purpose because so many sites use lists for layout. The result is that a navigation menu or a tag list styled without bullets reads as a run of separate items with no count.

If the list semantics matter, add role="list" to the ul or ol. That restores the announcement. Another fix that works in current Safari is to keep a marker but make it invisible with list-style: "" or a zero-width string, which keeps the role.

Do not add role="list" everywhere by reflex. A long list of decorative links may be easier to hear without the count. Decide based on whether knowing "8 items" helps the reader.

<ul role="list" class="tags">
  <li>Birding</li>
  <li>Walks</li>
</ul>

.tags { list-style: none; padding: 0; }

When should something be a list at all?

Use a list when you have three or more items of the same kind that a reader would scan: navigation links, features, search results, a set of cards. Wrapping site navigation in nav with a ul inside is a common, sound pattern because it gives both a landmark and an item count.

Avoid lists for a single item, for content that reads as one connected argument, or for layout alone. A row of social icons can be a list; a two-column hero with text and a photo is not. If you find yourself writing li elements that hold whole sections with headings, ask whether article or section elements would describe them better.

How do I check lists in DevTools and with a screen reader?

In the Elements panel, confirm every child of a ul or ol is an li. Stray div or a children break the structure, and Lighthouse reports them under "Lists do not contain only li elements". The Accessibility pane shows the role list and listitem; if it shows generic, the CSS reset or a framework removed it.

With NVDA, press L to jump from list to list and I to step through items. With VoiceOver, open the rotor and look for lists. Listen for the item count. If it says "list, 1 item" for a menu with six links, the generated markup put each link in its own ul.

What do AI tools commonly get wrong with lists?

Generated code often builds lists from div elements with a class like list-item, which loses the count and the navigation shortcuts. It also produces the opposite: ul around every group of two things, including form fields and footers.

Watch for sublists placed directly inside a ul rather than inside an li, ol used for unordered content because numbers looked tidy, dl with dd and no dt, and manual numbers typed into li text, as in "1. Mix", which doubles up with the browser's own markers. Each is a quick fix once you spot it in the Elements panel.

Field notes

  • Use ol when the order of items matters and ul when it does not.
  • Every item in a ul or ol goes inside an li element.
  • A nested list belongs inside an li, after that item's text.
  • A dl list pairs terms with their descriptions.

Easy to get wrong

A nested list must sit inside an li, not directly inside the parent list.

Only li elements belong directly inside ul and ol.

Typed numbers are just text. A real list is announced as a list with an item count.

Questions people ask

How do I remove bullets from a list in HTML?

Use CSS: list-style: none on the ul. Keep the ul element so the list still reads as a list.

How do I start an ordered list at a different number?

Add start to the ol, for example <ol start="4">.

Can I put a link or paragraph inside an li?

Yes. An li can hold links, paragraphs, images and nested lists.

What is the difference between dl and ul?

ul lists single items. dl pairs terms with descriptions.

Keep going