Behold the ubiquitous list elements, <ul> and <ol>! These two sexy elements help millions of websites display lists of information in clean, semantic fashion. Without them, we’d be crawling around like filthy cavemen, eating dirt and howling at the moon.

But these list elements aren’t just sexy, they are also extremely flexible, enabling us humble designers to create robust list configurations that are semantically versatile and highly customizable. We all know how to throw down a basic list:

This nested list markup will result in a unordered bulleted parent list with numerically ordered nested lists, resulting in something like this in a browser:

Pancakes

Swedish

Blueberry

Chocolate

Bananas

Manzano

Plantain

Cavendish

Monkeys

Spider

Howler

Squirrel

Of course, we can style the display of this list configuration with some super-sexy CSS. For example, we can change the appearance of both ordered ( <ol> ) and unordered ( <ul> ) list markers by specifying one of the following types:

And, as if those options weren’t enough, CSS also enables us to use any list marker imaginable via the incredibly sexy list-style-image property. For example, we could create a small GIF image of a banana and use it as a list marker with the following CSS:

ul, ol {
list-style-image: url(banana.gif);
}

This technique is also possible by setting a background-image for the individual list ( <li> ) items, thereby providing a greater degree of presentational control:

ul li, ol li {
background-image: url(banana.gif);
}

We can even combine these methods to establish a built-in fallback mechanism that will enable the custom list-marker images to degrade gracefully to any list-style type. While we’re at it, let’s change the position of the list markers to appear within the list element itself:

This will give us an unordered list that displays our custom banana.gif marker if supported, else the list markers will be displayed as circles. Further, the list markers in this example will be displayed on the inside of the list items. To conserve resources, we may combine these three rules into the following “shortcut” declaration:

ul {
list-style: circle url(banana.gif) inside;
}

If we wanted to display the list without markers, there are two ways to prevent long strings of list text from extending past the first line, for example:

This case happens when the list-style-position is set to inside and the list text wraps onto subsequent lines. So, to alleviate this awkward list display, simply remove the list-style-position:inside declaration or explicitly specify it as list-style-position:outside;. Alternately, if you simply must use an inline display-type, you can prevent subsequent lines from “underlapping” the first line by using the oft-overlooked text-indent property:

Ugh! There’s that nasty underlapping text wrap again. This happens because the generated content is inserted within the list elements. Unfortunately, setting the display-type to outside does not help in this scenario. Fortunately, we can easily resolve this issue by including a text-indent declaration to our previous list styles:

Problem solved. At this point, you may be thinking, “what’s with all of that funky ‘generated content’ stuff?” If so, allow me to explain.

CSS 2.1 provides us with tools that enable us to insert various types of content into our markup. By combining the :before or :after pseudo-selectors and the content property, we can add alphanumeric and special characters into our document via the stylesheet. The characters that may be inserted may be alphanumeric text strings or escaped hexadecimal character equivalents such as the following:

\0020 — blank space, unicode = &nbsp;

\21D3 — down arrow, unicode = &dArr; ( ⇓ )

\00BB — right double angle quote, unicode = &raquo; ( » )

But wait, there’s more! Using CSS may be the modern, “Web-Standards” way of configuring the presentation of list elements, but there are also some interesting and useful inline tricks that, although deprecated, prove a delightful romp nonetheless. Let’s peek into the past, shall we?

First, the list-style type property may be specified inline for <ul> (and even <li>) elements:

That’s all fine and well, but something that is far more useful is the ability to set specific values for various list items. By using the deprecated value attribute applied to the <li> element, we may set marker values as in the following example:

<ol>
<li value=3>The marker for this item is the number 3</li>
<li>The marker for this item is the number 4</li>
<li>The marker for this item is the number 5</li>
<li value=11>The marker for this item is the number 11</li>
<li>The marker for this item is the number 12</li>
<li>The marker for this item is the number 13</li>
</ol>

..which looks like this:

The marker for this item is the number 3

The marker for this item is the number 4

The marker for this item is the number 5

The marker for this item is the number 11

The marker for this item is the number 12

The marker for this item is the number 13

We can do something similar by using the start attribute, which enables us to specify the initial value of an ordered list. Here is an example:

<ol start=77>
<li>The marker for this item is the number 77</li>
<li>The marker for this item is the number 78</li>
<li>The marker for this item is the number 79</li>
</ol>

..which produces this:

The marker for this item is the number 77

The marker for this item is the number 78

The marker for this item is the number 79

This seems incredibly useful, such that I wonder if there is an equivalent way to accomplish this using modern methods, CSS and/or HTML.

One final trick before I close — older versions of HTML enable you to create “compact” lists using the compact attribute:

The idea here is that any list featuring the compact attribute will be displayed in a more compact fashion in the browser. Instead of applying the usual margin and padding to the list and its various items, the browser will reduce the amount of these properties to render a tighter, more “compact”-looking list.

Hi,
there actually is a way to change the start value of a list. You can do it with CSS counter variables and the properties counter-reset and counter-increment in combination with the :before pseudo element.
But of course that’s only a fiddly work-around since you have to disable the actual list-style and the numbers don’t behave like real list numbers. Unfortunately the custom numbers always have a position like list-style-type: inside; and it’s hard to fake outside list numbers.

Good article – thanks for posting. However, how do you handle validating your site then, if you’re using markup that has been deprecated (with the ol value attribute, etc.)? Shouldn’t validation be an important step in semantic and functional web development?

@Manko – thanks for sharing the tip, I’ve been looking for a way to alter the value of lists with CSS.

Projects

About the site

Perishable Press is the work of Jeff Starr, professional developer, designer, author, and publisher with over 10 years of experience.
Check out some of Jeff's books and projects, follow on Twitter, or learn more »

Fun fact: Perishable Press has been online since 2005, and features over 800 articles and more than 11,000 comments. More stats »