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
| Property | Example values |
|---|---|
list-style-type | disc, circle, square, decimal, lower-alpha, upper-roman, none |
list-style-position | outside (default) or inside |
list-style-image | url(tick.svg) |
list-style | Shorthand: 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:
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.
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:
.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-typeto change bullets and numbers, ornoneto remove them. ::markerstyles 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.
Custom bullets and numbers
<ul class="ticks">
<li>Fresh ingredients</li>
<li>Delivered in 30 minutes</li>
<li>Easy online ordering</li>
</ul>
<ol class="steps">
<li>Choose a dish</li>
<li>Pick a time</li>
<li>Pay at the door</li>
</ol>.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; }Line-by-line explanation
- Line 1A string becomes the bullet.
- Line 2
::markercolours the tick green. - Line 4Ordered lists can count in Roman numerals.
A horizontal navbar
<nav class="bar">
<a class="logo" href="#">Bakery</a>
<ul class="menu">
<li><a href="#" aria-current="page">Home</a></li>
<li><a href="#">Menu</a></li>
<li><a href="#">About</a></li>
<li class="push"><a href="#">Contact</a></li>
</ul>
</nav>.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; }Line-by-line explanation
- Lines 1 to 3The bar lines up the logo and the menu.
- Line 11The list loses its bullets and becomes a row that fills the remaining space.
- Line 12Each link is a padded block, so the whole area is clickable.
- Line 14The current page is highlighted.
- Line 16Contact is pushed to the far right.
A vertical sidebar menu
<ul class="side">
<li><a href="#">Dashboard</a></li>
<li><a href="#" aria-current="page">Orders</a></li>
<li><a href="#">Customers</a></li>
<li><a href="#">Settings</a></li>
</ul>.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; }Line-by-line explanation
- Lines 2 to 4Reset the default list styles.
- Line 12Block links stack vertically and fill the width.
- Line 16A transparent border keeps every link the same size.
- 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
.menu li { padding: 10px 14px; }.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
/* <div class="menu"><div><a href="/">Home</a></div></div> *//* <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
.menu { list-style: none; } /* still indented by 40px */.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.
Remove the bullets from the menu.
.menu {
: none;
}
list-style: none removes bullets and numbers.Which pseudo-element styles a list item's bullet?
What turns a list of links into a horizontal row?
How do you mark the current page in an accessible way?
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.
<ul class="menu"><li><a href="#">Home</a></li><li><a href="#">Shop</a></li></ul>.menu { list-style: square; }
.menu li { padding: 10px; }
.menu a { display: inline; }- 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.
Which value counts with Roman numerals?
- roman
- decimal
- numeric
- upper-roman
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
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
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
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
- Make
.nava flex row withalign-items: center - Reset
.links(no bullets,margin: 0,padding: 0) and make it a flex row with agapof8px - Make
.links adisplay: blockwithpadding: 8px 12px - Give the link with
aria-current="page"abackgroundofrgb(22, 163, 74)
<nav class="nav">
<a class="brand" href="#">Studio</a>
<ul class="links">
<li><a href="#" aria-current="page">Work</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>.nav { font-family: sans-serif; gap: 20px; }
- Nav is a centred flex row
- Links list is reset
- Links in a row with a gap
- Padded block links
- Current page highlighted