141

This has been bothering me for a while, and I'm wondering if there's any consensus on how to do this properly. When I'm using an HTML list, how do I semantically include a header for the list?

One option is this:

<h3>Fruits I Like:</h3>
<ul>
    <li>Apples</li>
    <li>Bananas</li>
    <li>Oranges</li>
</ul>

but semantically the <h3> heading is not explicitly associated with the <ul>

Another option is this:

<ul>
    <li><h3>Fruits I Like:</h3></li>
    <li>Apples</li>
    <li>Bananas</li>
    <li>Oranges</li>
</ul>

but this seems a bit dirty, as the heading is not really one of the list items.

This option is not allowed by the W3C:

<ul>
    <h3>Fruits I Like:</h3>
    <li>Apples</li>
    <li>Bananas</li>
    <li>Oranges</li>
</ul>

as <ul>'s can only contain one or more <li>'s

The old "list heading" <lh> makes the most sense

<ul>
    <lh>Fruits I Like:</lh>
    <li>Apples</li>
    <li>Bananas</li>
    <li>Oranges</li>
</ul>

but of course it's not officially part of HTML

I've heard it suggested that we use <label> just like a form:

<ul>
    <label>Fruits I Like:</label>
    <li>Apples</li>
    <li>Bananas</li>
    <li>Oranges</li>
</ul>

but this is a little strange and will not validate anyway.

It's easy to see the semantical problems when trying to style my list headers, where I end up needing to put my <h3> tags within the first <li> and target them for styling with something like:

ul li:first-of-type {
    list-style: none;
    margin-left: -1em;
    /*some other header styles*/
}

horrors! But at least this way I can control the entire <ul>, heading and all, by styling the ul tag.

