Can I rely on the implicit creation of the `<tbody>` tag?

I disagree with @spike's answer, at least if we talk about ordinary HTML parsing (not using innerHTML). Every tr becomes a child of implicitly created tbody unless it's already a child of another thead, tbody or tfoot. jQuery.support.tbody is for tables created using innerHTML or probably another DOM methods or so. If you omit <tbody> in the markup, it's always inserted.

The tbody element is not optional, it just has optional both opening and closing tag. To doubt about implicit tbody creation is similar mistake as to doubt about implicit creation of html or body element.

To prove what I said, the HTML4 specification forbids any <tr> elements as a direct childs of <table>s:

<!ELEMENT TABLE - -
 (CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)>

HTML5 specification says that <tr> can be, under certain circumstances, a child of <table>, however this applies only to DOM, not to markup parsing:

8.2.5.4.9 The "in table" insertion mode

...

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.


It's not a question on relying on it being automatically created or not.

The question is if it's mandatory or not.

According to the HTML5 draft:

A tbody element's start tag may be omitted if the first thing inside the tbody element is a tr element, and if the element is not immediately preceded by a tbody thead, or tfoot element whose end tag has been omitted.

A tbody element’s end tag may be omitted if the tbody element is immediately followed by a tbody or tfoot element, or if there is no more content in the parent element.

So you can actually omit it if your code met the above conditions, otherwise it is needed.

As other people pointed out, even if it is needed, and the html parser won't find it because you didn't write it, it will be inserted into the DOM for you, as stated in the html5 specs.

This said, as a rule of thumb, never rely on anyone creating something automatically for you! (see below)

So even if the browser will create it for you, this doesn't mean newer browsers or new version of the same browser will follow the same way, and your code may become broken then.


Also, your JS could be optimized.

$( document ).ready( function(){
    $( "td > input[id]" ).each( function( i, element ){ 
        alert( element.id );
    });
});
  1. Always write semicolons at the end of statements. Don't rely on the JS engine write them for you!!! (see above).

  2. No need to call the jQuery function and create a jQuery object out of element just to call the attr() method to get the id. JavaScript already has the id() method to retrieve the id.

  3. If your actual markup is like the one you posted in your answer, you could write the jQuery selector like this: table input[id]. Or, if you have nested tables td > input[id] like gilly3 suggested.


You can't rely on the browser automatically creating it. The HTML spec says that it should be optional, though I believe that Firefox and IE create it as you saw. You can use this property to find out how the browser behaves (true means it won't be added)

jQuery.support.tbody

Check out this example in a bunch of browsers: http://jsfiddle.net/CuBX9/1/

http://api.jquery.com/jQuery.support/