HTML Elements, the `caption` disagreement
Tags: html, webdev, css, beginners
Published: 2020-10-05 06:48:50

Recently I wanted to build a table with double captions, one at the top and one at the bottom.

An HTML Table has a lot of elements that make it up, for example:

> `thead`,  defines a set of rows defining the head of the columns of the table.
>
> `tfoot`, defines a set of rows summarizing the columns of the table.

And there is an HTML element to caption a table.

> `caption` specifies the caption (or title) of a table

So I thought, I'll just put two of them and position them with CSS.

```html
<table>
   <caption class="top">
     first
  </caption>
  <caption class="bottom">
     second
  </caption>
  <thead>
    <tr>
      <th>hello</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>world</td>
    </tr>
  </tbody>
</table>
```

The `caption` element is so convenient that, to position it, there is a `CSS` rule we can use.

```
.top {
	caption-side: top; 
}

.bottom {
	caption-side: bottom;
}
```

> `top` is the `initial-value` for `caption-side`.

All set and done, I pushed my changes and prepared to bike home. However on my way down to my bike, I started to check how the solution looked like on the phones I have available. Chromium based (Chrome and Brave) looked alright. Safari, check. 

Only Firefox was left, which is usually a very strict browser when it comes to HTML semantics, but I thought, double captions should be fine. However, this solution did not work on Firefox.

Here is a very simplified [codepen](https://codepen.io/icyJoseph/pen/eYZqgVG), open it on Chrome, works fine, but Firefox, does not play along.  Or perhaps am I playing foul?

{% codepen https://codepen.io/icyJoseph/pen/eYZqgVG %}

Firefox only renders the first caption tag. The rest of tags, all have size `0x0` and have `perspective-origin` and `transform-origin`, set to `0px 0px`.

A little bizarre behavior is that if you nest a caption within a caption, the browser flattens them in the DOM.

Also if the nested caption has a different `caption-side`, Chrome respects the CSS declaration.

> Chrome Version 85.0.4183.121
>
> Firefox Browser for Developers, version 82.0b6 (64-bit)

I did a few tests on IE 11, using [Browserling](https://www.browserling.com/), and IE is on the rendering many captions side. Though I didn't test nesting captions, I reckon it should work fine. 

## So who's right?

The [HTML Living Standard](https://html.spec.whatwg.org/multipage/tables.html#the-caption-element), says:

>[Contexts in which this element can be used](https://html.spec.whatwg.org/multipage/dom.html#concept-element-contexts):
>
>As the first element child of a `table` element.

Strictly speaking then, there should not be a possibility to have multiple captions.

The same is stated in the [HTML5 Recommended](https://www.w3.org/TR/html52/tabular-data.html#the-caption-element) specification.

The gold nugget lies in the [HTML 4.01 Specification](https://www.w3.org/TR/html401/struct/tables.html#h-11.2.2), which says:

> A [TABLE](https://www.w3.org/TR/html401/struct/tables.html#edef-TABLE) element may only contain one [CAPTION](https://www.w3.org/TR/html401/struct/tables.html#edef-CAPTION) element.

So that's the root of the behavior shown by Firefox.

Interestingly enough the [HTML 4.01](https://www.w3.org/TR/html401/struct/tables.html#h-11.2.2) also says that one should use the `summary` tag for `table`, this use case is [deprecated](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table#attr-summary) and instead the `summary` tag is used instead with the `details` tag. 

The [HTML 5 Recommended] specification also refers to the table model, where it states:

> In addition to [cells](https://www.w3.org/TR/html52/tabular-data.html#cell), [columns](https://www.w3.org/TR/html52/tabular-data.html#column), [rows](https://www.w3.org/TR/html52/tabular-data.html#row), [row groups](https://www.w3.org/TR/html52/tabular-data.html#row-group), and [column groups](https://www.w3.org/TR/html52/tabular-data.html#column-group), [tables](https://www.w3.org/TR/html52/tabular-data.html#table) can have a `caption` element associated with them. This gives the table a heading, or legend.

Again, `a caption element` is the language used. So it makes sense to expect only one caption.

After finding this out, I decided to change my design and markup instead of forcing a workaround. 

I think if you really wanted to hack this, you'd have to change the display property of the `caption` and then try to position your content with transform, but I wouldn't recommend it.

Happy coding!