Different ways to do separators in horizontal text


Quite often on the web, you'll see a set of "things" with a separator between them. For example, at the top of this post, you'll see

Thing 1 | Something Else | Another Thing.

This provides clear visual separation between logical groups. But there are a couple of problems. Firstly, the separator character may not be interpreted correctly by screen readers. They may read out "Vertical Pipe", which isn't very user friendly. Similarly, robots may not attach the correct semantics to the separator. Which is a problem if you're trying to do machine learning on text.

HTML and CSS are about the separation of content and style. So let's examine the ways we can provide a better way to do separators.

Hide Them

I think that this is the least satisfying method.

HTML HTML<span aria-hidden="true">|</span> Thing 1 <span aria-hidden="true">|</span> Something else

The aria-hidden tag hides the content from accessibility software. It is specifically designed to remove purely decorative items. But, because the separators are simply removed, the text runs together. That's a problem for screen readers.

CSS Borders

This is another popular way to visually distinguish groups.

HTML HTML<span style="border-right: solid #000 1px">Thing 1</span> <span style="border-right: solid #000 1px">Another thing</span>

You can style the CSS however you like. Depending on your layout, you may need to use :not() on the last element to prevent an unnecessary separator.

But, again, there's no way for a screen reader or robot to know that the content is supposed to be distinct from each other.

⋮:before and ::after?

Similarly, the ::before and ::after selectors can be used to add content before/after an element:

HTML HTML<style>
   span::after {
      content: " | ";
   }
</style>
<span>Thing 1</span> <span>Another thing</span>

Abuse the <hr> element?

This is a bit wacky. The <hr> element is a - somewhat - outdated way to provide a sectioning break by drawing a horizontal line. But it is accessible in CSS. By changing its rotation and width, it makes a passable vertical separator!

HTML HTMLThing 1 <hr style="rotate: 90deg;width: 1em;"> Another thing

It can be a bit tricky to get the styling just right - but it will effectively separate logical groups.

List styling

I like using lists for things like this. It groups the items together and provides a logical "block" that either a human or robot can interpret or skip.

Here's a baroque method to make a list horizontal and to replace the content of the bullet.

HTML HTML<style>
#hz > li::before {
    display: list-item;
    content: "";
    position: absolute;
    margin-inline-start: -.5em;
}
#hz > li {
    display: inline-block;
    list-style-type: "|";
    padding-right: 1em;
}
#hz > li:first-child {
    list-style-type: "";
}
</style>
<ul id="hz">
    <li>Thing 1</li>
    <li>Another thing</li>
</ul>

That removes all the bullets. Then replaces every one except the first with a pipe spaced back a little from the text. And lays the list out horizontally.

If you want to change the colour or position of the bullet, you can use ::marker instead.

Mix And Match

My preferred way is to use <li>, remove the bullets, and then style a border on the left - except for the first one. This keeps the semantics of the list, and is a relatively simple piece of CSS.

HTML HTML<style>
#hz > li {
    display: inline-block;
    border-left: solid #000 1px;
    padding: 0 1em 0 1em;
}
#hz > li:first-child {
    border: none;
}
</style>
<ul id="hz">
    <li>Thing 1</li>
    <li>Another thing</li>
</ul>

Is there a best way?

No, it is a matter of personal taste and appetite for complexity. My "strong opinion weakly held" is that semantic HTML is nearly always preferable to just chucking stuff in a load of <span>s and <div>s. It makes the content easy to understand if you're browsing without CSS, or if you're a robot trying to understand the world.

Similarly, I think simple CSS is better than complicated CSS. Something small and human-readable is always going to be easier to understand and manage in the future.

But, if you think I'm wrong - or know a better way to lay things out - please let me know in the comments.


Share this post on…

  • Mastodon
  • Facebook
  • LinkedIn
  • BlueSky
  • Threads
  • Reddit
  • HackerNews
  • Lobsters
  • WhatsApp
  • Telegram

3 thoughts on “Different ways to do separators in horizontal text”

  1. says:

    On my site, I have settled for the following HTML for navigation.

    <div class="feeds" aria-labelledby="site-feeds-label" role="list"> <span id="site-feeds-label" class="label">Site feeds </span> <span role="listitem" aria-label="ATOM Feed"><a href="https://takeonrules.com/index.atom">ATOM feed</a></span> <span aria-hidden="true"> · </span> <span role="listitem" aria-label="RSS Feed"><a href="https://takeonrules.com/index.xml">RSS feed</a></span> <span aria-hidden="true"> · </span> <span role="listitem" aria-label="JSON Feed"><a href="https://takeonrules.com/index.json">JSON feed</a></span> </div>

    The separator is the middot. From middot.net (https://middot.net)

    The middle dot (a.k.a. interpunct) is often used as a list separator, or in e.g. dictionaries for separating parts of a word (though in Unicode that is technically a different, but most often identical looking character: ‧).

    What I like about this is navigations visually render horizontally, regardless of stylesheets. And with the role="list" and role="listitem", accessibility devices will pick these up as lists. I also find the middot character to be just enough of a visual cue of separation.

    Reply

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.

Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p> <pre> <br> <img src="" alt="" title="" srcset="">