What is the correct way to do this? Any ideas?

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
Tomas Mulder
  • 2,207
  • 2
  • 16
  • 18
  • 5
    Some people are using LH, but may not realize that they are not actually using a "real" HTML tag, but are just making a random tag name. Browsers treat such a tag as an inline element. Some will allow you to put a class and css on it. – Glen Little Sep 04 '12 at 17:04
  • 1
    Possible duplicate of http://stackoverflow.com/questions/2417891/how-do-i-semantically-group-a-header-with-a-ul-in-html – goodeye Jan 06 '14 at 23:35
  • 2
    possible duplicate of [Best practice for provding a caption, title or label for a list in HTML](http://stackoverflow.com/questions/1141639/best-practice-for-provding-a-caption-title-or-label-for-a-list-in-html) – Foreever Jan 21 '14 at 06:14

8 Answers8

101

As Felipe Alsacreations has already said, the first option is fine.

If you want to ensure that nothing below the list is interpreted as belonging to the heading, that's exactly what the HTML5 sectioning content elements are for. So, for instance you could do

<h2>About Fruits</h2>
<section>
  <h3>Fruits I Like:</h3>
  <ul>
    <li>Apples</li>
    <li>Bananas</li>
    <li>Oranges</li>
  </ul>
</section>
<!-- anything here is part of the "About Fruits" section but does not 
     belong to the "Fruits I Like" section. -->
Chango
  • 6,754
  • 1
  • 28
  • 37
Alohci
  • 78,296
  • 16
  • 112
  • 156
  • 7
    This makes a lot of sense; thanks. Of course, if we're going to use HTML5, the heading should be `

    ` inside the `
    ` as it's the top level heading within those tags.

    – Tomas Mulder Jan 20 '12 at 01:13
  • 8
    You can use `

    ` there, sure. But `

    ` is OK too. So long as you don't use a higher level heading within the same section.

    – Alohci Jan 20 '12 at 01:26
  • 5
    We should stick to h1..h6 headings (here h2 and h3) as long as browsers, screen readers and other assistive technologies don't outline correctly headings as stated in HTML5 (see http://coding.smashingmagazine.com/2011/08/16/html5-and-the-document-outlining-algorithm/ - search "brows"...). I'm not sure how much it evolved in a few months, but probably not that fast with regards to accessibility API of browsers :/ – FelipeAls Jan 20 '12 at 02:39
  • 1
    As of May 2014, the use of only one h1 per page was advocated by the W3C (see https://www.w3.org/wiki/HTML/Usage/Headings/h1only) as user agents fail to take into account the semantic sectioning and treat `h1`s as top-level headings, leading to a flat structure if that's all you use. Hopefully this will improve quickly. – davidjb Dec 22 '15 at 05:43
  • 4
    @davidjb - be careful, that's not exactly what that advice says. It says that h1-h6 should be used to provide heading levels. i.e that h1 elements should only be used for the highest level of heading on the page. It does not say that there can only be one heading at that highest level. Incidentally, browser makers have made it clear they have no intention of implementing the outline algorithm, so there is little hope of the situation improving quickly. – Alohci Dec 22 '15 at 09:29
  • 1
    @Alohci, slightly poor wording on my account; I should have said the suggestion is "h1 as a top-level heading only". The [W3C's HTML Validator's](https://validator.w3.org/nu/) suggestion of "Consider using the h1 element as a top-level heading only (all h1 elements [are treated as top-level headings by many screen readers and other tools](https://www.w3.org/wiki/HTML/Usage/Headings/h1only))", which is where the link came from originally. – davidjb Dec 23 '15 at 06:01
  • 1
    I realize this is older, but what if you want a heading in the middle of your list? It looks ok when I do that.. – Michele Apr 03 '19 at 13:20
  • 3
    @Michele - That depends on whether you mean visually in the middle, or semantically in the middle. If visually, then that's a problem for CSS to sort out, and ideally wouldn't change your mark-up. If semantically, then I'm not sure what kind of list you've got. It may be you've got two lists, not one. – Alohci Apr 04 '19 at 00:44
  • 1
    @Alohci - Thank you. It's probably two lists, but I want to treat them as one list between ul, so I can use my script to do a search cumulatively in all parts of the list. If I divide into multiple ul's, it won't search them as one: – Michele Apr 04 '19 at 14:29
  • 1
    – Michele Apr 04 '19 at 14:29
  • 1
    I see html validation errors with h1/h2/h3 between ul's though. – Michele Apr 04 '19 at 14:35
68

In this case I would use a definition list as so:

<dl>
  <dt>Fruits I like:</dt>
  <dd>Apples</dd>
  <dd>Bananas</dd>
  <dd>Oranges</dd>
</dl>
Andrew
  • 42,517
  • 51
  • 181
  • 281
Duncan Tidd
  • 1,140
  • 10
  • 13
  • 7
    For an unordered list of things described by a label, like the example above, I think this is the best choice. The semantics match exactly: Here is a term or label (Fruits I like), and here are items that correspond to that label (each fruit). – Andrew Jan 16 '15 at 19:14
  • 2
    It's literally a *description list*. This is the best solution imo. – Derek 朕會功夫 Jul 09 '16 at 04:57
  • 1
    display: list-item ...CSS to display the bullets. Good answer. – Mycah Oct 23 '18 at 00:09
10

Your first option is the good one. It's the least problematic one and you've already found the correct reasons why you couldn't use the other options.

By the way, your heading IS explicitly associated with the <ul> : it's right before the list! ;)

edit: Steve Faulkner, one of the editors of W3C HTML5 and 5.1 has sketched out a definition of an lt element. That's an unofficial draft that he'll discuss for HTML 5.2, nothing more yet.

FelipeAls
  • 21,711
  • 8
  • 54
  • 74
  • 1
    I agree, the other solutions don't make sense at all –  Jan 20 '12 at 00:27
  • True, kind of like using a heading over a `

    `. But I would still like something a little more explicit, something like the `for`attribute for a `

    – Tomas Mulder Jan 20 '12 at 01:19
5

You could also use the <figure> element to link a heading to your list like this:

<figure>
    <figcaption>My favorite fruits</figcaption>    
       <ul>
          <li>Banana</li>
          <li>Orange</li>
          <li>Chocolate</li>
       </ul>
</figure>

Source: https://www.w3.org/TR/2017/WD-html53-20171214/single-page.html#the-li-element (Example 162)

Rambobafet
  • 139
  • 1
  • 5
5

a <div> is a logical division in your content, semantically this would be my first choice if I wanted to group the heading with the list:

<div class="mydiv">
    <h3>The heading</h3>
    <ul>
       <li>item</li>
       <li>item</li>
       <li>item</li>
    </ul>
</div>

then you can use the following css to style everything together as one unit

.mydiv{}
.mydiv h3{}
.mydiv ul{}
.mydiv ul li{}
etc...
Evert
  • 8,161
  • 1
  • 15
  • 17
  • Good choice, at least for styling purposes. – Tomas Mulder Jan 20 '12 at 01:22
  • Semanticaly speaking div means nothing, i don't get why it would be your first choice (out of styling issue)? :x – Rambobafet Feb 28 '18 at 09:36
  • @Rambobafet, great necromancy! That answer was from 2012, before html5 introduced sections and other more semantically correct options. Some browsers supported section already, but some didn't. "div" is short for "logical division" in your content, so at the time that was the best way to divide your content for styling. – Evert Jan 25 '19 at 15:17
  • You're perfectly right, didn't saw the " '12" part :) – Rambobafet Jan 26 '19 at 20:14
0

Try defining a new class, ulheader, in css. p.ulheader ~ ul selects all that immediately follows My Header

p.ulheader ~ ul {
   margin-top:0;
{
p.ulheader {
   margin-bottom;0;
}
VDWWD
  • 35,079
  • 22
  • 62
  • 79
-1

According to w3.org (note that this link is in the long-expired draft HTML 3.0 spec):

An unordered list typically is a bulleted list of items. HTML 3.0 gives you the ability to customise the bullets, to do without bullets and to wrap list items horizontally or vertically for multicolumn lists.

The opening list tag must be <UL>. It is followed by an optional list header (<LH>caption</LH>) and then by the first list item (<LI>). For example:

<UL>
  <LH>Table Fruit</LH>
  <LI>apples
  <LI>oranges
  <LI>bananas
</UL>

which could be rendered as:

Table Fruit

  • apples
  • oranges
  • bananas

Note: Some legacy documents may include headers or plain text before the first LI element. Implementors of HTML 3.0 user agents are advised to cater for this possibility in order to handle badly formed legacy documents.

Brooks Moses
  • 9,267
  • 2
  • 33
  • 57
Jfields
  • 23
  • 1
-9

I put the heading inside the ul. There's no rule that says UL must contain only LI elements.

Vlad
  • 612
  • 1
  • 7
  • 13
  • 16
    As a matter of fact, there is. http://www.whatwg.org/specs/web-apps/current-work/#the-ul-element , Content model – Veky Dec 19 '13 at 10:44