loading...

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

peterc profile image Peter Cooper ・3 min read

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;
}

Posted on by:

peterc profile

Peter Cooper

@peterc

I run CooperPress who publish stuff like JavaScript Weekly, Frontend Focus, run the @JavaScriptDaily Twitter account and stuff like that.

Discussion

markdown guide
 

Very nice.
Question: how can y make this line conections?
Notice that the connextion is onli betweeb 1st and 2nd dots (#). (each sub

  • has only 2 dots) (it is for a family tree chart). THANK YOU !!!

    1 .........

    | #1.......
    | | #1......
    | | | #1.....
    | | | |
    | | | #2.....
    | | #2......
    | | #1.....
    | | |
    | | #2.....
    | #2......
    | #1......
    | | #1....
    | | |
    | | #2.....
    | #2......
    | #1.....
    | |
    | #2.....

    2.........

       #1......
       |    #1.....
       |    |     #1.....
       |    |     |
       |    |     #2.....
       |    #2.....
       |         #1.....
       |         |
       |         #2.....
       #2......   
            #1.....
            |     #1.....
            |     |
            |     #2..... 
            #2.....
                 #1.....
                 |
                 #2.....
    

    Notice that the connextion is onli betweeb 1st and 2nd dots. (each sub

  • has only 2 dots)
  •  

    One thing to keep in mind is that if you set a list (ordered or unordered) to list-style: none in webkit, it removes the list element semantics, which is bad for accessibility. There is a fix for this posted by Scott O'Hara here: scottohara.me/blog/2019/01/12/list...

     

    You could also use a :before on the ul as a whole, and then you could use margins if you want. The tricky part would be stopping the line at the right place. One way to handle that would be a before: on the final li with a background color that covers it up.

     

    I'm trying to understand why is it that Saadat added those two background rules ( background-repeat: no-repeat; background-size: contain;). I've tested it on my Chromium and there's no difference between having it and not having those two rules. Can someone explain what's the purpose of those rules?

     
     

    Lovely! It's great for resume sites if you want enumerate jobs or skills… shared on Twitter