How to Create Joined Bulletpoint Lists with CSS, BBC News-style

By Peter Cooper

When there are live events, BBC News often runs a 'timeline' style list against stories. For example:

The effect on the BBC News site

I was intrigued to work out how they'd got the bullet points of the list items to be dynamically joined by a line, and set off with my trusty Chrome DevTools to figure it out.

And, boy, their markup is a trip!

It's an adventure..

Long story short, it's a standard HTML list (the BBC uses <ol> but I went with <ul>) where each list item (<li>) has a :before pseudo-element that's empty content-wise but is marked as being 2 pixels wide with a red background color. This creates the 'line' before each <li>. Further styling then positions this pseudo-element/line.

a debug style view

The key part of the CSS is for the pseudo-element:

li:before { background-color: #c00; width: 2px; content: ''; position: absolute; top: 0px; bottom: 0px; left: 5px;
}

You also need to make sure that the list item itself uses relative positioning so that the position: absolute on the pseudo-element doesn't base itself on the page but on the list item itself:

li { /* You need to turn on relative positioning so the line is placed relative to the item rather than absolutely on the page */ position: relative; /* Use padding to space things out rather than margins as the line would get broken up otherwise */ margin: 0; padding-bottom: 1em; padding-left: 20px;
}

(Also note that if you want to have gaps between your line items now, you need to use padding, otherwise the line would get broken up by the margins!)

The bullet-points aren't the standard HTML bullet-points but are just circles drawn using inline SVG. You could in theory use any shape (stars, squares, whatever) or maybe even something like an emoji, but I just copied the circle approach that the BBC uses.

Rather than bore you to tears with a technical explanation of how it works, I've boiled it down to the simplest code example I could come up with, added plentiful comments, and put it on CodePen for you to fiddle around with.

Play with it here:

LATE ADDITION:

Saadat on Twitter has extended the concept above a little more by baking the SVG for the bullets into the CSS by using the :after pseudo-element! This makes the code even cleaner. Their code is in this pen but the crux of it is this:

/* Small bullets for normal list items */
li::after { content: ''; position: absolute; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 32 32' focusable='false'%3E%3Ccircle stroke='none' fill='%23c00' cx='16' cy='16' r='10'%3E%3C/circle%3E%3C/svg%3E"); background-repeat: no-repeat; background-size: contain; left: 0; top: 2px; width: 12px; height: 12px;
}