The 6 Ways of Writing HTML (and Their Combinations)

Published on November 23, 2021 (↻ August 17, 2024), filed under (RSS feed for all categories).

Everyone can write HTML, until they find out they can’t. HTML, currently clocking in at 2,185 pages (PDF), is massive, and there’s evidence that it takes study and practice to master.

(The hubris exists and is significant. With so many people saying they know HTML, the attitude towards HTML is the IT industry’s equivalent to Germany having 80 million professional football coaches.)

Because of specification size and complexity, as well as differences in developer attitude and professionalism, there are several ways of writing HTML (6), and combinations thereof (19). This article documents these ways and combinations. If the reasoning is correct, everyone’s particular way of HTML should be reflected, allowing to consciously opt for another, if desired.

Contents

  1. The 6 General Ways of Writing HTML
    1. Unsystematic
    2. Valid
    3. Semantic
    4. Accessible
    5. Required-Only
    6. Hyper-Optimized
  2. The 19 Combinations of Writing HTML
    1. Popular Combinations of Writing HTML
    2. Recommended Combinations of Writing HTML

The 6 General Ways of Writing HTML

1. Unsystematic

This HTML writing style is naive or, nicer, unsystematic. The elements of HTML are not yet learned, the idea of semantics not entirely understood, output verification lacking when it comes to testing and not existing for validation, optimization options not yet known, and concepts like accessibility still foreign.

It’s usually the incomplete map of HTML elements that contributes the most to this style, where pragmatism reigns and where “divitis” and “classitis” are among the symptoms.

An example for the unsystematic type is this, taken from a random live site. The code is all over the place and it’s hard to consider the work professional:

  <!DOCTYPE html>
<!--[if IE 7]>
<html class="ie ie7" lang="en-US">
<![endif]-->
<!--[if IE 8]>
<html class="ie ie8" lang="en-US">
<![endif]-->
<!--[if !(IE 7) & !(IE 8)]><!-->
<html lang="en-US">
<!--<![endif]-->
<head>
<!-- snip -->

</head>

<body class="home page-template page-template-page-templates page-template-page-homepage page-template-page-templatespage-homepage-php page page-id-23 custom-font-enabled single-author">

    <!-- snip -->
      <script type="text/javascript">
      // snip
    </script>

<div id="page" class="hfeed site">
  <header id="masthead" class="site-header" role="banner">
    <div id="hamburger-menu"><span></span><span></span><span></span></div>

    <a href="https://example.com"><img id="pagelogo" src="https://example.com/wp-content/uploads/2016/08/logo.png"></a>

    <nav id="site-navigation" class="main-navigation" role="navigation">
      <div class="secondmenusection">
        <div class="menu-main-menu-container"><ul id="menu-main-menu" class="nav-menu"><li id="menu-item-262" class="work menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-262"><a href="http://example.com/work/">Work</a>
<ul class="sub-menu">
  <li id="menu-item-265" class="all menu-item menu-item-type-custom menu-item-object-custom menu-item-265"><a href="http://example.com/all/">Main</a></li>
  <li id="menu-item-562" class="menu-item menu-item-type-taxonomy menu-item-object-gal-categories menu-item-562"><a href="https://example.com/gal-categories/classic/">Classic</a></li>
</ul>
</li>
<li id="menu-item-21" class="biography menu-item menu-item-type-post_type menu-item-object-page menu-item-21"><a href="https://example.com/biography/">Biography</a></li>
<li id="menu-item-942" class="download hide_item__ menu-item menu-item-type-post_type menu-item-object-page menu-item-942"><a href="https://example.com/downloads/">Download</a></li>
<li id="menu-item-22" class="contact menu-item menu-item-type-post_type menu-item-object-page menu-item-22"><a href="https://example.com/contact/">Contact</a></li>
<li id="menu-item-299" class="instagram menu-item menu-item-type-custom menu-item-object-custom menu-item-299"><a target="_blank" rel="noopener" href="https://www.instagram.com/example/"><i class="fa fa-instagram"></i></a></li>
</ul></div>        <p class="create_foo"><span class="create_foo_icon"></span><span class="create_foo_text">Create Foo</span></p>
        <p class="client_login login"><span class="client_login_icon"></span><span class="client_login_text">Client Login</span></p>
              </div>
    </nav>

    <div id="zooms">
      <span class="fa plus"></span>
      <span class="fa minus"></span>
      <span class="fa grid"></span>
      <!--<i class="fa fa-plus"></i>
      <i class="fa fa-minus"></i>-->
    </div>

    <span class="float-down-arrow"></span>
  </header>

<!-- stop stop snip -->

2. Valid

