Lists are the structure of most information on the web: menus, steps, features, search results, definitions. HTML gives you three kinds, and choosing the right one is a matter of what the items are rather than how you want them to look.
What are the three types?
An unordered list for items with no inherent order, an ordered list for items where order carries meaning, and a definition list for terms and their descriptions.
<!-- unordered: a set of things, order does not matter -->
<ul>
<li>Semantic HTML</li>
<li>Accessible forms</li>
<li>Responsive layout</li>
</ul>
<!-- ordered: the sequence is the information -->
<ol>
<li>Install the toolkit</li>
<li>Start the server</li>
<li>Open the page</li>
</ol>
The difference is not the bullet or the number — that is entirely a styling decision. The difference is what the list means. A screen reader announcing "list of three items" versus "list of three items, 1 of 3" tells the user something different, and the second one is only true if the order matters.
When does order matter?
Use an ordered list when a reader would notice if the items were rearranged: installation steps, a procedure, a ranking, a sequence of events. Use an unordered list for a set of peers: features, links, tags, ingredients.
<ol>
<li>Back up your data</li>
<li>Upgrade the service</li>
<li>Verify the data</li>
</ol>
<ul>
<li>Backups</li>
<li>Monitoring</li>
<li>Alerting</li>
</ul>
Steps in a numbered list can be linked to directly — <li id="step-2"> plus <a href="#step-2"> — which is how a table of contents for a procedure is usually built.
How do nested lists work?
A list can contain another list, and the nesting expresses the hierarchy. The second list goes inside the list item it belongs to, not directly inside the outer list.
<ul>
<li>Layout
<ul>
<li>Flexbox</li>
<li>Grid</li>
</ul>
</li>
<li>Scripting
<ul>
<li>DOM</li>
</ul>
</li>
</ul>
The indentation of the source is only for readability — the browser nests correctly because of the tags. But there is a rule worth keeping: keep the nesting shallow, three levels at most. Beyond that, a list of lists becomes hard to read and harder to use with a screen reader.
What is a definition list?
A definition list pairs terms with descriptions. It is underused, and it is the right element whenever you are presenting a glossary, a specification, or a list of key-value facts.
<dl>
<dt>Server</dt>
<dd>The process that responds to requests for resources.</dd>
<dt>Client</dt>
<dd>The program that sends those requests, usually a browser.</dd>
</dl>
The <dt> holds the term and the <dd> holds its description. The two are associated programmatically, which is what a screen reader needs to read them as a pair rather than as an undifferentiated blob of text.
How do you style a list without breaking it?
Two habits separate a well-styled list from a broken one. First, remove the markers rather than the list itself: setting list-style: none keeps the semantics, while removing the list element and using bare <div>s throws them away. Second, if you want horizontal items, keep the list vertical in the markup and rotate the layout in CSS, so the reading order still matches what the user sees.
/* keep the semantics, drop the marker */
.clean-list {
list-style: none;
margin: 0;
padding: 0;
}
/* a horizontal row of links that is still a list in the markup */
.nav-list {
display: flex;
gap: 1rem;
list-style: none;
margin: 0;
padding: 0;
}
When a list is used purely for layout — a set of boxes arranged in a row, for instance — the honest choice is usually a different element. A navigation bar is a list because it is a list of destinations; a row of cards is a row of cards, and a <div> or a <section> says that more clearly.
Can an ordered list start at a different number?
Yes, and the attribute is start. It is worth knowing because a list that continues from a previous section would otherwise restart at one and confuse the reader.
<ol start="4">
<li>Fourth step</li>
<li>Fifth step</li>
</ol>
<ol reversed>
<li>Last thing to do</li>
<li>Second to last</li>
</ol>
<ol type="A">
<li>First option</li>
<li>Second option</li>
</ol>
Setting type="A" changes the marker to letters, and reversed counts down. Both are presentational conveniences, so the usual advice applies: if the numbering carries meaning that a sighted reader would miss, spell it out in the text instead. A list that counts down while the steps are actually performed in the written order is a trap.
How do you control the markers and the numbers?
The default bullets, numbers and letters are only the starting point. The list-style family of properties gives you three separate controls.
list-style-typechooses the marker:disc,circle,square,decimal,lower-alpha,upper-roman, andnone.list-style-positiondecides whether the marker sits outside the text box or inside it.list-style-imagereplaces the marker with your own image.
<ol class="steps">
<li>Write the draft</li>
<li>Get a second reader</li>
<li>Publish</li>
</ol>.steps {
list-style-type: upper-roman;
list-style-position: inside;
padding-inline-start: 0;
}
.steps li {
margin-block-end: 0.5rem;
color: #33475b;
}Setting list-style-type: none is the usual first step when you want to build a custom navigation, and it is the reason so many stylesheets also set padding-inline-start: 0 - the default indentation of a list would otherwise leave a gap on the left.
There is one subtlety worth knowing: the marker itself is not an element, so most of your normal rules do not apply to it. The exception is the ::marker pseudo-element, which lets you change the colour, size and content of the bullet - but nothing else. If you need a genuinely different marker, for instance a number followed by a dot, you either use ::marker with a content value, or you drop the list entirely and build the layout from ordinary elements.
Quick reference
<ul>for peers,<ol>when the order is the information,<dl>for terms and definitions.- Bullets and numbers are style, not meaning — the element carries the meaning.
- Nested lists go inside the list item, and three levels is the practical limit.
- Use
list-style: noneto drop markers without losing semantics. - A navigation bar is genuinely a list; a row of cards usually is not.
Try it yourself: write an ordered list of five steps, then rewrite it as an unordered list and describe what a screen reader user would notice. Then turn the ordered list into a horizontal navigation row using flexbox while keeping the list element, and check that the reading order still makes sense.