https://blog.novalistic.com/archives/2017/08/optional-end-tags-in-html/
[ ] Menu
Search blog.NOVALISTIC [ ] Search
* NOVALISTIC 'N' Logo Home
* About
* Products
* Stuff
* dev.NOVALISTIC
* blog.NOVALISTIC
* Contact
You are not required to close your
,
, , or tags in
HTML
August 26, 2017
HTML
1 comment
Permalink
Are you an author writing HTML?
Just so we're clear: Not XHTML. HTML. Without the X.
If you are, repeat after me, because apparently this bears repeating
(after the title):
You are not required to close your
,
, , or tags in
HTML.
(The same applies to over a dozen other elements but these are the
most common ones.)
There are a number of reasons it is good practice to do so (which
I'll get to later in this article), but it is not wrong or inherently
bad practice not to do so with elements with optional end tags or
elements without end tags (believe it or not, these exist -- they're
called void elements). Browsers do not treat missing optional end
tags as errors that need to be recovered from.
Anyone telling you otherwise about these elements was unfortunately
misinformed by the one before them. Please correct them, perhaps by
pointing them to this article; chances are you were referred here by
me or someone else for this very reason.
For the sake of convenience, "HTML5" refers to either WHATWG HTML
(the living standard) or W3C HTML5, whichever you're personally more
comfortable with. None of the differences between the two are
pertinent to this article, so I won't even make any references to
either specification. But I consider the living spec by WHATWG canon,
so all spec links will point to that.
Table of contents
1. Background
2. The rules in HTML, and XHTML
3. Best practices in HTML
Background
I see the following examples of misinformation being spread almost
every day on Stack Overflow, in both comments and answers (that get
upvoted!):
* `Your markup is invalid -- you must close all your tags or
browsers will fix them for you.'
* `You have not closed your img tags properly, this is how they
should be: '
* `Your html, head and body tags are missing; your page will not
render correctly without them.'
As well as the following examples of confused comments, directed at
me when I post HTML snippets with optional tags omitted for brevity,
or when I state the same thing I just massively did above:
* `Are you sure that's valid? I've never seen a table without
td>, or closing tags.'
* `Did you forget to close your p tags or is that on purpose?'
* `The question `why self-close tags?' is in the same category as
`why use DOCTYPE?' No one will complain if you don't. But the guy
is learning. Maybe you should learn strict coding standards
instead of the quirky [sic] ones?'
These are all adapted from real comments; that last one was from just
this week. Now, spreading misinformation is one thing. But spreading
misinformation under the guise of "the guy is learning" (and
attempting to school me about "strict coding standards"^1)? Sorry,
but I can't allow that. That's why I finally got around to writing
this article after sitting on it for years -- for the benefit of those
who are learning.
(BTW, no, those two questions aren't in the same category at all. The
DOCTYPE is mandatory, period. Self-closing void element tags in HTML
using the /> syntax is entirely a matter of personal preference -- I
cover this in full detail below.)
These misconceptions appear to stem from the XHTML fad of the 00s,
before HTML5 emerged. XHTML, being based on XML as opposed to SGML,
is notorious for being author-unfriendly due to its strictness,
requiring start and end tags for all elements (including void
elements using the /> syntax) and quotes around attribute values, as
well as forbidding minimization of Boolean attributes such as
checked, disabled and required. (Nevertheless, everyone attempted to
write XHTML, although almost no one ended up actually writing and
serving true XHTML.) It would seem that many authors who don't know
better have mistakenly believed that these rules carry over to HTML5
as they moved away from XHTML, and the misinformation has been
spreading ever since.
The rules in HTML, and XHTML
Let's start with some markup examples. The following fragments are
valid HTML and well-formed XHTML:
This paragraph has an end tag.
So does this one.
This list item has an end tag.
So does this one.
Stuff you're probably used to, where every element has a matching
pair of start and end tags.
On the other hand, if the following fragments make you uncomfortable,
relax -- they may not be well-formed XHTML, but they are valid HTML,
because the end tags of p and li are optional and browsers are told
exactly when to implicitly close a previously open element (again,
this is not error recovery!):
This paragraph does not have an end tag.
Neither does this one.
This list item does not have an end tag.
Neither does this one.
This is actually how I was taught HTML growing up! According to the
Neopets HTML Guide,
tags were simply a way to start new
paragraphs of text, and similarly
tags represented the bullets
or numbers themselves. Following this logic, end tags weren't needed.
In fact, the original 1993 draft of HTML that pre-dates 1995's RFC
1866 (HTML 2.0) described both p and li in nearly the exact same way
as Neopets did, and defined them as having an empty content model,
just like br, meaning they originally didn't have end tags either!
So, it actually baffles me any time someone claims that p and li have
"always required" end tags. Au contraire, they never did, and never
have in over 20 years. But I digress; enough about my childhood.
In situations where line breaks and indentation are involved, the
only difference between these two pairs of fragments is how
inter-element whitespace is treated: there is no inter-element
whitespace between each pair of elements without their end tags -- the
whitespace all becomes part of the text content of the first element
in each pair. This does have certain implications in CSS,
particularly in inline layout where whitespace processing plays a
crucial, if not central, role.
Next, let's look at the shortcut "self-closing" syntax />. This
syntax comes from XML, so it follows that it's used in XHTML. So, if
HTML5 is a language in its own right and neither based on SGML nor
XML, what is /> doing in HTML5? It's there for exactly one reason:
ease of migration from XHTML.^2 You have an XHTML document with all
these void elements closed with the /> syntax as expected in XHTML.
Migrating it to HTML5, provided there are no other compatibility
issues such as the use of obsolete elements like acronym, is as easy
as switching the DOCTYPE declaration to . Bam. Done.
Alright, so, I keep mentioning void elements. What is a void element?
A void element in HTML is an element that has a start tag and no end
tag (and therefore no content, hence "void"). Common examples of void
elements include br, hr, img, input, link, and meta. A full list can
be found in the spec. In previous versions of HTML, they were known
as empty elements, however XML and now HTML make a distinction
between empty elements and void elements, so the term to use going
forward is "void elements". In summary (these words are my own, taken
from the link right before this sentence):
+ An empty element is one that has no content, regardless of
whether it is allowed to have content in the first place.
+ A void element is one that cannot have any content.
Additionally, it can be said that all void elements are empty
elements by definition, but an empty element does not necessarily
represent a void element.
Now that you understand where the /> syntax came from and why it's in
use today, let's look at some examples. The following fragment is
valid HTML5 and well-formed XHTML, but not valid in any older version
of HTML:
I'm aware that the use of br here is incorrect;
this is simply for illustrative purposes.
Again, stuff you're probably used to, especially if you were taught
to always self-close your void element tags using />.
But, as the title of this article states, you are not required to do
that. The following fragment is not well-formed XHTML, but it is
valid in all versions of HTML:
I'm aware that the use of br here is incorrect;
this is simply for illustrative purposes.
Before I go on, you may also have noticed that there has always been
a space before the /> in HTML5 and XHTML, even in the example
fragments in this article. This is also not required in either
dialect, in the sense that validates just as well as
does.^3 However, it is a tradition dating back nearly 20 years
(again!), and the reason for this tradition was that Netscape
Navigator 3 (you read that right, not even Netscape 4, but Netscape 3
) would choke on .
Yes, an actual browser bug. I'm totally fine with tradition that has
roots in actual cross-browser problems, because while those problems
may no longer be relevant today, they were once upon a time, so
people didn't really have a choice back then. In contrast, no browser
in the history of XHTML has ever treated the /> syntax itself
incorrectly -- evidently, NN3 handled that just fine, provided you
included the space -- so there really is no excuse for claiming that
/> is required for void elements in HTML.
Speaking of which, best practices to come shortly, I promise. (You
can also skip straight over right now if you prefer, because what
follows is advanced stuff.)
For now, this is where things get really interesting. The following
fragment is well-formed XHTML^4, but not valid in any version of HTML
:
First, the end tag is allowed in XHTML because XML always
permits using either an explicit end tag or the /> syntax to close an
empty element. However, because input is a void element, it does not
have an end tag in HTML, and therefore specifying an explicit one is
forbidden.
But because the /> syntax comes from XML and not SGML, even though it
exists in HTML5 solely to ease migration from XHTML, apart from
foreign elements it is completely meaningless in HTML5 and invalid in
all older, SGML-based versions of HTML. And since void elements don't
have end tags, whether or not you self-close them is entirely a
matter of personal preference.
What about non-void elements? Well, not only is treated
exactly the same as
(resulting in a div that is missing an end
tag), but the same fragment above actually produces different DOM
trees in HTML and XHTML (when served as application/xhtml+xml as
intended) for this reason.
In the HTML DOM, the input becomes a child of the p, which in turn
becomes a child of the div (inter-element whitespace not significant
for the purposes of this example; explicit end tags added for
clarity):
In the XHTML DOM, the div, p and input are empty siblings of one
another (again, explicit end tags added for clarity):
For most authors, this will never be a problem since anyone who tries
to use /> to self-close non-void elements tags in text/html will
quickly find out that it doesn't work anyway. (They probably spend a
tad longer confused if writing "XHTML", i.e. XHTML that's not served
as application/xhtml+xml as intended, but as mentioned almost no one
ever serves it with the correct MIME type to begin with, so again
this really is a non-issue.)
Alright! Now for best practices. What you can do, and what you should
do when in doubt.
Best practices in HTML
Disclaimer: this is just my opinion, not gospel. But, if I do say so
myself, I feel it's advice worth considering. Having said that, if
you have any views of your own that you'd like to share, feel free to
leave a comment and we can discuss, so long as we promise to be
respectful to one another.
Here's what I recommend to anyone building a new site, whether
they're a new or seasoned HTML author: Be consistent. There is
nothing wrong with leaving out optional end tags where permissible,
and/or writing void element tags with />, but I recommend that you
either do it consistently, or don't do it at all (also consistently).
Here's my breakdown:
* For the well-versed, there's no harm in leaving out optional tags
for the sake of brevity, especially when you're writing technical
documentation and including short, self-contained example
fragments like the ones in this very article, as long as you know
what you're doing. Tables benefit the most from this, as
depending on how you use line breaks and indentation you can
nearly halve the number of lines just by removing unnecessary end
tags! (It also gives you an excuse to link back to this article
when you get questioned the same way I do, but don't tell anyone
I told you that!)
Just keep in mind the effect that placement of end tags has on
inter-element whitespace, and in turn the effect on your CSS
layout, as I mentioned earlier.
* For those who are still getting the hang of it, those working in
teams, or even just those who don't want to deal with whitespace
issues, I actually recommend that you always open and close your
non-void element tags explicitly, even in situations where
they're not required. Generally speaking, it's a good habit to
cultivate especially for less experienced authors as it will help
you keep track of where all your elements begin and end,
especially when you're nested several levels deep, and you don't
have to remember which elements require end tags and which ones
don't.
Not to mention, some IDEs and online editors don't support
optional end tags, and so will assume either that they're
missing, or you've incorrectly nested your markup even if you
haven't. On the other hand, you can never go wrong with closing
all your non-void element tags -- plus it'll help editors and
validators spot actual nesting errors.
I've heard that writing void element tags with /> helps with
readability as it trains people to internalize what the void
elements are (here's the link to the spec again) and, depending
on how they see things, either that they're "already closed", or
that they "don't need to be closed". If this is the case for you,
I'd recommend sticking to it as well. Remember, this only works
for void elements; attempting to use it with non-void elements
will cause problems, unless you're going out of your way to write
and serve application/xhtml+xml.
I do want to highlight a somewhat interesting case. While the
following fragment validates as HTML5:
... it does seem rather unusual, doesn't it? It's a mix of both HTML
syntax (unquoted attribute values, minimized Boolean attributes) and
XML syntax (/>). Personally I think using /> kinda partially cancels
out the brevity afforded by leaving out attribute quotes. And while
it does also contradict using minimized attributes in principle, at
least we can make a really strong case for doing that since you can
save yourself needlessly duplicating keystrokes and bytes. But yeah,
I'd say just quote all your attribute values if you're going to the
trouble of using />:
As mentioned in the very beginning of this article, any time someone
yells at you to close your
,
, , or tags because
"your markup is invalid", and you haven't stated outright that you're
writing XHTML, refer them to this article, and don't worry about it.
You are doing nothing wrong. Even if you meant to include the end
tags (perhaps based on my suggestions above) and simply left some out
by accident, that's a separate issue altogether. My point is that
it's not invalid as many seem to claim.
And here's what I recommend when migrating an existing site to HTML5:
If it ain't broke, don't fix it. In the vast majority of cases,
provided your site already validates according to whatever DTD it had
before, switching the DOCTYPE to should be enough. It
doesn't matter whether the site was previously XHTML or an older
version of HTML. Roll with it. HTML5 is cool like that, by design.
When the time comes for a redesign, then you can throw out everything
you learned about XHTML and just focus on writing standards-compliant
HTML^5 -- which does not necessitate using the /> syntax or expanding
Boolean attributes. Don't let anyone tell you otherwise.
---------------------------------------------------------------------
1. I built and maintained over half a dozen sites and WordPress
themes that remained entirely Valid XHTML 1.0 Strict for over 10
years combined. I think it's safe to say I know strict markup
better than you do. (Any WordPress theme developer from that era
knows that the things are a nightmare to make XHTML 1.0
Strict-compliant.) -
2. See also the obsolete polyglot markup TR. -
3. In fact, the vast majority of other XML documents don't include
the space because it's considered unnatural to do so. -
4. It's invalid XHTML 1.0, though, in the context of the body
element because it doesn't permit input being a child of body.
It's also invalid in HTML 4 and older. -
5. Unless you really like XHTML -- I for one would probably call
myself an XHTML apologist. -
1 comment
TylerH's Gravatar TylerH
Aug 28, 2017, 10:35 pm
Nice write-up!
Add a comment
Things to keep in mind:
* * denotes a required field.
* Please keep comments civil and on-topic.
* Markdown is supported; examples include **bold** for bold,
*italics* for italics, and [hyperlinks](http://example.com) for
hyperlinks. Learn more.
* You may choose to have your browser remember your name, email and
website for the next time you comment. Your email address will
not be shared either way. See the privacy policy.
Name [ ]
Email address [ ]
Website [ ]
What I'd like to say
[ ]
[ ]
[ ]
[ ]
[ ]
[ ]
[ ]
[ ]
[ ]
[ ]
[ ] Save my details for future comments Post Comment
Recent posts
1. 20 years of NOVALISTIC.com! 4 years ago
2. Talk.CSS #56 with Eric Meyer and Daniel Tan 5 years ago
3. :where(:is(#daniel.now)) 5 years ago
4. Performance of Array.prototype.every(), Array.prototype.some() 6
years ago
5. Talk.CSS #46 6 years ago
Archives
1. November 2021 (1)
2. November 2020 (2)
3. March 2020 (1)
4. January 2020 (2)
5. November 2019 (1)
6. October 2019 (1)
7. July 2019 (3)
8. June 2019 (1)
9. March 2019 (3)
10. January 2019 (1)
11. December 2018 (1)
12. October 2018 (1)
13. September 2018 (1)
14. July 2018 (3)
15. June 2018 (3)
16. May 2018 (2)
17. March 2018 (2)
18. February 2018 (1)
19. January 2018 (5)
20. September 2017 (4)
21. August 2017 (3)
22. July 2017 (2)
23. April 2017 (1)
24. October 2016 (1)
25. June 2016 (1)
26. February 2016 (1)
27. January 2016 (3)
28. December 2015 (3)
29. November 2015 (1)
Blogroll
* Hey Georgie
* Zach Saucier
(c) 2001, 2015-2026 NOVALISTIC. Hosting graciously provided by A Small
Orange.
Ratchet & Clank is a trademark of Sony Computer Entertainment America
LLC.
LEGO(r) is a trademark of the LEGO Group of companies which does not
sponsor, authorize or endorse this site.
All other trademarks are the property of their respective owners.
About NOVALISTIC Privacy policy Site map Contact me