The next succinct HTML style revolves around a baseline quality attribute for HTML: It’s valid. That’s sometimes all that is to see here, as the markup may not make the best use of elements yet. But, a sign of a professional developer attitude and of getting the basics right, at least the code is syntactically correct.

Here, an example for a valid page (by myself, out of convenience):

<!DOCTYPE html>
<meta charset=utf-8>
<meta name=viewport content="initial-scale=1,minimum-scale=1,width=device-width">
<meta property="og:image" content="https://mirrors.meiert.org/havewestoppedkillingyet.org/media/redrum.png">
<title>Have We Stopped Killing Yet?</title>
<link rel=icon href=favicon.ico>
<link rel=stylesheet href=setup/default.css>
<h1>Have We Stopped Killing<a href=https://meiert.com/en/blog/on-taking-life/><sup>*</sup></a> Yet?</h1>
<p><strong>No.</strong>
<p>This is unacceptable.
<p>We don’t need arms and armies and industrial slaughterhouses.
<p>We need respect for life.
<p>Everyone can <em>do something</em>. Speaking up is doing something. <a href=https://meiert.com/en/><img src=https://hell.meiert.org/core/png/meiert-logo-80x80-alt.png alt="Jens Oliver Meiert"></a>

3. Semantic

Another HTML style is the semantic one. Here, noticeable attention is being paid to using the correct elements and, if available, microformats or microdata. This style exhales the idea of meaning in HTML, with a palpable desire not to resort only to div elements.

The following is an example, also by myself (not because of me but because it’s hard to find a page that is long enough to serve as an example, but not so long as to dominate an article; and at the same time use enough markup to be meaningful, but not so much as to cloud the point):

<!DOCTYPE html>
<meta charset=utf-8>
<meta name=viewport content="initial-scale=1,minimum-scale=1,width=device-width">
<meta name=description property=og:description content="Edited">
<meta name=twitter:card content=summary>
<meta property=og:title content="UITest.com · Web Development Tools · Analyze Your Website, Explore Dev Tools">
<meta property="og:image" content="https://d2g3fg8cn2k57g.cloudfront.net/media/logo-social.png">
<title>UITest.com · Web Development Tools · Analyze Your Website, Explore Dev Tools</title>
<link rel=stylesheet href=https://d2g3fg8cn2k57g.cloudfront.net/setup/default.min.css>
<link rel=alternate href=/feed/ type=application/rss+xml title="All tools">
<header>
  <img src=https://d2g3fg8cn2k57g.cloudfront.net/media/logo.svg alt=UITest.com>
</header>
<section id=check>
  <h1><a href=/check/>Site Check</a></h1>
  <p>Test your website in more than 80 tools:
  <form action=/check/results/ method=post>
    <label for=url>URL:</label>
    <input type=url name=url id=url required inputmode=url placeholder=https://>
    <button>Go</button>
  </form>
</section>
<section>
  <h1><a href=/analysis/>Analyze Your Website</a></h1>
  <p><a href=/analysis/#general>General</a>, <a href=/analysis/#accessibility>Accessibility</a>, <a href=/analysis/#code>Code</a> <!-- snip -->
  <p>UITest.com favorite: <a href=https://www.webpagetest.org/>Website Performance Analysis (WebPageTest)</a>
</section>
<section>
  <h1><a href=/exploration/>Explore Dev Tools</a></h1>
  <p><a href=/exploration/#testing>Browser Testing</a>, <a href=/exploration/#auditing>Code Auditing</a>, <a href=/exploration/#generation>Code Generation</a> <!-- snip -->
  <p>UITest.com favorite: <a href=https://coolors.co/generate>Color Scheme Generator (Coolors)</a>
</section>
<section>
  <h1>Stay Up-to-Date</h1>
  <p>The latest additions to UITest.com (usually one per week):
  <ul>
    <li><a href=https://gf.dev/http3-test>HTTP/3 Test</a>
    <li><a href=https://www.seowl.co/title-rewrite-checker/>Google Title Rewrite Check</a>
    <li><a href=https://webspeedtest.cloudinary.com/>Image Performance Analysis</a>
  </ul>
  <p>Never miss new tools: <a href=/feed/>Subscribe to RSS feed</a> or <a href=https://twitter.com/uitestcom>follow UITest.com on Twitter</a>.
</section>
<footer>
  <ul>
    <li><a href=/feed/>Feed</a>
    <li><a href=https://twitter.com/uitestcom>Twitter</a>
  </ul>
  <ul>
    <li>Home
    <li><a href=/analysis/>Analysis</a>
    <li><a href=/exploration/>Exploration</a>
    <li><a href=/check/>Site Check</a>
    <li><a href=/contact/>Contact & Legal</a>
  </ul>
  <p>Last update: September 22, 2021
  <p>UITest.com: for people who test websites âœ“
  <p id=promo>Learning Web Development? Check out the <a href=https://leanpub.com/b/web-development-foundations-plus>Web Development Foundations book bundle</a>!
