CodeinWP CodeinWP

How is the DOM Affected by Improperly Nested HTML Elements?

Here’s something interesting I came across while reading Introducing HTML5 by Bruce Lawson and Remy Sharp, which I recently purchased.

In one of the early chapters, Bruce mentions that when tags are not nested properly, the resulting generated DOM will be seen differently in different browsers. Of course, when you “view source”, the code will be the same in all browsers. It’s when you inspect the page (or view the “generated source”) using developer tools that the results can differ.

After some testing, this is indeed the case. Here’s the code that I tested:

<div>
  <p><span><b>This is some text</span></b></p>
</div>

If you want to test it yourself, just throw that snippet into a valid HTML document inside the <body> tag. Here’s a demo page if you want to use my example.

You’ll notice that the tags inside the paragraph element are nested incorrectly; that is, the <span> tag opens, followed by an opening <b> element, but then when those tags are closed, the <span> element is closed first.

This is essentially code validation 101, so generally speaking, you shouldn’t ever do this when hand coding. Not to mention the fact that most good code editors will close tags automatically–and correctly–so you shouldn’t see this too often, if ever.

Nonetheless, for reasons I’ll get into below, you should be aware of how the DOM looks to a browser that sees this mistake. Here are some screen shots of different browsers viewing the DOM through their respective web developer tools:

Chrome 9

Chrome's DOM

Firefox 3.6

Firefox's DOM

Internet Explorer 9 Beta

IE9's DOM

Opera 11

Opera's DOM

Safari 5

Safari's DOM

As you can see from the five examples shown above, the DOM, which is built by the browser’s rendering engine, appears differently in some browsers.

(Oh and thanks to Thomas McGee and Zoran Jambor for pointing out how to enable the dev tools in Safari.)

Full Double Bold Element! What Does it Mean?

It almost looks like a triple bold element! Okay enough of that.

You might be thinking “Who cares if this happens?”. Well, an incorrectly rendered DOM could affect CSS and JavaScript that targets the elements in question. You might think this would never happen as long as you validate, but that’s not necessarily true. If a page is built dynamically, or has user-generated content, improper nesting may occur on occasion. This doesn’t seem like a serious problem to watch out for, but would fall in the “good to know” category.

Another key factor here (and the reason why Bruce mentions it in Introducing HTML5), has to do with the goal of interoperability for web languages. The HTML5 spec includes instructions to browser makers to tell them how to handle errors in markup. This way, problems like incorrectly nested tags are rendered the same way in each browser, thus avoiding cross-browser surprises for developers.

Firefox 3.6, IE9, and Safari 5 all display an extra element. Also, they are the most recent versions of those browsers, so it seems strange that they have different results from the others (especially Safari vs. Chrome since they’re both built on WebKit). If the browser makers are supposed to display incorrect markup the same way, then why are there differences in these examples?

If you can think of any other problems this could cause, or anything significant I’ve left out, feel free to comment.

8 Responses

  1. John says:

    Nice article!
    Firefox 4.10b – No Problem :P

  2. iteand says:

    But it does not happen in FF 4.0b
    very interesting

  3. Paul Irish says:

    Chrome, FF4, and Op11 all share the exact same HTML parser, which is why they handle this identically. (Oh and Safari Nightly has this too so you’ll see it in Saf6)

    IE9 decided not to implement the standard parser, for some legacy reasons, which is why stuff like this is gonna bite them.

    • I see. So Safari 5 and FF 3.6 made the same mistake IE9 did, but maybe not for the same reasons?

      Or were they pretty much free to do what they wanted then?

      • Paul Irish says:

        Saf5 was just released before the standardized html parser landed in webkit. Same deal with FF3.6 and gecko. This stuff happened in the last 7 months. :)

        The Redmond folks have other priorities.. but i guess we’ll see this sort of thing fold out as the HTML5 Test Suite gets built out.

  4. Afraz shahid says:

    A really nice article. I knew that it’s problematic method to start and close tags improperly but now, you provide a solid reason :)

  5. aeneas says:

    in fact they are all wrong
    this is how html code erros should be handled;
    your case for instance:

    
    <div>
    <p><span><b>This is some text</span></b></p>
    </div>
    

    Should get corrected this way:

    
    <div><p><b><span><b>This is some text</b></span></b></p>
    </div>
    

    Few other error:correction example cases that follow should be handled this way:
    error:

    
    <div><p><span>This is some text</b></span></p></div>
    

    correction:

    
    <div><p><span><b>This is some text</b></span></p></div>
    

    error:

    
    <div><p><span>This is some text</span></b></p></div>
    

    correction:

    
    <div><p><b><span>This is some text</span></b></p></div>
    

    error:

    
    <div><p><span>This is some text</span></p></b></div>
    

    correction:

    
    <div><p><span>This is some text</span></p></div>
    

    [!should be ignored, inline element should not be able to wrap a block container element nor affect the block content presentation]

    error:

    
    <div><p><span><b>This is some text</span></p></div>
    

    correction:

    
    <div><p><span><b>This is some text</b></span></p></div>
    

    and so on.

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field and deep URLs are not allowed in the "Website" field. If you use keywords or deep URLs, your comment or URL will be removed. No foul language, please. Thank you for cooperating.

Markdown in use! Use `backticks` for inline code snippets and triple backticks at start and end for code blocks. You can also indent a code block four spaces. And no need to escape HTML, just type it correctly but make sure it's inside code delimeters (backticks or triple backticks).