HTMLBeginner

HTML Lists In Depth: ul, ol, dl and Nesting Explained

Learn unordered, ordered and definition lists in HTML, custom numbering with type and start, nested lists, styling with CSS, and when to use each list.

All HTML lessons

What you will learn

A huge amount of real content is really a list: a menu, a set of steps, search results, a table of contents, a glossary. HTML has three dedicated list elements for this. In this lesson you will learn the unordered list, the ordered list (with custom numbering), the lesser-known definition list, how to nest lists inside each other correctly, and how to style them with CSS.

Why use a list element at all?

You could write items as separate paragraphs:

<p>Apples</p>
<p>Bananas</p>
<p>Oranges</p>

This displays as three lines, but it tells the browser nothing about the fact that these three lines are related items in one group. A list element wraps them as one structure, which matters for three reasons:

  • Screen readers announce it properly — “list with 3 items”, and let the user jump between items.
  • Styling a whole list is easy — one CSS rule can control every bullet, every number, the spacing.
  • Search engines and browsers understand the grouping, which helps things like the automatic numbering you’re about to see.

Unordered lists: <ul>

Use <ul> when the order of items does not matter — a bullet-point list. Each item goes inside an <li> (list item).

<ul>
  <li>Apples</li>
  <li>Bananas</li>
  <li>Oranges</li>
</ul>

By default, the browser draws a round bullet (•) before each item. Use <ul> for things like a grocery list, a set of features, or a navigation menu, where reordering the items would not change their meaning.

Changing the bullet style with CSS

ul {
  list-style-type: disc;   /* default: filled circle */
}

ul.squares {
  list-style-type: square;
}

ul.no-bullets {
  list-style-type: none;   /* removes bullets entirely, common for nav menus */
}
<ul class="no-bullets">
  <li>Home</li>
  <li>About</li>
  <li>Contact</li>
</ul>

list-style-type: none is exactly how a navigation bar’s <ul> ends up with no bullets at all — the semantic list stays, only the visual marker goes away.

Ordered lists: <ol>

Use <ol> when the sequence matters — steps in a recipe, a ranking, instructions that must happen in order.

<ol>
  <li>Preheat the oven</li>
  <li>Mix the ingredients</li>
  <li>Bake for 30 minutes</li>
</ol>

The browser numbers the items automatically: 1, 2, 3. If you insert or remove an <li>, every number after it updates by itself — you never type the numbers yourself.

Controlling the numbering

type changes the marker style:

type value Result
"1" 1, 2, 3, ... (default)
"A" A, B, C, ...
"a" a, b, c, ...
"I" I, II, III, ... (uppercase Roman)
"i" i, ii, iii, ... (lowercase Roman)
<ol type="I">
  <li>Introduction</li>
  <li>Methodology</li>
  <li>Conclusion</li>
</ol>

start changes the number the list begins counting from:

<ol start="5">
  <li>Fifth item</li>
  <li>Sixth item</li>
</ol>

reversed counts backwards:

<ol reversed>
  <li>Third place</li>
  <li>Second place</li>
  <li>First place</li>
</ol>

value on a single <li> jumps that one item to a specific number, and every item after it continues counting from there:

<ol type="I">
  <li value="3">Third item</li>
  <li>Fourth item</li>
  <li>Fifth item</li>
</ol>

This prints III, IV, V — the value="3" re-starts the count at 3, and the rest keep counting up normally. This is handy for a numbered list that continues after some other content interrupts it (like a code block breaking up a set of steps).

Definition lists: <dl>

This is the list beginners forget about, and it is genuinely useful. A definition list pairs a term with its description — perfect for a glossary, an FAQ, or a set of labelled details (like a spec sheet).

<dl>
  <dt>HTML</dt>
  <dd>The language used to structure the content of a web page.</dd>

  <dt>CSS</dt>
  <dd>The language used to style how a web page looks.</dd>

  <dt>JavaScript</dt>
  <dd>The scripting language that adds interactivity to a web page.</dd>
</dl>
  • <dl> — definition list: wraps the whole group.
  • <dt> — definition term: the word or phrase being defined.
  • <dd> — definition description: the explanation, indented by the browser by default.

A term can have more than one description, and a description can follow more than one term:

<dl>
  <dt>HTML</dt>
  <dt>HyperText Markup Language</dt>
  <dd>The standard language for creating the structure of web pages.</dd>

  <dt>Frontend</dt>
  <dt>Front-end</dt>
  <dd>The part of a website users see and interact with directly.</dd>
</dl>

Use <dl> whenever content is naturally a set of name–value pairs: a glossary, a key-value spec sheet (“Weight: 2kg”, “Colour: Black”), or an FAQ where you want the question and answer to be structurally linked, not just two separate paragraphs.

Nesting lists

A list item can contain another whole list. This is how sub-menus, outlines and category trees are built.

<ul>
  <li>
    Fruits
    <ul>
      <li>Apple</li>
      <li>Banana</li>
      <li>Orange</li>
    </ul>
  </li>
  <li>
    Vegetables
    <ul>
      <li>Carrot</li>
      <li>Spinach</li>
    </ul>
  </li>
