To summarize the excellent explanations given in the answers and comments by bobince, Kieron, Alohci and others:
- Firebug just displays the DOM of the parsed page. Due to complicated HTML parsing rules, the DOM will “differ” (in some sense) from the source HTML.
- In this case the
TBODY
element in the DOM is added by the HTML parser. Note that this weird parsing is limited to text/html documents and in XHTML the DOM corresponds closely to the source XML.- This behavior was specified in HTML 4. The content model (allowed children) for
table
is(CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)
—tr
s are only allowed intbody
! The spec says thattbody
‘s start tag is optional, which is supposed to mean that if the HTML parser encounterstr
directly inside atable
it inserts thetbody
start tag omitted by the author. - To make matters more clear HTML 5 defines very detailed parsing rules, in particular for this case: “When the insertion mode is “in table”, tokens must be handled as follows: […] A start tag whose tag name is one of: “td”, “th”, “tr” -> Act as if a start tag token with the tag name “tbody” had been seen, then reprocess the current token.”
- This behavior was specified in HTML 4. The content model (allowed children) for