DEV Community

Remy Sharp
Remy Sharp

Posted on • Originally published at remysharp.com on

head is locked

Yesterday I posted a little historical insight into why the closing </p> tag is optional, but in passing I mentioned you'll not see any new elements proposed for the head element.

Though I can't refer to any specifications (partly because I'm writing this from a gym treadmill!), here's the reason why.

It was the good young Mr Harry Roberts who called me out on twitter.

The reasoning is obvious once you see it, and I'll have to pass credit to Jeremy Keith for making me realise why.

You won't see new elements added to the head element because the parsing algorithm only allows for title, meta, style, script, base and link.

Today, if your browser spots anything else in the <head> tag, it'll land in the body element in the DOM.

You can see this happening in Hixie's DOM visualisation tool - the "invalid" positioned element gets tossed out into the body.

If a new element was created to go in the <head> all existing instances of browsers up to that point would eject the element into the body and it would mess things up.

This would completely break the backwards compatible feature of HTML, which, as we've seen, hasn't happened yet.

For this reason, you'll find the link's rel is repurposed ALL the time (link rel="preconnect", etc) to get around this problem.

So, that's why head is locked and you won't see new elements designated beyond the body element.

Written from a treadmill on my 41st birthday, so you'll forgive any typos 😉

Originally published on Remy Sharp's b:log

Top comments (4)

Collapse
 
alohci profile image
Nicholas Stimpson • Edited

I'm not sure I buy it. To be clear, if you put an unknown element in the head section of the markup, then it will cause the head to be closed, the body opened and the unknown element, its contents and all subsequent elements to be placed in the body.

But from a backward compatibility perspective, that's not really a problem. For one thing, web backward compatibility is about not doing things that break existing sites and pages. Adding new elements won't in most cases be in existing pages, so it won't break them. For another, browsers really don't care much whether elements are in the head or body. You might get FOUC where you wouldn't otherwise have done, but almost everything works just the same.

I should also point out that the template element was added to the head section of the parsing algorithm relatively recently. If it could be done for that, it could be done for other elements.

The one danger to watch out for that I can see, is that because the body start tag is optional, an element with the name of the new head element which was previously the first element after head and which caused the body start tag to be inferred, would instead be end up in head. This would mean that it would be hidden by the display:none of head, where previously it would have been visible.

Collapse
 
remy profile image
Remy Sharp

Hi Nicholas - this is a great comment (I would have loved to have seen this as a first class post too).

Your first point, is spot on (and my rushed post doesn't touch that at all because it was completely out of mind).

if you put an unknown element in the head section of the markup, then it will cause the head to be closed

Thinking about it, it's this feature that makes head locked, but we'll come back to that.

Your example template element is perfect, because although the in specification all the examples are in the body, it is allowed as part of "meta content" - meaning allowed inside the head element.

Running a simple test in a new browser, you can see template is indeed kept inside the head and doesn't trigger a close.

This example has a template in the top of the head element and uses JavaScript to print the current state of the DOM once loaded: remy.jsbin.me/steep-night-d89/

If you view the link in a modern browser, you'll find the template is where you'd expect it to be.

The thing is, this did break backward compatibility. Viewed in IE11, the template causes the head to close and causes all the content of the template to be rendered in the body - so we see text that we shouldn't and it runs code that it shouldn't:

IE11 head closed

What's more important here in the older browser (pre-template support) is that the title tag and anything following the template have been shunted out.

Arguably the only "real" effect is the lost title on the document (I've not tested it, but I think link[rel="stylesheet"] would still have their effect outside of head - it's base that would be the more interesting one to check).

However, the document not having a title anymore is a broken page. Another one I've not tested, but I wonder how this would affect a screen reader navigating tabs and windows where the title of document were blank.

(Remember: I wasn't selling anything, and I was on a treadmill when I wrote the post, so this discourse is super 👍 - once the dust settles on this, I'd like to either edit the original or post a follow up with your points - and any feedback you have to this new comment).

Collapse
 
alohci profile image
Nicholas Stimpson

Hi Remy,

Thanks for your response. I'll try to cover as many points as I can.

The fact that the template element doesn't work in IE was not considered a problem for its introduction shows that that kind of backward incompatibility is not a blocker. Indeed, if new features had to work in old browsers, the entire web platform would be permanently locked.

As I said, what matters for backward compatibility is that old web pages don't break. So if a template element was widely used on pages, even though it would have been invalid HTML, before the current template element and its special parser behaviour was invented, that would have been a backward compatibility problem that would have stopped its invention. Presumably, WHATWG did research on how much use of a template element there was in the extant web before its introduction. I didn't see the discussions on it, but I have seen similar discussions on other elements.

It's still the responsibility of web authors to ensure that their new pages with the new HTML features are compatible with old browsers.

Which brings me on to the next point. Validity, and what is "allowed" plays no direct part in such changes, if for no other reason than inventing a new element must change in some way what is valid. What matters is browser behaviour. Browser behaviour (among other things) informs validity, but not vice versa.

I'm not sure what you mean by the "lost title". The title is still in the document, and the window or tab title bar still shows it, so I see no reason why it wouldn't be visible to screen readers or other AT.

Yes, stylesheet links work fine in body. As does base in modern browsers, though not IE. The HTML standard just says that the first base element with a href attribute in the document should be used. It says nothing about it needing to be in head. Because URLs get followed during parsing, it's necessary for the base element to precede in the markup any URL that needs to use it, but the inferred closing of head and opening of body doesn't change the order of the elements, so that's not a problem.

Thread Thread
 
remy profile image
Remy Sharp

Oh, my bad - when I looked at the IE11 rendered screenshot I was looking across the top and there was no title, but it is indeed there in the tab.

This screenshot shows that IE11 has indeed managed to read the title even though it's not in the head: cloudup.com/clxEBCmrXHA

So my key concern is invalid.

Validity and functionality in the old browsers isn't a concern (or one that I raised - I'd never expect IE11 to know what to do with it!) - because it doesn't break the IE11/old browser functionality.

So to close off discussion - you're absolutely right.


I do wonder what motivated the change to bring template into the head element knowing it would trigger closing the head tag. I'd guess the impact is limited as all the elements that normally reside in the head still work when they're in the body. Interestings but doubt if we'll ever know :)