</ul>

The inner <ul> goes inside the <li> it belongs to, after the text label (“Fruits”, “Vegetables”). Read it carefully: the nested list is a child of the <li>, not a sibling of it.

You can nest an <ol> inside a <ul> (or the other way around) whenever that mix makes sense:

<ul>
  <li>
    Frontend Technologies
    <ol>
      <li>HTML</li>
      <li>CSS</li>
      <li>JavaScript</li>
    </ol>
  </li>
  <li>
    Backend Technologies
    <ol>
      <li>Node.js</li>
      <li>Express.js</li>
      <li>MongoDB</li>
    </ol>
  </li>
</ul>

Here the outer list (categories) does not have a natural order, so it is a <ul>. The inner lists (a learning path within each category) do have an order, so they are <ol>.

Definition lists can nest too, by putting a whole <dl> inside a <dd>:

<dl>
  <dt>Frontend</dt>
  <dd>
    <dl>
      <dt>HTML</dt>
      <dd>Structures the page.</dd>
      <dt>CSS</dt>
      <dd>Styles the page.</dd>
    </dl>
  </dd>
</dl>

Indent nested lists so they’re readable

Nesting quickly gets hard to read if you don’t indent consistently. Always indent the inner list by two spaces, matching the pattern from the nesting lesson:

<ul>
  <li>
    Level 1
    <ul>
      <li>
        Level 2
        <ul>
          <li>Level 3</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

Three levels deep is usually the practical limit — beyond that, consider whether the content might read better as separate sections instead.

Which list should you use? A quick guide

Situation Use
Grocery list, feature list, tags <ul>
Steps, rankings, instructions <ol>
Glossary, FAQ, spec sheet (term + meaning) <dl>
Navigation menu <ul> (styled with list-style-type: none)
Sub-categories or an outline Nested <ul> / <ol>

Common mistakes

  • Using <br> or separate paragraphs to fake a list. Always use <ul>, <ol> or <dl> — it is both more meaningful and easier to style.

  • Putting text directly inside <ul> or <ol>, not inside an <li>. Every item must be wrapped in its own <li>.

  • Forgetting to close <li>. A missing closing tag can pull the rest of the list — or the whole page — into the wrong item.

  • Nesting the inner <ul> as a sibling of <li>, instead of inside it. This breaks the semantic relationship between the parent item and its sub-list:

    <!-- Wrong: the nested list is not inside the li -->
    <ul>
      <li>Fruits</li>
      <ul>
        <li>Apple</li>
      </ul>
    </ul>
    
    <!-- Right -->
    <ul>
      <li>
        Fruits
        <ul>
          <li>Apple</li>
        </ul>
      </li>
    </ul>
  • Using <dl> for something that is not really a term/description pair. If the items don’t naturally pair up as “name” and “value”, a <ul> fits better.

  • Manually typing numbers inside <li> text, like <li>1. Preheat the oven</li> inside an <ol>. The browser already numbers ordered lists — typing your own creates double numbering and breaks if you reorder items.

  • Removing bullets with list-style-type: none and forgetting it is still a list. This is fine and common (menus do it constantly) — just remember screen readers still announce it as a list, which is exactly the point.

Interview-style questions

When would you use <ol> instead of <ul>? When the sequence of items matters — like steps in a recipe or a ranking — since <ol> numbers items automatically and communicates that order to the reader.

What is a definition list used for? Pairing a term with its description, such as a glossary or an FAQ, using <dl>, <dt> and <dd>.

How do you make an ordered list count down instead of up? Add the reversed attribute to the <ol>.

How do you nest a list correctly? Place the inner <ul> or <ol> inside the <li> of the outer list, after that item’s text — not as a sibling of the <li>.

Practice

  1. Use the Practice in Editor button. Change the shopping list’s bullet style to square, then remove the bullets entirely with list-style-type: none.

  2. Turn the recipe steps into a Roman-numeral list starting from step 5 using type and start.

  3. Add two more terms to the glossary <dl>, each with its own description.

  4. Build a two-level nested list of your own: a <ul> of two hobby categories, each containing an <ol> of steps to get started in that hobby.

  5. Fix this code (it has two mistakes: text outside an <li>, and a nested list placed as a sibling instead of inside the <li>):

    <ul>
      <li>Fruits</li>
      <ul>
        <li>Apple</li>
        <li>Banana</li>
      </ul>
      Notes about fruit
    </ul>

Recap

  • <ul> is for lists where order doesn’t matter; <ol> is for lists where it does.
  • Every list item goes inside an <li>, whether the parent is <ul> or <ol>.
  • <ol> accepts type (numbering style), start (starting number), reversed, and a per-item value.
  • <dl> pairs a <dt> (term) with one or more <dd> (descriptions) — perfect for glossaries and FAQs.
  • Nest a list by placing the inner <ul>/<ol> inside the relevant <li>, not next to it.
  • CSS list-style-type controls the bullet or number style, including removing it entirely with none.