CSS Lists and Navigation Bars

Style list bullets and numbers, remove default list styles, and turn a list of links into horizontal and vertical navigation bars with active states.

Lesson 25 of 49Beginner15 min read

Lists are everywhere on the web, and not just as bullet points. Navigation menus, footers, breadcrumb trails, feature lists, pricing tables and tag clouds are almost always built from <ul> or <ol> elements. That's because a list tells screen readers "here are seven related items", which helps people understand and move through the page.

CSS lets you style lists in two very different ways. For content lists, you can change the bullet or number style, use custom bullets, and colour the markers. For menus, you usually remove the bullets entirely and lay the items out in a row with flexbox.

In this lesson you'll learn the list-style properties and the ::marker pseudo-element, then build the most common pieces of site navigation: a horizontal navbar, a vertical sidebar menu, and an active-page highlight. In the responsive navbar lesson you'll make these menus collapse into a hamburger menu on phones.

List style properties

PropertyExample values
list-style-typedisc, circle, square, decimal, lower-alpha, upper-roman, none
list-style-positionoutside (default) or inside
list-style-imageurl(tick.svg)
list-styleShorthand: list-style: square inside;

list-style-type also accepts a string, so list-style-type: "→ " uses an arrow as the bullet. Ordered lists can count in Roman numerals or letters, and the HTML start and reversed attributes control where counting begins.

Styling bullets with ::marker

The ::marker pseudo-element selects the bullet or number itself:

