Styling lists and tables
The browser shows the lists and tables from the HTML chapter in a plain way: black bullets, cells without borders. This lesson covers the properties that turn them into a neat menu, a list of benefits or a price list.
Marker type
The list-style-type property chooses the marker — the sign in front of a list item. It can be a dot, a circle, a square, numbers or letters:
<style>
.square { list-style-type: square; }
.roman { list-style-type: upper-roman; }
</style>
<ul class="square"><li>Tea</li><li>Coffee</li></ul>
<ol class="roman"><li>Introduction</li><li>Main part</li></ol>| Value | Marker |
|---|---|
disc | a filled dot (the default for <ul>) |
circle, square | a circle, a square |
decimal | 1, 2, 3 (the default for <ol>) |
upper-roman, lower-alpha | I, II, III or a, b, c |
none | no marker |
A custom marker
The ::marker pseudo-element styles the marker itself: its color and size, and the content property replaces it with any text:
<style>
.benefits li::marker { content: "✓ "; color: seagreen; font-weight: 700; }
</style>
<ul class="benefits">
<li>Next-day delivery</li>
<li>Returns within a month</li>
</ul>Not every property works on ::marker — mainly color, font and content. For complex icons, use ::before. Custom numbering such as 1.1 and 1.2 is made with counters — see the lesson "CSS counters".
A menu from a list
A site menu is a list of links. To make it look like a menu, the list loses its markers and indents, and the items are put in a row with flexbox:
<style>
.menu { list-style: none; margin: 0; padding: 0; display: flex; gap: 16px; }
.menu a { color: steelblue; text-decoration: none; }
</style>
<ul class="menu">
<li><a href="#">Home</a></li>
<li><a href="#">Catalog</a></li>
<li><a href="#">Contacts</a></li>
</ul>The list-style shorthand sets the marker in one declaration. The left indent of a list is its padding, so it is reset separately.
Table cells
A table needs merged borders (border-collapse from the tables lesson), padding inside the cells and alignment. Text is aligned to the left and numbers to the right, so that the digits line up:
<style>
table { border-collapse: collapse; }
th, td { padding: 6px 12px; border-bottom: 1px solid silver; text-align: left; }
.num { text-align: right; }
</style>
<table>
<tr><th>Item</th><th class="num">Price</th></tr>
<tr><td>Backpack</td><td class="num">$40</td></tr>
<tr><td>Tent</td><td class="num">$120</td></tr>
</table>Zebra stripes
A long table is easier to read when rows alternate in color. Even rows are selected with the :nth-child(even) pseudo-class, and the row under the cursor with :hover:
<style>
table { border-collapse: collapse; }
th, td { padding: 6px 12px; text-align: left; }
thead { background: steelblue; color: white; }
tbody tr:nth-child(even) { background: aliceblue; }
tbody tr:hover { background: lightyellow; }
</style>
<table>
<thead><tr><th>Day</th><th>Activity</th></tr></thead>
<tbody>
<tr><td>Monday</td><td>Yoga</td></tr>
<tr><td>Tuesday</td><td>Swimming</td></tr>
<tr><td>Wednesday</td><td>Tennis</td></tr>
<tr><td>Thursday</td><td>Running</td></tr>
</tbody>
</table>The table caption
By default <caption> sits above the table. The caption-side: bottom property moves the caption down:
<style>
table { border-collapse: collapse; }
td { padding: 6px 12px; border: 1px solid silver; }
caption { caption-side: bottom; padding-top: 6px; color: gray; font-size: 14px; }
</style>
<table>
<caption>Prices include tax</caption>
<tr><td>Tea</td><td>$3</td></tr>
<tr><td>Coffee</td><td>$4</td></tr>
</table>Common mistake
A border on a <tr> row does not appear until the table has border-collapse: collapse: in the normal mode only cells draw borders:
<style>
table { margin-bottom: 8px; }
td { padding: 6px 12px; }
tr { border-bottom: 2px solid crimson; }
.fixed { border-collapse: collapse; }
</style>
<table><tr><td>Without collapse</td><td>no line</td></tr></table>
<table class="fixed"><tr><td>With collapse</td><td>a line</td></tr></table>