HTML: Foundation — Lists

HTML Lists

Learning outcomes:

  • What are lists
  • The <ol> and <ul> elements
  • Some simple lists
  • Nesting lists within lists
  • Things to note regarding <ol> and <ul>

Introduction

So far in this unit, we've learned about a great deal of HTML elements, including <h1> to <h6> for representing headings, <p> for representing paragraphs, <a> for representing hyperlinks, and so on.

Another pretty useful set of elements is that of <ol> and <ul>, used to denote ordered and unordered lists, respectively.

In this chapter, we'll get to unravel what the <ol> and <ul> elements exactly are; their only possible child element, <li>; how to create multiple lists within one another; and much more on this road.

What are lists?

We'll start by defining a list:

A list is simply a collection of items that might be ordered or unordered.

For example, the steps to follow in preparing a meal sit well with an ordered list, since the order of the steps is important.

Similarly, the items in a grocery list can be modeled using an unordered list, since whether 'detergent' comes first or last doesn't matter.

In HTML, there are two fundamental elements to denote lists:

  • <ol> is used to denote ordered lists, hence the name 'ol'.
  • <ul> is used to denote unordered lists, hence the name 'ul'.

Both <ol> and <ul> define each list item using <li>.

The <li> element stands for 'list item' and represents an item of an <ol> or <ul> list. Note that <li> should only be used inside <ol> and <ul>; nothing else.

Conversely, also note that <ol> and <ul> shouldn't directly contain anything besides <li>. (We'll demonstrate what this means below.)

In the next section, we consider a handful of examples of <ol> and <ul>.

Some simple lists

Suppose we want to denote the following collection of programming languages as an unordered list: JavaScript, Ruby, C++, Swift and Perl.

Well, it's really easy to do so.

Since we need an unordered list, we start off with the <ul> element:

HTML
<ul></ul>

This denotes our list.

Now inside this <ul> element, we just need to put five <li> elements corresponding to the five programming languages given above.

Something as follows:

HTML
<ul>
   <li>JavaScript</li>
   <li>Ruby</li>
   <li>C++</li>
   <li>Swift</li>
   <li>Perl</li>
</ul>

And we're done!

Let's see the output:

  • JavaScript
  • Ruby
  • C++
  • Swift
  • Perl

By default, <ul> lists are rendered with a small filled circle (often referred to as a disk) preceding every list item. This acts as a list item marker.

Also note that lists are slightly spaced out from the left side. This is just so that it's easier for us to distinguish lists from other elements on a webpage.

Once again, as with almost all HTML elements, we can customize all the default styles of <ul> (and <ol>) lists using the power of CSS.

Now, let's consider an example of <ol>.

Suppose we want to list out the following students, in the order given, to represent their positions in a competitive programming tournament: Alice, Bob, Ali.

Once again, this is very straightforward. Take the <ol> element and put each student inside an <li> element. Something as follows:

HTML
<ol>
   <li>Alice</li>
   <li>Bob</li>
   <li>Ali</li>
</ol>

And that's done!

Here's the output:

  1. Alice
  2. Bob
  3. Ali

Notice the marker for each list item now, for an ordered list. It's a number corresponding to the position of the <li> element in its parent <ol>.

It's easy enough to remember that <ol> lists are numbered and not <ul> lists: the order matters only in <ol> lists and so, likewise, they are numbered.

While it's possible to change the item markers of <ol> and <ul> lists — even swap them and thus make <ol> lists bulleted and <ul> lists numbered — it's recommended to use numbering only with <ol> and non-numbering only with <ul> lists.

Nesting lists

The hidden power of HTML lists lies in that they can be nested. That is, we can have list items containing lists themselves.

Having such use cases isn't very rare. For example, programming spec documents routinely use nested lists — an algorithm has a list of steps and some of those steps themselves are divided into further substeps.

Let's consider an instance of nesting lists.

We have the following list of languages along with their category:

  • Markup languages: Markdown, HTML, SVG
  • Programming languages: JavaScript, C++, Ruby

Our job is to represent this whole collection of languages as nested lists, with each language listed under its respective category.

First, we'll create an unordered list for the two entries, markup languages and programming languages:

HTML
<ul>
   <li>Markup languages</li>
   <li>Programming languages</li>
</ul>

Next, we'll need to 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.

Altogether, we'll get to the following code:

HTML
<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>
  • Markup languages
    • Markdown
    • HTML
    • SVG
  • Programming languages
    • JavaScript
    • C++
    • Ruby

Notice the item markers of the nested <ul> list items here. They aren't filled circles but instead hollow circles.

These different item markers and the added indentation clearly helps us distinguish nested lists from outer-level lists.

Now, while the code above works, there's a slight issue with the category text.

Currently, both 'Markup languages' and 'Programming languages' are written as mere text inside the <li> elements, not marked up by any element. It's much better to put them inside, let's say, a <p>, or possibly an <h2>, etc.

We do this below, using the <p> element:

HTML
<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 output might not be that much different than what we had before but code-wise this variant is much better than the previous one (with non-marked-up text sitting inside <li>).

The vertical spacing around the category text in the code above is a consequence of the margins applied by default to <p> elements.

Moving on, just for the sake of visualizing nested <ol> lists, let's rewrite the code above, replacing <ul> with <ol>:

HTML
<ol>
   <li>
      <p>Markup languages</p>
      <ol>
         <li>Markdown</li>
         <li>HTML</li>
         <li>SVG</li>
      </ol>
   </li>
   <li>
      <p>Programming languages</p>
      <ol>
         <li>JavaScript</li>
         <li>C++</li>
         <li>Ruby</li>
      </ol>
   </li>
</ol>