CSS
li::marker { color: #16a34a; font-weight: bold; }

It supports colour, font properties and content, which is enough for most custom bullets. For fully custom designs, such as an icon in a circle, remove the bullet with list-style: none and draw your own with li::before.

From list to navigation bar

A navbar is a list of links inside a <nav>:

HTML
<nav><ul class="menu"><li><a href="/">Home</a></li>...</ul></nav>

Three steps turn it into a horizontal menu:

  1. Reset the list: list-style: none; margin: 0; padding: 0;
  2. Line the items up: display: flex; gap: 8px; on the <ul>
  3. Style the links: display: block; padding: 10px 14px; so the whole padded area is clickable

For a vertical menu, skip step 2 or add flex-direction: column.

Showing the current page

Mark the current page in HTML with aria-current="page". Screen readers announce it as "current page", and you can style it with an attribute selector:

CSS
.menu a[aria-current="page"] { background: #16a34a; color: white; }

This is better than an .active class alone, because it adds meaning for assistive technology at the same time.

CSS Lists and Navbars Syntax

Lists and navbars

ul.features { list-style: square; }
li::marker { color: #16a34a; }
.menu { list-style: none; margin: 0; padding: 0; display: flex; gap: 4px; }
.menu a { display: block; padding: 10px 14px; text-decoration: none; }
.menu a:hover { background: #f3f4f6; }
.menu a[aria-current="page"] { font-weight: bold; }

CSS Lists and Navbars Summary

  • Use list-style-type to change bullets and numbers, or none to remove them.
  • ::marker styles the bullet or number directly.
  • Navbars are lists of links: reset the list, use flexbox, and pad the links.
  • Make the link the padded block so the whole area is clickable.
  • Mark the current page with aria-current="page" and style that attribute.

CSS Lists and Navbars Examples

Each example runs in the page. Edit the code and press Run to see what changes.

Example 1

Custom bullets and numbers

.ticks { list-style-type: "✓  "; }
.ticks li::marker { color: #16a34a; font-weight: bold; }

.steps { list-style-type: upper-roman; }
.steps li::marker { color: #9333ea; }

li { font-family: sans-serif; margin: 4px 0; }
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Line 1A string becomes the bullet.
  2. Line 2::marker colours the tick green.
  3. Line 4Ordered lists can count in Roman numerals.
Example 2

A horizontal navbar

.bar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 8px 16px;
  background: #1f2937;
  font-family: sans-serif;
}
.logo { color: #fbbf24; font-weight: bold; text-decoration: none; }

.menu { list-style: none; margin: 0; padding: 0; display: flex; gap: 4px; flex: 1; }
.menu a { display: block; padding: 8px 12px; color: #e5e7eb; text-decoration: none; border-radius: 6px; }
.menu a:hover { background: #374151; }
.menu a[aria-current="page"] { background: #fbbf24; color: #1f2937; }

.push { margin-left: auto; }
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Lines 1 to 3The bar lines up the logo and the menu.
  2. Line 11The list loses its bullets and becomes a row that fills the remaining space.
  3. Line 12Each link is a padded block, so the whole area is clickable.
  4. Line 14The current page is highlighted.
  5. Line 16Contact is pushed to the far right.
Example 3

A vertical sidebar menu

.side {
  list-style: none;
  margin: 0;
  padding: 8px;
  width: 200px;
  background: #f9fafb;
  border-right: 1px solid #e5e7eb;
  font-family: sans-serif;
}

.side a {
  display: block;
  padding: 10px 12px;
  color: #374151;
  text-decoration: none;
  border-left: 3px solid transparent;
}
.side a:hover { background: #f3f4f6; }
.side a[aria-current="page"] { border-left-color: #2563eb; color: #2563eb; font-weight: 600; }
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Lines 2 to 4Reset the default list styles.
  2. Line 12Block links stack vertically and fill the width.
  3. Line 16A transparent border keeps every link the same size.
  4. Line 19The current page gets a blue bar on the left.

Common CSS Lists and Navbars Mistakes

Padding on the li instead of the a

Don't
.menu li { padding: 10px 14px; }
Do
.menu a { display: block; padding: 10px 14px; }

With padding on the li, only the text is clickable. Padding the link makes the whole area clickable.

Building menus from divs

Don't
/* <div class="menu"><div><a href="/">Home</a></div></div> */
Do
/* <nav><ul class="menu"><li><a href="/">Home</a></li></ul></nav> */

nav and ul tell screen readers it's a navigation list with a number of items.

Forgetting the default padding

Don't
.menu { list-style: none; } /* still indented by 40px */
Do
.menu { list-style: none; margin: 0; padding: 0; }

Browsers add left padding to lists for the bullets, so remove it as well.

CSS Lists and Navbars in Real Projects

Navigation in the wild

Nearly every website header is a flexbox row with a logo, a list of links and a call-to-action button pushed to the right. Admin dashboards use vertical sidebar menus with an active-item bar. Footers group links into several short lists, and breadcrumbs are ordered lists with separators drawn by ::before. Blogs style content lists with coloured markers or ticks for feature lists.

CSS Lists and Navbars Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Fill in the blankseasy

Remove the bullets from the menu.

.menu {
  : none;
}
Multiple choiceeasy

Which pseudo-element styles a list item's bullet?

Multiple choicemedium

What turns a list of links into a horizontal row?

Multiple choicemedium

How do you mark the current page in an accessible way?

Fix the bugmedium

The menu should be a horizontal row with no bullets and no default padding, and each link should be a padded block. Fix the CSS.

.menu { list-style: square; }
.menu li { padding: 10px; }
.menu a { display: inline; }
ResultEdit the code, then press Run or Ctrl+Enter
Checks
  • No bullets
  • No default padding
  • Items in a row
  • Links are padded blocks

CSS Lists and Navbars Quiz

5 questions to check what you learned.

  1. Which value counts with Roman numerals?

    • roman
    • decimal
    • numeric
    • upper-roman
  2. What does margin-left: auto do on a flex item in a navbar?

    • Centres it
    • Removes its margin
    • Pushes it and later items to the far right
    • Hides it
  3. Why use a list for navigation?

    • It tells assistive technology how many related links there are
    • Lists load faster
    • Lists are required for links
    • Flexbox only works on lists
  4. What does list-style-position: inside do?

    • Hides the bullet
    • Puts the bullet inside the item's content box, so text wraps under it
    • Moves the bullet to the right
    • Makes the list horizontal
  5. Can list-style-type use a custom string?

    • No, only keywords
    • Only emoji
    • Yes, for example list-style-type: "→ "
    • Only in ordered lists

CSS Lists and Navbars Challenge

Build a site header

  1. Make .nav a flex row with align-items: center
  2. Reset .links (no bullets, margin: 0, padding: 0) and make it a flex row with a gap of 8px
  3. Make .links a display: block with padding: 8px 12px
  4. Give the link with aria-current="page" a background of rgb(22, 163, 74)
.nav { font-family: sans-serif; gap: 20px; }
ResultEdit the code, then press Run or Ctrl+Enter
Checks
  • Nav is a centred flex row
  • Links list is reset
  • Links in a row with a gap
  • Padded block links
  • Current page highlighted