Why are unclosed H3 tags breaking this page?
Asked Answered
A

3

12

If you take a look at this page in a modern browser (latest stable builds of Chrome, Firefox, or IE), you will see that the text increases in size. Taking a look at the source code, it seems that it is due to unclosed <h3>s in the code.

However, I recall that most browsers autoclose tags whenever given the opportunity to. The following code (same doctype as the broken site) works fine with all tags getting closed:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
  <head></head>
  <body>Hello
    <h3>My
    <h3>Name
    <h3>Is
    <h3>Manish
  </body>
</html>

So unclosed <h3>s may not be (or may be only a part of) the issue.

So, my question is, why aren't the browsers autoclosing the tags there?

Arvo answered 9/2, 2013 at 10:40 Comment(7)
Are you asking why invalid html doesn't work?Monotype
brainyquote.com/quotes/quotes/c/charlesbab141832.htmlAlacrity
@KevinBowersox: No, I'm asking why the magic invalid HTML fixer isn't working.Arvo
It can only fix so much.Alacrity
font face, bgcolor ... all these tags are invalid.Hole
For anyone wondering. Here's the archived version of the link above: web.archive.org/web/20140310190221/http://…Epicarp
@Alex_M, even better, I extracted the relevant bits and inserted them into the question as a snippet.Dogtired
C
15

First and foremost, the h1 to h6 elements have always required both their opening and closing tags in order to validate, even back in HTML 3.2:

H1, H2, H3, H4, H5 and H6 are used for document headings. You always need the start and end tags.

So both the page in the link and your example are invalid.

That said, it's interesting how a browser handles both cases differently (and yes, unclosed <h3> tags are the issue):

In any HTML DOM, the h1 to h6 elements can never be children of one another, similar to how p elements can never be children of each other. Any opening <h1> to <h6> tag that directly follows any such unclosed opening tag will implicitly close it, and only then. Therefore, all the h3 elements in your example are really siblings of one another, and not successive descendants.

What's happening in that page, though, is that the h3 elements aren't siblings of each other at all. Instead, they're all separated by table cells, font elements, and so on. It's quite a mess (although that's probably to be expected of a page authored with Microsoft FrontPage1).

However, while the <tr> and <td> tags have their own closing tags, this does not cause the <h3> tags between them to implicitly close. They're still open! Since none of the <h3> tags are closed and there are intermediate <font> and other tags clashing with the h3 elements, the result is that the h3 elements contain all their following ones as descendants, but not directly as children, in spite of the <tr> and <td> elements:

h3
  font
    font
      ...
        h3
         font
           font
             ...

As a result, the font size increments with each successive h3, and a sizable (ha!) catastrophe ensues. Note that the font elements are irrelevant since none of them define a size attribute.

The main takeaway from all this?

Validate your freakin' markup.2 In particular, close all your freakin' tags (except where closing tags are forbidden).


Although the page and your example use the HTML 3.2 doctype, which triggers quirks mode, it should be noted that this behavior is consistent in both quirks mode and standards mode. In fact, the HTML5 spec contains a section entirely dedicated to parsing and DOM tree construction in order to set in stone various browser behaviors with respect to invalid markup (for compatibility with legacy markup and all that). Browsers are expected to follow this specification even in standards mode, hence the consistent behavior in both modes in most browsers.

In there is a subsection containing a rule on how to handle this specific situation:

A start tag whose tag name is one of: "h1", "h2", "h3", "h4", "h5", "h6"

If the stack of open elements has a p element in button scope, then act as if an end tag with the tag name "p" had been seen.

If the current node is an element whose tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then this is a parse error; pop the current node off the stack of open elements.

Insert an HTML element for the token.

This means if the parser encounters a heading tag only while currently in an open heading element, then a parse error is thrown and it should close the previously-opened heading element, before entering this new heading element, which is what's happening with your example. Otherwise, nothing special happens (i.e. the parser should continue as usual).

That said, please don't rely on this. A parse error is still an error; be nice to the parser and don't throw errors at it just because you can. Just write valid code and you'll be fine. Of course, when browsers continue to mess up even after you've validated your code, then you can worry.


1 Which, incidentally, was my first HTML editor too... I was 9.

2 Don't overdo it, but don't neglect to do it either.

Cartel answered 9/2, 2013 at 10:47 Comment(2)
This isn't even my first time answering a question on why a browser treats invalid HTML a certain way.Cartel
While your answer does answer the question really well, I might add a comment as to why the fonts are getting bigger (which is the question to which I was searching an answer when I came here and probably other people as well). The increasing of font sizes the further you go down the page is due to the 'em'-font size unit used on the page which is relative to the parent's font size. since all h3 tags are nested the font size keeps increasing. (this is also why we have 'rem' today which is relative to the root font size)Furry
A
1

Only specific tags like <p> or <li> are autoclosed. <hN> tags are not.

(Also, for future reference, if a site is broken in more than two modern browsers, the problem's not with the browsers or the specs, it's usually the site).

There's a limit to how much punishment the invalid correcter can do. Since the <font> element is inline (even if invalid), and <h3> isn't a direct descendant (it's not recognized as a "sibling"), there's no reason for it to close the <h3> outside of these elements, and they are included within.

Aryanize answered 9/2, 2013 at 10:43 Comment(2)
The point is that <h3> is being closed on the example code I gave above. Why isn't it working here?Arvo
<hN> tags can in fact be auto-closed. See the quoted HTML5 spec in the accepted answer as well as the simple example in the question.Dogtired
M
-3

You always need to close heading tags. From what I've learned, it's also good to close p and li tags although usually it doesn't matter. Thing about coding is it's best to be as specific as possible. You don't want your browser to try to guess anything, so be specific.

Magyar answered 9/2, 2013 at 11:0 Comment(1)
Again, I more of wanted to know why unclosed h3 tags broke one page but they got autoclosed in the other. (See BoltClock's answer). Don't worry, I don't leave tags open normally.Arvo

© 2022 - 2024 — McMap. All rights reserved.