Home > Designing, Others > Newer Things to Know About Good Ol’ HTML Lists

Newer Things to Know About Good Ol’ HTML Lists

November 28th, 2022 Leave a comment Go to comments

HTML lists are boring. They don’t do much, so we don’t really think about them despite how widely used they are. And we’re still able to do the same things we’ve always done to customize them, like removing markers, reversing order, and making custom counters.

There are, however, a few “newer” things — including dangers — to know when using lists. The dangers are mostly minor, but way more common than you might think. We’ll get to those, plus some new stuff we can do with lists, and even new ways to approach old solutions.

To clarify, these are the HTML elements we’re talking about:

  • Ordered lists
    1. Unordered lists
      • Description lists
      • Interactive lists

      Ordered lists, unordered lists, and interactive lists contain list items (

    2. ) which are displayed according to what kind of list we’re dealing with. An ordered list (
        ) displays numbers next to list items. Unordered lists (

          ) and menu elements (

          ) displays bullet points next to list items. We call these “list markers” and they can even be styled using the ::marker pseudo-element. Description lists use description terms (

          ) and description details (

          ) instead of

        • and don’t have list markers. They‘re supposed to be used to display metadata and glossaries, but I can’t say I’ve ever seen them in the wild.

          CodePen Embed Fallback

          Let’s start off with the easy stuff — how to correctly (at least in my opinion) reset list styles. After that, we’ll take a look at a couple of accessibility issues before shining a light on the elusive

          element, which you may be surprised to learn… is actually a type of list, too!

          Resetting list styles

          Browsers automatically apply their own User Agent styles to help with the visual structure of lists right out of the box. That can be great! But if we want to start with a blank slate free of styling opinions, then we have to reset those styles first.

          For example, we can remove the markers next to list items pretty easily. Nothing new here:

          /* Zap all list markers! */
          ol, ul, menu {
            list-style: none;
          }

          But modern CSS has new ways to help us target specific list instances. Let’s say we want to clear markers from all lists, except if those lists appear in long-form content, like an article. If we combine the powers of newer CSS pseudo-class functions :where() and :not(), we can isolate those instances and allow the markers in those cases:

          /* Where there are lists that are not articles where there are lists... */
          :where(ol, ul, menu):not(article :where(ol, ul, menu)) {
            list-style: none;
          }

          Why use :where() instead of :is()? The specificity of :where() is always zero, whereas :is() takes the specificity of the most specific element in its list of selectors. So, using :where() is a less forceful way of overriding things and can be easily overridden itself.

          UA styles also apply padding to space a list item’s content from its marker. Again, that’s a pretty nice affordance right out of the box in some cases, but if we’re already removing the list markers like we did above, then we may as well wipe out that padding too. This is another case for :where():

          :where(ol, ul, menu) {
            padding-left: 0; /* or padding-inline-start */
          }

          OK, that’s going to prevent marker-less list items from appearing to float in space. But we sort of tossed out the baby with the bathwater and removed the padding in all instances, including the ones we previously isolated in an

          . So, now those lists with markers sorta hang off the edge of the content box.

          CodePen Embed Fallback

          Notice that UA styles apply an extra 40px to the

          element.

          So what we want to do is prevent the list markers from “hanging” outside the container. We can fix that with the list-style-position property:

          CodePen Embed Fallback

          Or not… maybe it comes down to stylistic preference?

          Newer accessibility concerns with lists

          Unfortunately, there are a couple of accessibility concerns when it comes to lists — even in these more modern times. One concern is a result of applying list-style: none; as we did when resetting UA styles.

          In a nutshell, Safari does not read ordered and unordered lists styled with list-style: none as actual lists, like when navigating content with a screen reader. In other words, removing the markers also removes the list’s semantic meaning. The fix for this fix it to apply an ARIA list role on the list and a listitem role to the list items so screen readers will pick them up:

          <ol style="list-style: none;" role="list">
            <li role="listItem">...</li>
            <li role="listItem">...</li>
            <li role="listItem">...</li>
          </ol>
          
          <ul style="list-style: none;" role="list">
            <li role="listItem">...</li>
            <li role="listItem">...</li>
            <li role="listItem">...</li>
          </ul>

          Oddly, Safari considers this to be a feature rather than a bug. Basically, users would report that screen readers were announcing too many lists (because developers tend to overuse them), so now, only those with role="list" are announced by screen readers, which actually isn’t that odd after all. Scott O’Hara has a detailed rundown of how it all went down.

          A second accessibility concern isn’t one of our own making (hooray!). So, you know how you’re supposed to add an aria-label to

          elements without headings? Well, it sometimes makes sense to do the same with a list that doesn’t contain a heading element that helps describe the list.

          <!-- This list is somewhat described by the heading -->
          <section>
            <h2>Grocery list</h2>
            <ol role="list">
               <!-- ... -->
            </ol>
          </section>
          
          <!-- This list is described by the aria-label -->
          <ol role="list" aria-label="Grocery list">
            <!-- ... -->
          </ol>

          You absolutely don’t have to use either method. Using a heading or an ARIA label is just added context, not a requirement — be sure to test your websites with screen readers and do what offers the best user experience for the situation.

          In somewhat related news, Eric Bailey wrote up an excellent piece on why and how he considers aria-label to be a code smell.

          Wait,

          is a list, too?

          OK, so, you’re likely wondering about all of the

          elements that I’ve been slipping into the code examples. It’s actually super simple; menus are unordered lists except that they’re meant for interactive items. They’re even exposed to the accessibility tree as unordered lists.

          In the early days of the semantic web, I mistakenly believed that menus were like

  1. No comments yet.
  1. No trackbacks yet.
You must be logged in to post a comment.