Beginner11 min read

Styling Unordered and Ordered Lists in CSS

11 min read
280 words
20 sections16 code blocks

Default List Styles

Browsers apply default styles to HTML lists that include left padding, vertical margins, and bullet or number markers:

CSS
/* Browser defaults (approximately) */
ul, ol {
  margin-top: 1em;
  margin-bottom: 1em;
  padding-left: 40px;
}

ul { list-style-type: disc; }
ol { list-style-type: decimal; }

The list-style-type Property

Control the type of marker displayed next to each list item:

For Unordered Lists

CSS
.disc { list-style-type: disc; }       /* Filled circle (default) */
.circle { list-style-type: circle; }    /* Empty circle */
.square { list-style-type: square; }    /* Filled square */
.none { list-style-type: none; }        /* No marker */

For Ordered Lists

CSS
.decimal { list-style-type: decimal; }            /* 1, 2, 3 */
.lower-alpha { list-style-type: lower-alpha; }    /* a, b, c */
.upper-alpha { list-style-type: upper-alpha; }    /* A, B, C */
.lower-roman { list-style-type: lower-roman; }    /* i, ii, iii */
.upper-roman { list-style-type: upper-roman; }    /* I, II, III */
.none { list-style-type: none; }                   /* No numbers */

Custom String Markers

You can even use custom strings as markers:

CSS
ul {
  list-style-type: '>> ';
}

The list-style-position Property

Control whether the marker appears inside or outside the list item's content box:

CSS
/* Marker is outside the content box (default) */
.outside { list-style-position: outside; }

/* Marker is inside the content box */
.inside { list-style-position: inside; }

With outside (default), the text wraps neatly without going under the bullet. With inside, the marker is part of the text flow.

The list-style-image Property

Use a custom image as the list marker:

CSS
ul {
  list-style-image: url('checkmark.png');
}

However, this method gives limited control over sizing and positioning. A better approach is using background images or pseudo-elements (covered below).

The list-style Shorthand

Combine type, position, and image in one property:

CSS
/* list-style: type position image */
ul { list-style: square inside; }
ol { list-style: upper-roman outside; }
ul { list-style: none; } /* Removes all markers */

Removing Default List Styles

To completely reset list styles (common for navigation menus):

CSS
.clean-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

Controlling List Spacing

Space Between Items

CSS
li {
  margin-bottom: 0.5rem;
}

/* Remove margin from last item */
li:last-child {
  margin-bottom: 0;
}

Using Gap (Modern)

CSS
ul {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  list-style: none;
  padding: 0;
}

Custom Markers with ::marker

The ::marker pseudo-element gives you direct control over list markers:

CSS
li::marker {
  color: #3498db;
  font-size: 1.2em;
  font-weight: bold;
}

/* Different color for ordered list numbers */
ol li::marker {
  color: #e74c3c;
}

Properties you can style with ::marker: color, font-size, font-weight, font-family, content, and a few others.

Custom Bullets with Pseudo-Elements

For full control over custom markers, use ::before pseudo-elements:

CSS
.custom-list {
  list-style: none;
  padding-left: 0;
}

.custom-list li {
  padding-left: 1.5em;
  position: relative;
}

.custom-list li::before {
  content: '\2713'; /* Checkmark character */
  position: absolute;
  left: 0;
  color: #27ae60;
  font-weight: bold;
}

Using Emoji Markers

CSS
.emoji-list li::before {
  content: '\1F449'; /* Pointing finger emoji */
  margin-right: 0.5em;
}

Styling Nested Lists

Control the appearance of nested lists with descendant selectors:

CSS
/* First level */
ul { list-style-type: disc; }

/* Second level */
ul ul { list-style-type: circle; }

/* Third level */
ul ul ul { list-style-type: square; }

/* Reduce spacing for nested lists */
ul ul {
  margin-top: 0.5rem;
  margin-bottom: 0;
}

Creating Navigation from Lists

Lists are the semantic foundation for navigation menus:

Horizontal Navigation

CSS
.nav {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 1rem;
  background: #333;
  padding: 1rem;
}

.nav a {
  color: white;
  text-decoration: none;
  padding: 0.5rem 1rem;
}

.nav a:hover {
  background: rgba(255,255,255,0.1);
  border-radius: 4px;
}

Vertical Sidebar Navigation

CSS
.sidebar-nav {
  list-style: none;
  padding: 0;
  margin: 0;
}

.sidebar-nav li {
  border-bottom: 1px solid #eee;
}

.sidebar-nav a {
  display: block;
  padding: 0.75rem 1rem;
  color: #333;
  text-decoration: none;
}

.sidebar-nav a:hover {
  background: #f5f5f5;
  color: #3498db;
}

Summary

CSS provides extensive control over list styling through list-style properties, the ::marker pseudo-element, and ::before pseudo-elements for fully custom markers. Remove default styles with list-style: none for navigation menus, use ::marker for simple color and size changes, and use pseudo-elements for complete creative control over list bullets.