And now let's see the output:

  1. Markup languages

    1. Markdown
    2. HTML
    3. SVG
  2. Programming languages

    1. JavaScript
    2. C++
    3. Ruby

Alright, so unlike <ul> lists, the item markers in nested <ol> lists remain the same — decimal numbers.

In this discussion, we demonstrated nesting just one list inside another list, but in HTML we can nest as many lists within lists as we want to.

However, the deeper the nesting, the more complex it would become to maintain and work with the list's HTML code. So, it's best to keep the nesting depth of lists to a minimum wherever possible.

Special attributes for <ol>

Talking about the <ol> element, there are three special attributes that we can use to customize the list's order, type, and beginning of numbering.

  • reversed — makes the list be numbered in reverse order.
  • type — specifies the type of numbering markers to use.
  • start — gives the starting number for the list.

In this section, we shall explore these three attributes along with examples for each one.

reversed

Consider the following <ol> list:

HTML
<ol>
   <li>Alice</li>
   <li>Bob</li>
   <li>Ali</li>
</ol>
  1. Alice
  2. Bob
  3. Ali

Notice the numbering: it begins at 1 and ends at 3.

With the application of the reversed attribute, however, this can be changed. In particular, using reversed, we can reverse an <ol> list's numbering.

Consider the following rewrite of the <ol> list above, this time with reversed set:

HTML
<ol reversed>
   <li>Alice</li>
   <li>Bob</li>
   <li>Ali</li>
</ol>
  1. Alice
  2. Bob
  3. Ali

Notice the numbering again: this time it begins at 3 and ends at 1. Clearly, the numbering is reversed, all thanks to reversed.

With reversed set, only the numbering for <li>s — their ordering remains the same. That is, the first <li> is still the first item shown in the output; the second <li> is the second item shown; and so on and so forth.

type

Using the type attribute, we can customize the type of marker used for numbering the list items.

The acceptable values are:

  • "a" for lowercase numbering based on letters, i.e. a, b, c, ...
  • "A" for uppercase numbering based on letters, i.e. A, B, C, ...
  • "1" for digit numbering, i.e. 1, 2, 3, ...
  • "i" for Roman numbering, i.e. i, ii, iii, ...
  • "I" for Roman numbering in uppercase, i.e. I, II, III, ...

Let's consider the same list as above. In the following code, we change its marking to Roman numerals, using the value "i":

HTML
<ol type="i">
   <li>Alice</li>
   <li>Bob</li>
   <li>Ali</li>
</ol>
  1. Alice
  2. Bob
  3. Ali

Let's also try out letter-based numbering using "a":

HTML
<ol type="a">
   <li>Alice</li>
   <li>Bob</li>
   <li>Ali</li>
</ol>
  1. Alice
  2. Bob
  3. Ali

start

Last but not the least, to customize the very first number in an <ol> list, we can leverage the start attribute. It must hold the number to begin at.

By default, as we know, an ordered list begins at the number 1. But using start, we can change it to any number.

In the following example, we change the starting number of our list to 10:

HTML
<ol start="10">
   <li>Alice</li>
   <li>Bob</li>
   <li>Ali</li>
</ol>
  1. Alice
  2. Bob
  3. Ali

Quite brilliant, isn't this?

Keep in mind that if start is provided, an <ol> list's numbering would always begin at that number regardless of whether any other attribute is set or not.

Based on this rule, try answering the following question.

What would the following HTML output?

HTML
<ol reversed start="10">
   <li>Alice</li>
   <li>Bob</li>
   <li>Ali</li>
</ol>
    1. Alice
    2. Bob
    3. Ali
    1. Alice
    2. Bob
    3. Ali
    1. Alice
    2. Bob
    3. Ali
Since start="10" is set, the <ol> list starts its numbering at 10. And by virtue of reversed, the counting goes backwards, that is, 10, 9, and then 8.

Things to note

The <ol>, <ul> and <li> elements are all pretty simple to use. However, there are two things to take special care of when using them.

<ol>/<ul> shouldn't directly contain anything except for <li>

First of all, <ol> and <ul> elements can NOTdirectly contain any element besides <li>.

So, for example, the following is bad HTML:

HTML
<ul>
<p>Here are the items:</p> <!-- This is not good! --> <li>Item 1.</li> <li>Item 2.</li> </ul>

The issue here is the <p> element occurring directly inside the <ul> element — we should have nothing directly inside <ol>/<ul> besides the <li> element.

For now, fixing this code is pretty straightforward; just take the <p> outside the <ul>:

HTML
<p>Here are the items:</p>
<ul>
   <li>Item 1.</li>
   <li>Item 2.</li>
</ul>

Notice the emphasis on the word 'directly' above; it means that the given rule applies only when we are talking about adding something directly inside <ol> or <ul>.

For example, it's perfectly valid to have a <p> occurring inside a <ul> element, given that it is nested under an <li> element, as follows:

HTML
<p>Here are the items:</p>
<ul>
   <li>
<p>This is item 1</p> <!-- Perfectly valid. --> </li> <li>Item 2.</li> </ul>

As a matter of fact, we can have any element inside <li> (that is also valid to be used inside the <body> element).

<li> shouldn't go anywhere except for in <ol>/<ul>

Conversely, it's also NOT considered good practice to have the <li> element appearing inside any other element besides <ol> or <ul>.

Likewise, the following code is again bad HTML:

HTML
<p>Here are the items:</p>
<p> <li>Item 1.</li> <!-- <li> shouldn't go inside <p>! --> <li>Item 2.</li> <!-- same here -->
</p>

Whenever you use <li>, make sure that it's inside <ol> or <ul>.

Spread the word

Think that the content was awesome? Share it with your friends!

Join the community

Can't understand something related to the content? Get help from the community.

Open Discord

 Go to home Explore more courses