Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to make a nested list

Short answer

Put a new list inside an <li> item — after its text:

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

The browser shifts the nested list right and changes the marker on its own: disc, circle, square.

Custom markers per level

Each level's marker is set with a descendant selector:

<style>
  ul { list-style-type: square; }
  ul ul { list-style-type: "– "; }
</style>
 
<ul>
  <li>Drinks
    <ul><li>Tea</li><li>Coffee</li></ul>
  </li>
</ul>

1.1, 1.2 numbering

Multilevel numbers, as in documents, are built on CSS counters and the counters() function:

<style>
  ol { counter-reset: item; list-style: none; }
  li::before { counter-increment: item; content: counters(item, ".") ". "; }
</style>
 
<ol>
  <li>Setup
    <ol><li>Download</li><li>Install</li></ol>
  </li>
  <li>Usage</li>
</ol>

Common mistake

The nested <ul> is placed between two <li> elements instead of inside an item. Only <li> elements are allowed directly inside a list, so the markup is invalid, and a screen reader does not know which item the sublist belongs to:

<ul>
  <li>Fruit</li>
  <ul><li>Apples</li></ul>
</ul>

Functions used in this recipe

  • <ul> — A bulleted list: items whose order does not matter.
  • <ol> — A numbered list: items whose order matters.
  • <li> — An item of a `<ul>`, `<ol>` or `<menu>` list.
  • list-style — The look of list markers: their type, position and image.
  • content — The content of the `::before` and `::after` pseudo-elements.

Thanks for reading!

Donate to the site — we work hard for you.