Optional Tags in HTML 4

Published on June 1, 2008 (↻ February 5, 2024), filed under (RSS feed for all categories).

This and many other posts are also available as a pretty, well-behaved ebook: On Web Development.

For your convenience, here’s a list of all optional tags according to the HTML 4.01 Strict DTD. Omitting these tags allows to save markup and thus file size—if you choose to. I created this list because even nine years after release of the HTML 4 specification, there still is no list like this.

These are indeed tags, not elements. The list might explain the simplicity of the supposedly best HTML template. Thanks Rupert for the inspiration, and others for the encouragement to extend it (HTML 5? [which I made available 11 years later]).

Was this useful or interesting? Share (toot) this post, or maybe treat me to a coffee. Thanks!

About Me

Jens Oliver Meiert, on September 30, 2021.

I’m Jens (long: Jens Oliver Meiert), and I’m a frontend engineering leader and tech author/publisher. I’ve worked as a technical lead for companies like Google and as an engineering manager for companies like Miro, I’m close to W3C and WHATWG, and I write and review books for O’Reilly and Frontend Dogma.

I love trying things, not only in web development (and engineering management), but also in other areas like philosophy. Here on meiert.com I share some of my views and experiences.

If you want to do me a favor, interpret charitably (I speak three languages, and they can collide), yet be critical and give feedback for me to learn and improve. Thank you!

