How to Format HTML: A Practical Guide to the HTML Formatter
Pretty-print minified or generated HTML into clean indented markup. How nesting, void tags, and inline elements format, all in your browser.
How to Format HTML: A Practical Guide to the HTML Formatter
Open view-source on almost any production page and you get the same thing: a single line that scrolls sideways forever. The page renders fine, but for a human trying to understand the structure, it is useless. Minifiers strip every line break and indent before shipping, and build tools, CMS exports, and email builders generate markup that was never indented in the first place. When you need to read that markup, you need it pretty-printed back into a shape your eyes can follow.
That is the whole job of the HTML Formatter: take messy or compressed HTML and rebuild it into clean, indented, line-per-element markup. This guide walks through how it decides where the line breaks and indent levels go, why void tags and inline elements get special treatment, and a worked example you can follow along with.
What pretty-printing actually does
Formatting HTML is not parsing it into a perfect DOM and serializing it back. It is a lighter, more forgiving pass: the tool walks the tag stream from start to finish, tracking how deep it is in the nesting, and decides for each tag whether to start a new line and how far to indent it.
The core rule is simple and worth stating plainly: each nested element indents one level deeper than its parent. Open a tag, the depth counter goes up. Close it, the counter comes back down. A <body> sits at depth zero, a <div> inside it at depth one, a <p> inside that div at depth two. The indent you see on screen is just that depth multiplied by your chosen unit, whether that is 2 spaces, 4 spaces, or a tab.
You pick the indent width to match your project. A lot of front-end style guides use 2 spaces; some teams prefer 4; tab people exist and have feelings about it. The formatter does not care which you choose, it just applies it consistently to every level.
Why void tags break the simple rule
Here is where a naive "open means indent, close means dedent" loop falls apart. Some HTML elements have no closing tag at all. They are called void elements, and the HTML5 spec lists exactly which ones they are: area, base, br, col, embed, hr, img, input, link, meta, param, source, track, and wbr.
A concrete point that trips up beginners and bad formatters alike: void tags like <img> have no closing tag, so they must not push the indent level deeper. If the formatter treated <img src="logo.png"> like an opening tag and bumped the depth, every element after it would drift one level to the right with no closing tag to ever bring it back. The output would slowly stair-step off the right edge of the screen.
So a good formatter recognizes void elements and lays them down at the current depth without changing the counter. <br>, <img>, <input>, <meta> each land on their own line, and the next sibling stays right where it should be. This is exactly what the HTML Formatter does, which is why pages full of <meta> tags in the head come out flat and tidy instead of cascading sideways.
Inline versus block: keeping sentences whole
The other judgment call is inline versus block elements. Block-level elements like div, section, ul, and p define structure, and you generally want each on its own line. Inline elements like span, a, b, and i flow within text, and breaking each one onto its own line shreds a readable sentence into one word per row.
Worse, it can change what renders. Whitespace between inline elements is significant. The space between two <a> links is a real, visible space on the page. If a formatter splits <a>one</a> <a>two</a> across separate lines, it can add or move that rendered gap. So the formatter gives you an inline-on-same-line switch: keep prose-style inline markup together so a paragraph stays a paragraph, and your formatting never silently alters the layout.
A few regions get protected entirely. The contents of pre, textarea, script, and style are passed through verbatim, byte for byte. Those are whitespace-significant or raw-text regions, and reindenting them would change what shows on screen or break the code outright. A <pre> block of ASCII art comes out exactly as it went in, only the tags around it get tidied.
A worked example
Say you pulled this minified fragment off a live page:
<ul class="nav"><li><a href="/">Home</a></li><li><a href="/about">About</a></li></ul>
One line, three nesting levels jammed together. Paste it in, choose 2-space indent and inline-on-same-line, and you get:
<ul class="nav">
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/about">About</a>
</li>
</ul>
Now the structure reads itself. The ul is at depth zero, each li indented one level under it, and each <a> indented one more level inside its li. The anchor text stays on the same line as its tag because it is inline content, so "Home" and "About" do not get pushed onto their own rows. The nesting that was invisible in the one-liner is now obvious at a glance, and you can find and edit any node without counting angle brackets by hand.
How I use it day to day
I keep this open in a pinned tab. The moment that earns its place most often is reading other people's pages. I will be inspecting why some layout breaks, open view-source, and get the usual wall of minified markup. I copy the chunk I care about, paste it into the formatter, and within a second I have an indented tree where I can actually trace which div wraps which. The other recurring save is CMS and email exports, which arrive as nested-table soup with inline styles and zero formatting. Beautifying them is the difference between editing by hand and giving up. I never feel weird pasting client markup in either, because the whole thing runs locally and nothing leaves the tab.
Local processing, and the round trip
Everything happens in your browser. The HTML is tokenized and reindented in plain JavaScript on your machine, never uploaded, logged, or stored on a server. The one caveat worth knowing: the shareable URL encodes your input in the query string, so if you paste a share link into chat, that markup lands in the recipient server's access log. For confidential page source or unreleased templates, use the copy button and paste the text instead of sharing the link.
Formatting is the reverse of minifying. A minifier strips whitespace and line breaks to shrink a file for shipping; a formatter adds them back so a person can read and edit. The two are a natural round trip: beautify while you work, then run the HTML Minifier before you deploy. The rendered page looks identical either way, because the whitespace a formatter adds between tags is the kind browsers ignore.
One last expectation to set: this tidies, it does not repair. It will indent broken markup, but it will not close your unclosed tags or fix invalid nesting. Feed it <div><p></div> and you get the same mismatch back, just indented. For correctness, reach for a validator. For readability, this is the fastest path from an unreadable line to markup you can actually work with.
Made by Toolora · Updated 2026-06-13