Build ordered, unordered and nested lists for menus and steps
Look at almost any business page and you will find lists everywhere, even where they are not marked up as lists. A menu of services. Steps to place an order. Opening hours. Frequently asked questions.
Writing those as loose paragraphs works visually and throws away the structure. A list tells the browser, and anyone using a screen reader, "these things belong together, and there are five of them" — which is announced before the first item is read.
HTML has three kinds, and choosing between them is a question about meaning, not appearance.
Words in this lesson
| Word | What it means, in plain English |
|---|---|
<ul> | Unordered list — the order of items doesn't matter. |
<ol> | Ordered list — the order is part of the meaning. |
<li> | One item inside a list. |
<dl> / <dt> / <dd> | Description list: terms and their descriptions. |
| Nesting | A list inside a list item, for sub-points. |
Unordered lists: order does not matter
<ul>
<li>Bespoke suits</li>
<li>Alterations and repairs</li>
<li>Aso-ebi for groups</li>
<li>School uniforms</li>
</ul>
<ul> wraps the list, <li> wraps each item. The browser draws bullets.
Use it when shuffling the items would change nothing: a list of services, a set of features, ingredients you need.
Ordered lists: order matters
<ol>
<li>Send us a message with your date and headcount</li>
<li>We confirm the price and take a deposit</li>
<li>Come in for measurements</li>
<li>Collect your finished garment</li>
</ol>
Same structure, different wrapper. The browser numbers them.
Use it when the sequence is part of the meaning: steps, directions, rankings, a procedure.
Choose by meaning, not by whether you want numbers. If you want numbers on a list whose order is irrelevant, that is a CSS decision later. If the order genuinely matters, <ol> says so even to somebody who cannot see the numbers.
The rule people break
Only <li> may be a direct child of <ul> or <ol>.
Nothing else. Not a paragraph, not a heading, not a stray <div>:
<ul>
<p>Our services:</p>
<li>Bespoke suits</li>
</ul>
That is broken. The introduction belongs before the list:
<p>Our services:</p>
<ul>
<li>Bespoke suits</li>
</ul>
You can put whatever you like inside an <li> — paragraphs, images, links, another list. The restriction is only on what sits directly inside the <ul> or <ol>.
Nesting
This is where the rule above earns its keep. A nested list goes inside an <li>, not between two of them:
<ol>
<li>Remove the skin from the garlic, and chop coarsely.</li>
<li>Remove all the seeds and stalk from the pepper, and chop coarsely.</li>
<li>Add all the ingredients into a food processor.</li>
<li>
Process all the ingredients into a paste.
<ul>
<li>If you want a coarse "chunky" hummus, process it for a short time.</li>
<li>If you want a smooth hummus, process it for a longer time.</li>
</ul>
</li>
</ol>
Read the fourth item carefully. The <ul> sits inside that <li>, after its text, and the <li> closes after the nested list. That is what makes the sub-points belong to step four rather than floating loose in the sequence.
Get this wrong:
<ol>
<li>Process all the ingredients into a paste.</li>
<ul>
<li>Short time for chunky.</li>
</ul>
</ol>
The <ul> is now a direct child of the <ol>, which is not allowed. It will often look right, which is exactly why it survives in so many pages.
Indentation is how you keep this visible. Every nested level moves two spaces right, and the closing tags line up under their openers.
Description lists: terms and their descriptions
The third kind, and the one almost nobody uses — which is a pity, because it fits a lot of real content.
<dl>
<dt>Bespoke suit</dt>
<dd>Cut to your measurements from your chosen fabric. Two fittings included.</dd>
<dt>Alterations</dt>
<dd>Taking in, letting out, hemming and zip replacement.</dd>
<dt>Aso-ebi</dt>
<dd>Group orders of five or more, sewn to one design.</dd>
</dl>
<dl> wraps the whole thing, <dt> is the term, <dd> is its description.
A single term may have more than one description — just put several <dd> elements after the <dt>:
<dl>
<dt>Opening hours</dt>
<dd>Monday to Friday, 8am to 6pm</dd>
<dd>Saturday, 9am to 4pm</dd>
<dd>Closed Sunday</dd>
</dl>
Good fits for a small business page: a glossary, opening hours, an FAQ where <dt> is the question and <dd> is the answer, or a specification list.
Choosing between the three
| Content | Element |
|---|---|
| Services, features, anything unordered | <ul> |
| Steps, directions, a ranking | <ol> |
| Terms with descriptions, questions with answers | <dl> |
Ask yourself: would reordering these change the meaning? Yes means <ol>. No means <ul>. And if each item is really a pair — a name and an explanation — it is <dl>.
Why bother, when a few paragraphs look the same
Because a screen reader announces "list, four items" before reading the first one, and lets the user skip the whole thing or step through it item by item. Four paragraphs get none of that — they are just four paragraphs.
It also matters for you. In the next lesson you will discover that a navigation bar is, underneath, an unordered list of links. Getting comfortable with lists now makes that lesson trivial.
Common mistakes
| Mistake | Why it's wrong |
|---|---|
A <p> or heading directly inside <ul> | Only <li> may be a direct child |
A nested list placed between two <li> elements | It must go inside the <li> it belongs to |
<ol> chosen because you wanted numbers | Choose by meaning; numbers are a CSS decision |
<ul> used for a sequence of steps | The order is part of the meaning — use <ol> |
<br> between items instead of a list | Throws away the structure, as in Module 2 |
| A list of one item | If there is only one, it is a paragraph |
The short version
- Business pages are full of lists — services, steps, opening hours, FAQs — whether or not they're marked up as one.
<ul>when order doesn't matter,<ol>when it does. Steps to place an order are<ol>; a list of services is<ul>.- Only
<li>goes directly inside<ul>or<ol>. That's the rule people break. - A nested list goes inside the
<li>, not between items. <dl>suits term-and-definition pairs like opening hours or an FAQ.- Marking a list as a list tells a screen reader how many items there are before reading them — a paragraph of dashes tells it nothing.
Try it yourself
Add three lists to your site, each a different type:
- An unordered list of at least four things — services, skills, or what you offer.
- An ordered list of the steps somebody goes through to work with you or contact you. At least four steps.
- Nest a sub-list inside one of those ordered steps, with two or three sub-points. Check the nested list sits inside the
<li>, not between two of them. - A description list with at least three terms and their descriptions. Give one term two
<dd>elements. - Open DevTools and inspect the nested list. Confirm in the Elements tree that the inner
<ul>really is inside an<li>and not a direct child of the<ol>. - Break it deliberately: move the nested
<ul>so it sits directly inside the<ol>. Notice it still looks almost right in the browser. Put it back.
Next lesson: a table, for the one kind of content a list cannot handle.
You'll know you've got it when you notice lists on other people's pages that weren't marked up as lists.
More free previews
- ▶Install VS Code and Chrome (plus a phone-only setup with Acode)20 min
- ▶Write headings h1 to h6 in a logical outline15 min
- ▶Link between pages with relative paths and to sites with absolute URLs20 min
- ▶Build a contact form with labels, text inputs and a submit button25 min
- ▶Write title and meta description tags that show up well in Google15 min
- ▶Plan the pages and content for a real local business or your own brand20 min