I viewed the html source code, there is no <tbody>
, but when viewed via firebug in the HTML tab, <tbody>
appears. Any idea why?
Why does firebug add to ?
Asked
Active
Viewed 5,739 times
30
-
(From @baptx): The weird thing is that creating a table without tbody using javascript createElement/appendChild will not add tbody but using innerHTML will do it. Why?
I've asked question here: http://stackoverflow.com/questions/9053572/no-automated-tbody-with-createelement-appendchild
– Dan Blows
Jan 29 '12 at 16:40
-
This annoyed me *so much* when I was trying to compare my HTML parser's output to Firefox's HTML.
– lesderid
Mar 16 '13 at 11:20
-
1
possible duplicate of [Why do browsers insert tbody element into table elements?](http://stackoverflow.com/questions/938083/why-do-browsers-insert-tbody-element-into-table-elements)
– Ciro Santilli OurBigBook.com
Jul 20 '14 at 11:30
5 Answers
20
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 in tbody
! The spec says that tbody
's start tag is optional, which is supposed to mean that if the HTML parser encounters tr
directly inside a table
it inserts the tbody
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."
Nickolay
- 31,095
- 13
- 107
- 185
6
Its not firebug, but firefox which does that. This is the way tables are supposed to be written with <TBODY>
separate from meta data like <COLGROUP>
Firefox simply inserts the <TBODY>
tags when it finds them missing.
KJ Saxena
- 21,452
- 24
- 81
- 109
-
8
-
8
As for "why": Tables are supposed to have a `TBODY`, so Firefox' inner workings *want one to be there*. If you're not specifying it explicitly, it'll create it on its own, because it *wants one to be there*. Even if you're fine eating off the floor, you're placed at a table, because the waiter *wants a table to be there*. ;o)
– deceze
Nov 05 '09 at 05:42
-
@deceze, that's Firefox deciding that. The W3C standard says no such ting - tbody is optional unless you have a thead or tfoot.
– paxdiablo
Nov 05 '09 at 06:49
-
@paxdiabolo: This can quickly slide into fine semantics, but: The standard **requires** the use of `TBODY`, **except for** when it's obvious that the only data in the table *is* the `TBODY` (paraphrased, as per your own comment on Kierons answer). That sounds like quite a strong encouragement to me and IMHO may be summarized with "is supposed to be there".
– deceze
Nov 05 '09 at 09:05
-
If the standard says it doesn't have to be there, it doesn't have to be there. Period. What people or browsers infer is irrelevant. The statement that tables are "supposed to be written with " is clearly incorrect. The standard says it's optional.
– paxdiablo
Nov 05 '09 at 10:06
-
2
Obviously the standard can be read both ways. Fact is the *element* exists and *should* be used, but its *declaration can be skipped* if there's no ambiguity. *Internally* the browser just always assumes it's there because it makes implementing it easier. If by "it doesn't have to be there" you mean "its *explicit declaration* can be skipped", then I agree. The *element* though should always implicitly be there, and that's what you're looking at in Firebug. Don't confuse the markup with the interpreted result.
– deceze
Nov 05 '09 at 11:49
-
The "optional" part is tricky since it depends on the interpretation. You're erring on the side of *skip if not needed*, but the technical easier choice for the browser is *imply if absent*. A Standard™® open to interpretation?! Oh noes, stop the presses! ;o)
– deceze
Nov 05 '09 at 12:08
-
2
Great back on forth on standards interpretation. Similar to the perennial: Must
always to be wrapped by ? ;)
– micahwittman
Dec 22 '09 at 03:59
4
Firefox adds them, because the standard says so.
TABLE
is not actually allowed to contain TR
elements directly, they must be contained in THEAD
, TFOOT
or TBODY
. But for simplicity and backwards compatibility, the start tag of TBODY
may be omitted "when the table contains only one table body and no table head or foot sections"; in which case the element is inferred by the browser.
Kieron
- 11,588
- 5
- 34
- 29
-
While not the most humorous or witty, this answer is the _correct_ one.
– shylent
Nov 05 '09 at 05:57
-
1
This is *not* the correct answer at all. If you're going to link to the standard and then comment on it, you might want to make sure your comment is right. The *standard* states: "TBODY start tag optional, end tag optional" and "The TBODY start tag is always required except when the table contains only one table body and no table head or foot sections. The TBODY end tag may always be safely omitted".
– paxdiablo
Nov 05 '09 at 06:47
-
5
That is what “start tag optional” *means*. You can omit the start tag, but an HTML parser must still imply the element is there. The content model of `table` is `(CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)`; note `tr` is *not* in that list. It's like when you forget ``, the parser will imply it as soon as you use an element like `` that must be in body.
– bobince
Nov 05 '09 at 09:14
-
2
Note that this case is different for XHTML 1.0, because the weird SGML “start tag optional” feature does not exist in XML (thankfully). In this case the content model includes `(tbody+|tr+)`: you may use tbodies or bare trs but you can't mix them. In served-as-XML parsing mode, Firefox should not add the implied `tbody` element.
– bobince
Nov 05 '09 at 09:21
-
1
@bobince, whether the parser implies it or not, the *tag* is optional. The question asked why the tag had appeared.
– paxdiablo
Nov 05 '09 at 10:04
-
5
@paxdiablo, right. But then the answer is that firebug doesn't depict *tag*s, it depicts *element*s. The tag is optional, the element is not. (The question now, doesn't use the word "tag" or "element", but it's been edited, so maybe it did originally.)
– Alohci
Nov 05 '09 at 10:26
1
It's not added by firebug, it's added by Firefox. Firebug gives you what the actual dom looks like. If you browse through the various dom elements you'll notice Firefox has added some of it's own style elements as well.
ChadT
- 7,598
- 2
- 40
- 57
0
A.19. Explicit Elements
DO use explicit tbody elements within tables.
Rationale: While the content model of the table element permits the tbody element to be skipped, in HTML 4 this element is implicit. HTML 4 user agents will silently add this element, thus potentially confusing scripts or style sheets.
Source : http://www.w3.org/TR/2009/NOTE-xhtml-media-types-20090116/#compatGuidelines
Jitendra Vyas
- 148,487
- 229
- 573
- 852
-
(From @baptx): The weird thing is that creating a table without tbody using javascript createElement/appendChild will not add tbody but using innerHTML will do it. Why? I've asked question here: http://stackoverflow.com/questions/9053572/no-automated-tbody-with-createelement-appendchild – Dan Blows Jan 29 '12 at 16:40
-
This annoyed me *so much* when I was trying to compare my HTML parser's output to Firefox's HTML. – lesderid Mar 16 '13 at 11:20
-
1possible duplicate of [Why do browsers insert tbody element into table elements?](http://stackoverflow.com/questions/938083/why-do-browsers-insert-tbody-element-into-table-elements) – Ciro Santilli OurBigBook.com Jul 20 '14 at 11:30
5 Answers
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

- 31,095
- 13
- 107
- 185
Its not firebug, but firefox which does that. This is the way tables are supposed to be written with <TBODY>
separate from meta data like <COLGROUP>
Firefox simply inserts the <TBODY>
tags when it finds them missing.

- 21,452
- 24
- 81
- 109
-
8
-
8As for "why": Tables are supposed to have a `TBODY`, so Firefox' inner workings *want one to be there*. If you're not specifying it explicitly, it'll create it on its own, because it *wants one to be there*. Even if you're fine eating off the floor, you're placed at a table, because the waiter *wants a table to be there*. ;o) – deceze Nov 05 '09 at 05:42
-
@deceze, that's Firefox deciding that. The W3C standard says no such ting - tbody is optional unless you have a thead or tfoot. – paxdiablo Nov 05 '09 at 06:49
-
@paxdiabolo: This can quickly slide into fine semantics, but: The standard **requires** the use of `TBODY`, **except for** when it's obvious that the only data in the table *is* the `TBODY` (paraphrased, as per your own comment on Kierons answer). That sounds like quite a strong encouragement to me and IMHO may be summarized with "is supposed to be there". – deceze Nov 05 '09 at 09:05
-
If the standard says it doesn't have to be there, it doesn't have to be there. Period. What people or browsers infer is irrelevant. The statement that tables are "supposed to be written with " is clearly incorrect. The standard says it's optional. – paxdiablo Nov 05 '09 at 10:06
-
2Obviously the standard can be read both ways. Fact is the *element* exists and *should* be used, but its *declaration can be skipped* if there's no ambiguity. *Internally* the browser just always assumes it's there because it makes implementing it easier. If by "it doesn't have to be there" you mean "its *explicit declaration* can be skipped", then I agree. The *element* though should always implicitly be there, and that's what you're looking at in Firebug. Don't confuse the markup with the interpreted result. – deceze Nov 05 '09 at 11:49
-
The "optional" part is tricky since it depends on the interpretation. You're erring on the side of *skip if not needed*, but the technical easier choice for the browser is *imply if absent*. A Standard™® open to interpretation?! Oh noes, stop the presses! ;o) – deceze Nov 05 '09 at 12:08
-
2Great back on forth on standards interpretation. Similar to the perennial: Must
always to be wrapped by – micahwittman Dec 22 '09 at 03:59? ;)
Firefox adds them, because the standard says so.
TABLE
is not actually allowed to contain TR
elements directly, they must be contained in THEAD
, TFOOT
or TBODY
. But for simplicity and backwards compatibility, the start tag of TBODY
may be omitted "when the table contains only one table body and no table head or foot sections"; in which case the element is inferred by the browser.

- 11,588
- 5
- 34
- 29
-
While not the most humorous or witty, this answer is the _correct_ one. – shylent Nov 05 '09 at 05:57
-
1This is *not* the correct answer at all. If you're going to link to the standard and then comment on it, you might want to make sure your comment is right. The *standard* states: "TBODY start tag optional, end tag optional" and "The TBODY start tag is always required except when the table contains only one table body and no table head or foot sections. The TBODY end tag may always be safely omitted". – paxdiablo Nov 05 '09 at 06:47
-
5That is what “start tag optional” *means*. You can omit the start tag, but an HTML parser must still imply the element is there. The content model of `table` is `(CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)`; note `tr` is *not* in that list. It's like when you forget ``, the parser will imply it as soon as you use an element like `` that must be in body.– bobince Nov 05 '09 at 09:14
-
2Note that this case is different for XHTML 1.0, because the weird SGML “start tag optional” feature does not exist in XML (thankfully). In this case the content model includes `(tbody+|tr+)`: you may use tbodies or bare trs but you can't mix them. In served-as-XML parsing mode, Firefox should not add the implied `tbody` element. – bobince Nov 05 '09 at 09:21
-
1@bobince, whether the parser implies it or not, the *tag* is optional. The question asked why the tag had appeared. – paxdiablo Nov 05 '09 at 10:04
-
5@paxdiablo, right. But then the answer is that firebug doesn't depict *tag*s, it depicts *element*s. The tag is optional, the element is not. (The question now, doesn't use the word "tag" or "element", but it's been edited, so maybe it did originally.) – Alohci Nov 05 '09 at 10:26
It's not added by firebug, it's added by Firefox. Firebug gives you what the actual dom looks like. If you browse through the various dom elements you'll notice Firefox has added some of it's own style elements as well.

- 7,598
- 2
- 40
- 57
A.19. Explicit Elements
DO use explicit tbody elements within tables.
Rationale: While the content model of the table element permits the tbody element to be skipped, in HTML 4 this element is implicit. HTML 4 user agents will silently add this element, thus potentially confusing scripts or style sheets.
Source : http://www.w3.org/TR/2009/NOTE-xhtml-media-types-20090116/#compatGuidelines

- 148,487
- 229
- 573
- 852