</footer>

4. Accessible

A style distinct even from the semantic style (more on that in a second) is the accessible one. This one prioritizes accessibility over everything else and can typically be recognized by two things: WCAG focus as well as eager (and sometimes overeager) use of ARIA:

<!DOCTYPE html>
<html lang="en">
<head>

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <meta name="theme-color" content="#e6e6e6" media="(prefers-color-scheme: light)">
  <meta name="theme-color" content="#636366" media="(prefers-color-scheme: dark)">
  <link rel="canonical" href="https://example.com" />

<title>Home · Example</title>
<meta content="" name="description">
<meta content="" name="keywords">

<meta content="Home · Example" property="og:title">
<meta content="website" property="og:type">
<meta content="Example" property="og:site_name">
<meta content="https://example.com" property="og:url">
<meta content="" property="og:image">
<meta content="" property="og:description">
<meta content="en_GB" property="og:locale">

<!-- snip -->

<meta content="index, follow, noodp" name="robots">

    <link href="https://example.com/assets/css/prism.css" rel="stylesheet">
<link href="https://example.com/assets/css/index-dist.css" rel="stylesheet">
<link href="https://example.com/assets/css/templates/home.css" rel="stylesheet">
  <link rel="openid.delegate" href="https://example.net/">
  <link rel="openid.server" href="https://id.example.net/" />
  <link rel="openid2.provider" href="https://id.example.net/" />
  <meta data-embetty-server="https://example.net/embetty">
  <link rel="shortcut icon" type="image/x-icon" href="https://example.com/favicon.ico">
  <link rel="alternate" type="application/rss+xml" title="Latest articles" href="https://example.com/feed"/>
  <link rel="alternate" type="application/json" title="Latest articles" href="https://example.com/feed/json"/>
  <script defer data-domain="example.net" src="https://stats.example.net/js/index.js"></script>

</head>
<body>

  <header class="header">
        <a class="logo" href="https://example.com">
      Example    </a>

    <nav class="menu" aria-label="main">
                  <a  href="https://example.com/blog">Blog</a>
            <a  href="https://example.com/videos">Videos</a>
            <a  href="https://example.com/talks">Talks</a>
            <a  href="https://example.com/about">About</a>
            <span class="social">
    <a href="https://twitter.com/example" aria-label="Twitter">
    <!-- snip -->  </a>
    <a href="https://youtube.com/example" aria-label="YouTube">
    <!-- snip -->  </a>
  </span>
    </nav>
  </header>

  <main class="main">

<header class="h1">
  <h1>Example</h1>
    <p class="subheadline">Edited</p>
  </header>

<div class="text">
  <img class="avatar" src="https://example.com/media/pages/home/a85119863c-1633597165/avatar.example.net.jpeg" alt="Example, edited.">
  <p>Edited.</p><div class="clients">
  <h2 class="h2">Recommended By:</h2>
  <div class="gallery">
          <div>
        <img role="img" src="https://example.com/media/pages/home/foo.svg" alt="Edited">
      </div>
          <div>
        <img role="img" src="https://example.com/media/pages/home/bar.png" alt="Edited">
      </div>
          <div>
        <img role="img" src="https://example.com/media/pages/home/baz.svg" alt="Edited">
      </div>
          <div>
        <img role="img" src="https://example.com/media/pages/home/scribble.svg" alt="Edited">
      </div>
          <div>
        <img role="img" src="https://example.com/media/pages/home/screech.svg" alt="Edited">
      </div>
      </div>
</div>
<div id="insert_steady_checkout_here" style="display: none;"></div>
</div>

  </main>

  <footer class="footer">
    <div class="grid">
      <section class="column" style="--columns: 8">
        <h2>Example</h2>
        <p>
          Edited
        </p>
      </section>
      <section class="column" style="--columns: 2">
        <h2>Feeds</h2>
        <ul>
          <li><a href="https://example.com/feed">RSS Feed</a></li>
          <li><a href="https://example.com/feed/">JSON Feed</a></li>
        </ul>
      </section>
      <section class="column" style="--columns: 2">
        <h2>Pages</h2>
        <!-- snip -->
      </section>
    </div>
  </footer>

  <script src="https://example.com/assets/js/prism.js"></script>
<script src="https://example.com/assets/js/embetty.js"></script>
<script src="https://example.com/assets/js/index.js"></script>

</body>
</html>

Why is this not the same as the semantic style? In short, because the semantic and accessible approaches reflect two different schools; they walk a good part of the way together, but they’re not identical. A technical manifestation of this is that the semantic school often makes use of microformats and microdata, while the accessible school likes ARIA.

