Complete CSS Course Module 5: Beginner: Styling Common Elements

Styling Lists and Links with CSS

  • Beginner
  • Lesson 5.1
  • 5 min read
  • 20 of 77 in the course

In short

Learn how to style lists and links with CSS: change or remove bullets, build a simple nav menu, add custom markers and style every link state. How do you change list bullets with list-style-type? Every <ul> and <ol> comes with a marker: the bullet or number in front of each item.

Learn how to style lists and links with CSS: change or remove bullets, build a simple nav menu, add custom markers and style every link state.

How do you change list bullets with list-style-type?

Every <ul> and <ol> comes with a marker: the bullet or number in front of each item. The list-style-type property changes what that marker looks like.

<h3>Shopping list</h3>
<ul class="shopping">
  <li>Bread</li>
  <li>Milk</li>
  <li>Apples</li>
</ul>

<h3>Steps to make tea</h3>
<ol class="steps">
  <li>Boil the water</li>
  <li>Add the tea bag</li>
  <li>Wait three minutes</li>
</ol>
.shopping {
  list-style-type: square;
}

.steps {
  list-style-type: upper-roman;
}

The shopping list now shows small squares instead of round dots, and the tea steps are numbered I, II, III. Common values are disc (the default dot), circle, square, decimal (1, 2, 3), lower-alpha (a, b, c), upper-roman and none.

Two more list properties are useful:

  • list-style-position: inside puts the marker inside the item's box, so wrapped lines start under the marker. The default, outside, hangs the marker in the left padding.
  • list-style-image: url("check.svg") uses a small image as the marker. It is hard to size and position, so most people now use ::marker or ::before instead (see below).

You can also write all three in one shorthand: list-style: square inside;.

Removing bullets to build a navigation menu

A website menu is really a list of links, so we write it as a <ul> inside a <nav>. But menus don't need bullets. To remove them, set list-style: none and also remove the default padding and margin that browsers add to lists.

<nav class="main-nav">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/courses">Courses</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>
.main-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.main-nav li {
  display: inline-block;
  margin-right: 16px;
}

.main-nav a {
  color: #1e3a8a;
  text-decoration: none;
  font-weight: bold;
}

You will see the four links in one row with space between them and no bullets. display: inline-block puts the items side by side. In the Flexbox module you'll learn an even better way to lay out menus.

Common mistake: Removing only the bullets with list-style: none and wondering why the menu is still pushed to the right. Lists have a default padding-left of about 40px. Set padding: 0 too.

Custom markers with ::marker

The ::marker pseudo-element selects the bullet or number itself. You can change its color, size and even its content, without touching the text.

<ul class="features">
  <li>Free lessons</li>
  <li>Practice exercises</li>
  <li>Learn at your own speed</li>
</ul>
.features li::marker {
  content: "✔  ";
  color: #16a34a;
  font-weight: bold;
}

Each item now starts with a green tick instead of a black dot. ::marker only accepts a few properties (like color, content and font properties), but that is enough for most designs.

Tip: Want a red number but black text in an ordered list? Use ol li::marker { color: red; }. Before ::marker existed, people had to hide the number and rebuild it by hand.

A link can be in different states, and you can style each one with a pseudo-class:

  • :link – a link the user has not visited yet.
  • :visited – a link the user has already visited.
  • :hover – the mouse is over the link.
  • :focus-visible – the link was reached with the keyboard (Tab key).
  • :active – the link is being clicked right now.

Write them in this order: Link, Visited, Hover, (focus), Active. Remember it as "LoVe HAte". All these selectors have the same specificity, so the last matching rule wins. If you put :hover before :visited, visited links would never change color on hover.

a:link {
  color: #2563eb;
}

a:visited {
  color: #7c3aed;
}

a:hover {
  color: #1d4ed8;
  text-decoration-thickness: 2px;
}

a:focus-visible {
  outline: 3px solid #f59e0b;
  outline-offset: 2px;
}

a:active {
  color: #dc2626;
}

New links are blue, links you have already opened are purple, the underline gets thicker on hover, keyboard users see an orange ring, and the link flashes red while it is pressed.

Sometimes a link should look like a button, for example a "Start learning" link on a home page. Keep it a real <a> (because it goes to another page) and just style it.

<a class="button-link" href="/signup">Start learning</a>
.button-link {
  display: inline-block;
  padding: 12px 24px;
  background: #2563eb;
  color: white;
  text-decoration: none;
  font-weight: bold;
  border-radius: 8px;
}

.button-link:hover {
  background: #1d4ed8;
}

.button-link:focus-visible {
  outline: 3px solid #f59e0b;
  outline-offset: 3px;
}

.button-link:active {
  background: #1e40af;
}

You will see a blue, rounded "button" that gets darker on hover and darker still when pressed. display: inline-block is important: without it, the top and bottom padding would overlap the lines around the link.

Note: Use <a> when the user goes somewhere (a new page) and <button> when something happens on the same page (open a menu, submit a form). The look can be the same; the meaning is different, and screen readers announce them differently.

You can find all the list values on MDN's list-style-type page.

Practice exercise

Make a "Footer links" section with a heading and a list of five links (Privacy, Terms, Help, Blog, Careers). Remove the bullets, show the links in one row, remove the underline, and bring the underline back only on hover. Then add one button-like link that says "Contact us".

Hint: use text-decoration: none on the links and text-decoration: underline inside a:hover. Don't forget padding: 0 on the <ul>.

Key takeaways

  • list-style-type, list-style-position and the list-style shorthand control list markers.
  • For menus, use list-style: none plus margin: 0 and padding: 0.
  • ::marker lets you color or replace bullets and numbers.
  • Style link states in LVHA order: :link, :visited, :hover, :focus-visible, :active.
  • A link can look like a button with padding, a background and display: inline-block.