Comments (Closed)

  1. On June 1, 2008, 16:27 CEST, johno said:

    Thanks for compiling the list. At last, I know the difference between a tag and an element.

  2. On June 2, 2008, 4:48 CEST, Duluoz said:

    Just curious…. Why do you construct your blog with XHTML markup verses HTML?

  3. On June 2, 2008, 7:28 CEST, Philippe said:

    Some endtags are explicitly forbidden, like this or this one or that one, according to the HTML 4.01 spec. Granted, the wording of the DTD is not as clearcut.

    Nitpicking ? You’ll be the judge… 😊.

  4. On June 2, 2008, 11:26 CEST, Jens Oliver Meiert said:

    David, because of cost of problem vs. cost of solution and because my blog uses WordPress (which uses XHTML by default).

    Philippe, good point. I just grabbed all optional tags, where the optional start and end tags of e.g. body, head, and html are probably of most interest (as opposed to </img>, for example).

  5. On June 2, 2008, 16:19 CEST, Gunnar Bittersmann said:

    IMHO, the most useful statement about optional tags is missing here: not to make use of the option of leaving them out (for that only makes the HTML source unclear, thus harder to read and more vulnerable to errors).

    “[…] to allow for additional bits or bytes being saved”? No, thank you, that’s a too heavy price for a questionable gain.

  6. On June 2, 2008, 17:02 CEST, Duluoz said:

    @Jens - I have a horrible memory! I think I read that post last year…HA!

    I really only asked the question to see if your answer is what you already stated in your 2007 post. I think I subconsciously had that post in mind! I too came to the same conclusions for project at work. Glad to know I made the same decisions for the same reasons as yourself. 😉

  7. On June 5, 2008, 10:43 CEST, Jens Oliver Meiert said:

    Gunnar, why should omitting something make anything more unclear or harder to read?

    David, glad to hear that 😊 Idealism is a nice currency but you cannot buy everything with it.

  8. On June 5, 2008, 12:34 CEST, Anne van Kesteren said:

    FWIW, some of these tags are not optional, they are simply not allowed (do not exist, if you will), such as </br> and </hr>.

    (HTML5 will indeed add more empty elements, such as command, event-source, and source.)

  9. On June 5, 2008, 12:51 CEST, Jens Oliver Meiert said:

    Thanks for dropping by, Anne; I know, for clarity’s sake I probably shouldn’t have grabbed just everything that was declared optional in the DTD. But, people may figure out that this list is not about </link> and </meta> 😉

  10. On June 5, 2008, 17:22 CEST, Gunnar Bittersmann said:

    I tend to disagree. Let me give an example:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/­strict.dtd">
    <script type="text/javascript" src="myScript1.js"></script>
    <p id="myParagraph1">Some text.
    <script type="text/javascript" src="myScript2.js"></script>
    <p id="myParagraph2">More text.
    <li>some list item
    <li>another one
    <p id="myParagraph3">Yet more text.

    Where exactly does the body element begin? Where exactly does the p[@id="myParagraph1"] element end?

    You need a lot of knowledge about HTML to answer these questions. The element tree is not always as one has expected (what becomes noticeable when styling the document). Spotting one’s errors is difficult since a validator can’t help. Not so if you write all closing tags.

    A very common error is trying to append a tr element as a child to a table element with JavaScript. The source code


    leads one to think that tr was a child of table which is never the case in HTML; there is always a tbody element in between.

    My advice: Never omit optional tags. Don’t write HTML 4.01, do write XHTML 1.0.

  11. On June 6, 2008, 11:05 CEST, Alan Gresley said:

    If implementations decides to repair tag soup forever, where will the web go?

    I want a unforgiving browser. Where do I find one? 😊

  12. On June 6, 2008, 11:12 CEST, Alan Gresley said:


    Just curious…. Why do you construct your blog with XHTML markup verses HTML?

    Why not use XHTML. My own personal choice of language to code web pages.

    Look at where Eric Meyer wants HTML5 to go. href on many elements.

  13. On September 3, 2008, 18:13 CEST, Thorsten said:

    I stumbled across this post some days ago and in the meantime also found a list on the W3C homepage including the same information.

  14. On February 17, 2009, 0:38 CET, cid said:


    ” Granted, the wording of the DTD is not as clearcut.”

    It’s clearcut, given that the spec defines how element declarations
    should be read:

    This example illustrates the declaration of an empty element type:


    The element type being declared is IMG.
    The hyphen and the following “O” indicate that the end tag can be omitted, but together with the content model “EMPTY”, this is strengthened to the rule that the end tag must be omitted.

    I don’t understand why Jens included empty elements in this list.

  15. On February 23, 2009, 17:00 CET, cid said:


    I don’t think it was confusing, you consistently referred to elements with ‘ - O ‘ MIN field.

    The point is the DTD, in fact, does not declare those tags optional just because ‘ - O ‘ is in the MIN field as ‘ - O ‘ and ‘ - O EMPTY ‘ don’t mean the same as far as the end-tag is concerned.
    In HTML DTDs the two minimization parameters are required in all element declarations even when the end-tag is prohibited by the SGML standard.

    For reasons of common sense—and, as the note points out, this has nothing to do with markup minimization—when an element is declared to be empty then the end-tag must be omitted.

    If an element has a declared content of “EMPTY”, or an explicit content reference, the end-tag must be omitted.

    The SGML Handbook
    7.3 Element

    Also for reasons of common sense, end-tags that “must be omitted” cannot possibly be “optional tags”.

    The “O” may serve a different purpose in empty element declarations:

    Recall that the end-tag must always be omitted if an element has empty content, because anything that follows the start-tag must then be part of the containing element. Although this rule has nothing to do with markup
    minimization, it is helpful to mark the “O” as a reminder that no end-tags will be found in the document.

    The SGML Handbook
    C.1.2.3 End-tag Omission: Intruding Start-tag

    I.e. </area>, </img>, </input>etc. are not an optional tags in HTML 4 rather they are non-existent tags in HTML 4.

  16. On August 26, 2009, 14:00 CEST, Thomas Hühn said:

    Don’t expect OpenID discovery to work when omitting the HEAD start tag.

    Most implementations seem not to work under that circumstance. The widely used OpenID PHP library from openidenabled, for example.

  17. On August 24, 2010, 19:01 CEST, mozes66 said:

    1000 thanks.