Adding Commas within an Unordered List

Last Updated November 30, 2016

Adding Commas within an Unordered List

You’re building a site and you want something to look like this:

comma separated list

It looks straight forward. It would be pretty easy to just write some HTML along these lines:

<strong>Tags:</strong> <a href="#">Front End</a>, <a href="#">HTML</a>, <a href="#">Workflow</a>, <a href="#">Web Development</a>

But, is that really semantic?

NOTE:

Semantic in web development simply means that the structure of your code, describe the content. You’ll use a <header> tag to wrap the header content, a <footer> tag to wrap the footer content, etc.

You have a list of items, so it would make sense to use a list.

Let’s think this all the way through. If you’re trying to display this HTML dynamically (with PHP), in order to get a comma between each item, you have to run checks within your code to find the last item, to ensure that the last item doesn’t have a comma at the end:

<strong>Tags:</strong>
<ul>

<?php // how many items are in the $tags array?
$numItems = count($tags);

// create a counter for our loop
$i = 0;

// loop through each item in the array and display it
foreach ($tags as $tag) {
	echo '<a href="' . $tag->link . '">' . $tag->title . '</a>';
	
	// if this is not the last item in the array, display a comma
	if (++$i < $numItems) {
		echo ', ';
	}
} ?>

</ul>

That doesn’t seem very efficient. What seemed like a very easy HTML snippet of code has quickly become more complicated.

Our PHP would be more efficient if we used a list:

<strong>Tags:</strong>
 <ul>
<?php // loop through each item in teh array and display it
foreach ($tags as $tag) {
'' 	echo '<li><a href="' . $tag->link . '">' . $tag->title . '</a></li>';
} ?>
</ul>

But, then how do we maintain the display? CSS cand do it…and it’s actually pretty easy.

Our new HTML:

<strong>Tags:</strong>
<ul>
	<li><a href="#">Front End</li>
	<li><a href="#">HTML</a></li>
	<li><a href="#">Workflow</a></li>
	<li><a href="#">Web Development</a></li>
</ul>

It looks like this:

Semantic Tag List

We want to remove the extra spacing around the <ul></ul> and remove the bullets:

ul {
	display: inline;
	list-style: none;
	margin: 0;
	padding: 0;
}

We want everything to appear on line:

li {
	display: inline;
}

Now, it looks like this:

Unordered List Inline

Now, we just need to add a comma and some spacing between each item.

We can use pseudo elements to target what we need: (1) the content after our item and (2) the last item in our list.

NOTE:

A pseudo element is used to style specific parts of an element. CSS-Tricks has a great post: A Whole Bunch of Amazing Stuff Pseudo Elements Can Do.
li:after {
	content: '\002C\0020';
}

I bet you’re wondering what that goobley gook is next to the content property. Those are unicode characters.

I like to use this site this site, when trying to find the correct values. The \002C is a comma and the \0020 is a space.

Now our display looks like this:

Comma Separated List, with trailing comma

The last thing we need to do is remove the comma after the last item in our list:

li:last-child:after {
	content: '';
}

Finally:

Comma Separated List, no trailing comma

That wasn’t too bad and our code is a lot more efficient, not to mention easier to read.

Here’s our final HTML:

<strong>Tags:</strong>
<ul>
	<li><a href="#">Front End</li>
	<li><a href="#">HTML</a></li>
	<li><a href="#">Workflow</a></li>
	<li><a href="#">Web Development</a></li>
</ul>

and if we were accomplishing it with PHP:

<strong>Tags:</strong>
 <ul>
<?php // loop through each item in teh array and display it
foreach ($tags as $tag) {
'' 	echo '<li><a href="' . $tag->link . '">' . $tag->title . '</a></li>';
} ?>
</ul>

and the corresponding CSS:

ul {
	display: inline;
	list-style: none;
	margin: 0;
	padding: 0;
}

li {
	display: inline;
}

li:after {
	content: '\002C\0020';
}

li:last-child:after {
	content: '';
}

Done!


Bonus Round

What if we wanted to have the last two items in our list separated by the word “and”?

List with an and

You can still accomplish this with CSS! There’s another pseudo element called :nth-last-child(#). It allows you put a number inside the parenthesis and count that many items back. For our use case, we need the second item from the end, so :nth-last-child(2):

li:nth-last-child(2):after {
	content: ', and ';
}

Perfect! — and we didn’t have to change our HTML or PHP!


The Conversation