HTML Formatterhtmlformatteronline.com

HTML formatting best practices

Conventions that pay for themselves: the structural ones that affect real users, and the stylistic ones that stop code review turning into an argument about whitespace.

Structure

Declare the doctype, always

Without <!DOCTYPE html> on the first line, browsers switch to quirks mode and apply twenty-year-old layout rules. The box model changes. Your CSS stops behaving. It is one line and there is no situation where omitting it helps.

Set lang on the html element

<html lang="en"> tells screen readers which pronunciation rules to use and helps browsers offer translation correctly. A page in the wrong voice is close to unusable for someone relying on audio.

Use elements for what they mean

A <nav> rather than <div class="nav">. A <button> rather than a clickable <div>. Semantic elements come with keyboard behaviour, screen reader announcements and browser defaults that you would otherwise have to rebuild — usually incompletely.

Keep heading levels in order

One <h1> per page, then <h2> for sections, then <h3> beneath those. Do not skip levels to get a particular size — that is what CSS is for. Screen reader users navigate by heading, and a broken hierarchy is a broken table of contents.

Writing the markup

Lower-case tags and attribute names

HTML is case-insensitive, so <DIV> works. Mixed case in one file is still visual noise that costs a fraction of a second every time someone scans it. Lower-case is universal convention.

Double-quote every attribute value

HTML5 permits unquoted values, and permits single quotes. Neither is worth the inconsistency. Unquoted values also break silently the moment a value contains a space.

Avoid
<img src=photo.jpg alt=A photo of a cat>
Do this
<img src="photo.jpg" alt="A photo of a cat">

In the first example the alt attribute is the single word A, and photo, of, a and cat have become four separate boolean attributes. The browser will not tell you.

Do not close void elements

<br>, not <br /> or <br></br>. The XHTML slash is harmless but meaningless in HTML5, and the closing tag is invalid. The same applies to <img>, <hr>, <input>, <meta> and <link>.

Write closing tags even where they are optional

HTML lets you omit </li>, </p> and </td>. Do not. Explicit closures make nesting visible to the next reader and remove a whole class of ambiguity when something goes wrong.

Keeping it lean

Drop redundant attributes

type="text/javascript" on a script tag and type="text/css" on a stylesheet link are both defaults in HTML5. Boolean attributes need no value: required, not required="required".

Keep styling in the stylesheet

Inline style attributes are hard to override, impossible to reuse, invisible to your design system and a problem for Content Security Policy. The exceptions are genuinely dynamic values and HTML email, where inline styles are the only thing that reliably works.

Delete wrappers that do nothing

A <div> with no class, no id and one child is usually a leftover from a layout approach you have since abandoned. Formatting the file makes these obvious — they show up as a step in the indent with nothing to justify it.

Give every image an alt attribute

Descriptive text for images that carry meaning, and alt="" for purely decorative ones. Empty is correct and deliberate; missing is a failure. Screen readers announce the filename when alt is absent, which is worse than silence.

Formatting habits

Automate it

Format on save in your editor, or a pre-commit hook, or a CI check. Any of the three. What matters is that no human ever has to decide, because humans forget and then argue about it in code review.

Commit an .editorconfig

It is read by nearly every editor, often without a plugin, and it settles indent style, line endings and trailing whitespace for the whole project in eight lines.

Keep whitespace changes in their own commit

Reformatting a file touches every line. Mixed into a functional change, it makes the diff unreviewable. Separate commit, clear message, move on.

Validate before you ship

Structural checks catch unclosed tags and duplicate IDs in seconds. Run the validator on templates after a big edit, and the W3C service before a launch.

A reference skeleton

Everything above, applied to a page head.

Recommended head
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Descriptive, unique page title</title>
    <meta name="description" content="One sentence a search engine can show.">
    <link rel="canonical" href="https://example.com/page/">
    <link rel="stylesheet" href="/assets/css/site.css">
  </head>
  <body>
    <a class="skip" href="#main">Skip to content</a>
    <header>…</header>
    <main id="main">…</main>
    <footer>…</footer>
    <script src="/assets/js/site.js" defer></script>
  </body>
</html>

charset comes first because it must appear within the first 1024 bytes. The script carries defer so it does not block rendering. The skip link is the first focusable element on the page, which is what makes it useful.

Questions about this

Is there an official HTML style guide?

There is no single official one. Google's HTML/CSS Style Guide is the most widely cited and is a reasonable default. The WHATWG specification defines what is valid, not what is stylish. Whatever you adopt, write it down and make a tool enforce it.

Do these rules matter for a small personal site?

The structural ones do — doctype, lang, alt text and heading order affect real people using screen readers regardless of how many visitors you have. The formatting conventions matter mostly in proportion to how many people touch the file.

Should I use XHTML-style self-closing tags?

No, not in an HTML5 document. <br /> is parsed identically to <br>, so it is harmless, but it signals a document type you are not using. The exception is inline SVG, where XML rules apply and self-closing tags are required.

How strict should I be about semantic elements?

Strict where it changes behaviour, relaxed where it does not. <button> versus a clickable <div> is a real accessibility difference and worth insisting on. <section> versus <div> for a generic wrapper rarely changes anything for anyone.

Try it on your own file

The formatter, minifier and validator are all on the front page.

Open the formatter

Keep reading