How to semantically provide a caption, title or label for a list in HTML
HtmlHtml ListsSemantic MarkupHtml Problem Overview
What is the proper way to provide a semantic caption for an HTML list? For example, the following list has a "title"/"caption".
Fruit
- Apple
- Pear
- Orange
How should the word "fruit" be handled, in a such way that it is semantically associated with the list itself?
Html Solutions
Solution 1 - Html
While there is no caption or heading element structuring your markup effectively can have the same effect. Here are some suggestions:
Nested List
<ul>
<li>
Fruit
<ul>
<li>Apple</li>
<li>Pear</li>
<li>Organge</li>
</ul>
</li>
</ul>
Heading Prior to List
<hX>Fruit</hX>
<ul>
<li>Apple</li>
<li>Pear</li>
<li>Orange</li>
</ul>
Definition List
<dl>
<dt>Fruit</dt>
<dd>Apple</dd>
<dd>Pear</dd>
<dd>Orange</dd>
</dl>
Solution 2 - Html
Option 1
HTML5 has the figure
and figcaption
elements, which I find work quite nicely.
Example:
<figure>
<figcaption>Fruit</figcaption>
<ul>
<li>Apple</li>
<li>Pear</li>
<li>Orange</li>
</ul>
</figure>
These are then easily styled with CSS.
Option 2
Using CSS3's ::before pseudo-element can be a nice solution:
HTML:
<ul title="Fruit">
<li>Apple</li>
<li>Pear</li>
<li>Orange</li>
</ul>
CSS:
ul[title]::before {
content: attr(title);
/* then add some nice styling as needed, eg: */
display: block;
font-weight: bold;
padding: 4px;
}
You can, of course, use a different selector than ul[title]
; for example, you could add a 'title-as-header' class and use ul.title-as-header::before
instead, or whatever you need.
This does have the side effect of giving you a tooltip for the whole list. If you don't want such a tooltip, you could use a data attribute instead (e.g., <ul data-title="fruit">
and ul[data-title]::before { content: attr(data-title); }
).
Solution 3 - Html
As far as I know, there are no provisions in current HTML specs for providing a caption for a list, as there are with tables. I'd stay with using either a classed paragraph, or a header tag for now.
<h3>Fruit</h3>
<ul>
<li>Apple</li>
<li>Pear</li>
<li>Orange</li>
</ul>
In the future, when HTML5 gains wider adoption, you will be able to use the <legend>
and <figure>
tags to accomplish this slightly more semantically.
See this post on the W3C mailing list for more information.
Solution 4 - Html
To ensure screen readers connect the list to an associated heading, you could use aria-labelledby
connected to a heading with an id
like so:
<h3 id="fruit-id">Fruit</h3>
<ul aria-labelledby="fruit-id">
<li>Apple</li>
<li>Pear</li>
<li>Orange</li>
</ul>
As noted in a previous answer, make sure your heading level follows heading order in your document.
Solution 5 - Html
There is no caption-like tag for a list like a table has. So I'd just give it an <Hx>
(x depending on your previously used headers).
Solution 6 - Html
I know this is old but wanted to add the answer that I found for future people: https://www.w3.org/MarkUp/html3/listheader.html
use the <lh>
element:
<ul>
<lh>Types of fruit:</lh>
<li>Apple</li>
<li>Orange</li>
<li>Grape</li>
</ul>
Solution 7 - Html
Since I was trying to find a solution with older browser support, I have what might be an over-simplified solution. Using table display styles and ids/classes:
<ul>
<li id="listCaption">My List</li>
<li>first item</li>
<li>second item</li>
<li>third item</li>
</ul>
Then apply the display: table-row;
style to the element in CSS:
li#listCaption {
display: table-row;
font-size: larger;
text-decoration: underline; }
This works much better if you are using a description list, which is what I was doing when I had the same question. In that case, you can use <div>
in the HTML and display: table-caption;
in CSS, as div elements are supported within the dl list:
<dl>
<div id="caption">Table Caption</div>
<dt>term</dt>
<dd>definition</dd>
</dl>
In CSS you can apply various styles to the caption:
#caption {
display: table-caption;
font-family: Arial, Helvetica, sans-serif;
font-size: 20px;
background: transparent;
caption-side: top;
text-align: center; }
I should note that table-caption
does not work as well in ul/ol
as it is treated as a block element and the text will be aligned vertically, which you probably don't want.
I tested this in both Firefox and Chrome.
Solution 8 - Html
You can always use <label/>
to associate label to your list element:
<div>
<label for="list-2">TEST</label>
<ul id="list-1">
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
<label for="list-2">TEST</label>
<ol id="list-2">
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</div>