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)
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.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).
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 thehead
element.Running a simple test in a new browser, you can see
template
is indeed kept inside thehead
and doesn't trigger a close.This example has a
template
in the top of thehead
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 thehead
to close and causes all the content of thetemplate
to be rendered in the body - so we see text that we shouldn't and it runs code that it shouldn't:What's more important here in the older browser (pre-
template
support) is that thetitle
tag and anything following thetemplate
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 ofhead
- it'sbase
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).
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.
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 thehead
: cloudup.com/clxEBCmrXHASo 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 thehead
element knowing it would trigger closing the head tag. I'd guess the impact is limited as all the elements that normally reside in thehead
still work when they're in thebody
. Interestings but doubt if we'll ever know :)