A more general view is that accessible markup must not by necessity be semantic—at least not if you assign the native meaning of HTML elements more weight than that of added-on ARIA markup. In other words, we cannot—a semantic school advocate would not—view <h1>Heading</h1> and <div role=heading aria-level=1>Heading</div> as equivalent. That would need to be the case to defend the idea that the accessible way of writing HTML is necessarily also the semantic one.

5. Required-Only

With the “required-only” HTML writing style, the idea is only to use the markup (as well as other code) that is strictly needed. It is the style of minimal web development and the one that avoids using optional markup, even in development.

The required-only style gives you boilerplate HTML like this, not only shedding optional code but also the idea that one could actually have any boilerplate HTML:

<!DOCTYPE html>
<title>␣</title>

6. Hyper-Optimized

The final style we can distinguish is the one of “hyper-optimized” HTML. This is the style that uses anything to minimize code and payload—as such it is a subset of the “required-only” style—, including parse errors. Barely anyone ever uses this style—for both good and bad reasons.

The bad reason first: HTML is decades old, but with some developers make-believing themselves into knowing it after five minutes, the highest step in evolution for a frontend developer may often be the unsystematic style, and in some cases the semantic one.

The good reason is that the hyper-optimized style is super-hard to play, with marginal returns and no (or little) tooling to support. We can probably be happy no one makes use of this style.

<!doctypehtml><title>Everyone knows HTML</title><img alt="My logo"src=logo><! TODO: write rest of doc >

This code is completely made up. It’s not valid. It works. It makes use of the “missing-whitespace-between-attributes” and “incorrectly-opened-comment” parse errors. It’s hyper-optimized.

The 19 Combinations of Writing HTML

The 6 general ways of writing HTML now lead to the following 19 combinations of writing HTML. It’s a list of ways that are compatible with each other.

The list doesn’t include random combinations—for example, when a unsystematically written document happens to be valid.

  1. Unsystematic
  2. Valid
  3. Valid, semantic
  4. Valid, semantic, accessible
  5. Valid, semantic, accessible, required-only
  6. Valid, accessible
  7. Valid, accessible, required-only
  8. Valid, required-only
  9. Semantic
  10. Semantic, accessible
  11. Semantic, accessible, required-only
  12. Semantic, accessible, required-only, hyper-optimized
  13. Semantic, required-only
  14. Semantic, required-only, hyper-optimized
  15. Accessible
  16. Accessible, required-only
  17. Accessible, required-only, hyper-optimized
  18. Required-only
  19. Required-only, hyper-optimized

These are the 19 specific ways we write HTML.

Does this miss a combination, or have I not explained something well? Let me know!

Popular Combinations of Writing HTML

When you go through the list, you’ll notice that some styles are styles we advocate and aspire to, that others feel common, and that a couple look unusual. I’d roughly order the main ones like this, in descending order of perceived popularity:

  1. Unsystematic (a large part of web pages)
  2. Semantic (largest minority style)
  3. Accessible
  4. Semantic, accessible
  5. Valid, semantic (quite rare, <2% of web pages)
  6. Valid, accessible

Recommended Combinations of Writing HTML

Identifying HTML writing styles and recommending HTML writing styles are, I believe, the real use cases for this categorization. In my mind, the following are the styles we should promote, in ascending order of both usefulness and difficulty:

  1. Valid
  2. Valid, semantic, accessible
  3. Valid, semantic, accessible, required-only

Why this order?

  1. Valid: baseline quality bar to aim for; invalid markup is unprofessional.
  2. Valid, semantic, accessible: semantic markup is largely accessible markup; although there’s one to be made (see earlier notes), there seems little merit in emphasizing the distinction.
  3. Valid, semantic, accessible, required-only: as a general rule, it makes sense to also leave out optional code.

Even if our field was so advanced as to be ready for the hyper-optimized style, the gains are too small to sacrifice the great value of validity and conformance (which is incompatible with it) as a quality standard. It is an HTML writing style, but a hypothetical rather than a practically useful one.

❧ These are the 6 ways of writing HTML, and their 19 combinations. Which way or combination is yours? Which one do you aspire to? Follow up on this post’s tweet, or reach out directly! And while I recommend everyone to make the valid way part of their own style, it’s important to internalize this: HTML is the most important web standard. It’s worth mastering it.

Many thanks to Thomas Steiner for reviewing this post.

Was this useful or interesting? Share (toot) this post, and support my work by learning with my ebooks!

About Me

Jens Oliver Meiert, on November 9, 2024.

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 a contributor to several web standards, 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 experiences and views. (Please be critical, interpret charitably, and give feedback.)