Unordered lists
The <ul> element is used to denote an unordered list (hence the name "ul"), where the order of items doesn't matter.
An individual list item goes inside an <li> element ("li" stands for "list item").
When rendered, each list item is preceded by an abstract shape or character, known as the list item marker, or simply the marker. For an unordered list, the marker is customarily a bullet icon (a filled circle), as illustrated below:

Suppose we wish to denote the following (unordered) list of scripting languages: JavaScript, PHP, and Perl. It's an unordered list, so we'll need a <ul>. Furthermore, because there are 3 items in the list, we'll need 3 <li> elements.
Here's the code to produce this list:
<ul>
<li>JavaScript</li>
<li>Perl</li>
<li>PHP</li>
</ul>- JavaScript
- Perl
- PHP
Ain't that simple?
Ordered lists
If the order of items in the list matters, the <ol> element is what we need ("ol" stands for 'ordered list').
Unlike <ul>, list item markers for <ol> are numbers (though we can change them to other kinds of numbers, e.g. Roman numerals).
Suppose you wish to present the top 3 position holders in a school competition: Alice, Bob, and Ali (the first one being Alice, the second one Bob, and the third one Ali). Here's how you can do so using <ol>:
<ol>
<li>Alice</li>
<li>Bob</li>
<li>Ali</li>
</ol>- Alice
- Bob
- Ali
Take note of the list item markers here: "1", then "2", then "3". If instead you prefer Roman numerals, use the type attribute of <ol>. For lowercase Roman numerals, we use the value "i" (the first number in that number system).
"I".Here's an example:
<ol type="i">
<li>Alice</li>
<li>Bob</li>
<li>Ali</li>
</ol>- Alice
- Bob
- Ali
Yeah I know, now you're starting to like HTML!
Nesting lists
The hidden power of HTML lists lies in that they can be nested. That is, we can have lists within lists.
For example, an algorithm (which is a list of steps) might have some steps that are themselves divided into further substeps. This is a perfect scenario to employ nested lists in HTML.
Let's consider a concrete example.
Say we have the following 2 categories of languages along with some instances of languages that belong to them:
- Markup languages: Markdown, HTML, SVG.
- Programming languages: JavaScript, C++, Ruby.
Our job is to represent this as a list containing lists. The categories will go in the outer list, and for each one, we'll have another, inner, list.
First, let's create an unordered list for the two categories, "Markup languages" and "Programming languages":
<ul>
<li>Markup languages</li>
<li>Programming languages</li>
</ul>Next up, let's put the list of all markup languages inside the first <li> and similarly the list of all programming languages inside the second <li>. Both of these lists will be <ul> themselves as well:
<ul>
<li>
Markup languages
<ul>
<li>Markdown</li>
<li>HTML</li>
<li>SVG</li>
</ul>
</li>
<li>
Programming languages
<ul>
<li>JavaScript</li>
<li>C++</li>
<li>Ruby</li>
</ul>
</li>
</ul>Here's the rendered result:
- Markup languages
- Markdown
- HTML
- SVG
- Programming languages
- JavaScript
- C++
- Ruby
Notice the markers of the nested <ul> list items here — they aren't filled circles but rather hollow circles. This helps distinguish inner lists from outer ones.
Now, while the code above works fine, there's one thing that we could change about it. Both the categories "Markup languages" and "Programming languages" are written as mere text inside the <li> elements, not marked up by any element. It's better to put them inside a <p>, like this:
<ul>
<li>
<p>Markup languages</p>
<ul>
<li>Markdown</li>
<li>HTML</li>
<li>SVG</li>
</ul>
</li>
<li>
<p>Programming languages</p>
<ul>
<li>JavaScript</li>
<li>C++</li>
<li>Ruby</li>
</ul>
</li>
</ul>Markup languages
- Markdown
- HTML
- SVG
Programming languages
- JavaScript
- C++
- Ruby
The extra spacing around the category texts here is a consequence of using <p> to denote them (remember that <p> comes with its default margins).
So that's it for lists in HTML. I hope you got the gist of them. (Did that rhyme?)