Skip to content
AgileLogics
5 min read

Styling Lists and Tables

Prerequisites: Styling links and interactive states

Lists

ul.checklist {
  list-style: none;
  padding-left: 0;
}

ol.steps {
  list-style-type: decimal-leading-zero;
  padding-left: 2rem;
}

ul.fancy {
  list-style-type: "★ ";
}

ul.fancy li::marker {
  color: tomato;
}

.nav-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
  • list-style-type: disc, circle, square, decimal, lower-alpha, upper-roman, none, or a string.
  • ::marker styles the bullet or number itself.
  • Browsers add left padding to lists for the markers; remove it when you remove the markers.
  • Safari's VoiceOver may stop announcing a list as a list when list-style: none is set. For navigation this rarely matters; if it does, add role="list" to the ul in the HTML.

Tables

table {
  border-collapse: collapse;
  width: 100%;
}

caption {
  text-align: start;
  font-weight: bold;
  padding-block: 0.5rem;
}

th, td {
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid #ddd;
  text-align: start;
}

thead th {
  background: #f4f4f4;
}

tbody tr:nth-child(even) {
  background: #fafafa;
}

td.number {
  text-align: end;
  font-variant-numeric: tabular-nums;
}
  • border-collapse: collapse merges neighboring cell borders into one line (the default, separate, draws a border around every cell with gaps between them).
  • tr:nth-child(even) stripes every second row — zebra stripes.
  • Right-align numbers and use tabular-nums so digits line up.
<style>
  table { border-collapse: collapse; }
  tbody tr:nth-child(even) { background: rgb(250, 250, 250); }
</style>
<table>
  <caption>Stripes</caption>
  <thead><tr><th scope="col">Row</th></tr></thead>
  <tbody>
    <tr><td>1</td></tr><tr><td>2</td></tr><tr><td>3</td></tr><tr><td>4</td></tr>
  </tbody>
</table>
<script>
  document.querySelectorAll("tbody tr").forEach((tr, i) =>
    console.log("row", i + 1, getComputedStyle(tr).backgroundColor));
</script>
row 1 rgba(0, 0, 0, 0)
row 2 rgb(250, 250, 250)
row 3 rgba(0, 0, 0, 0)
row 4 rgb(250, 250, 250)

:nth-child counts from 1, so "even" rows are the 2nd and 4th.

Practice

Style a table so header cells have a dark background with white text, the whole table has a 1-pixel border around each cell with no double lines, and hovering a body row highlights it.

Show solution
table { border-collapse: collapse; }
th, td { border: 1px solid #ccc; padding: 0.5rem; }
thead th { background: #222; color: white; }
tbody tr:hover { background: #fff8d6; }