HTML Formatter

Format and beautify HTML in your browser — nested markup indented consistently, tag balance checked first with exact error locations, nothing uploaded. Free, no sign-up — runs locally in your browser.

Your work is auto-saved in this browser only, so a refresh won't lose it. Nothing is uploaded.

…or drop a file onto the box above. Files are read locally, never uploaded.

What is an HTML formatter?

HTML that comes out of a template engine, a CMS, an email builder or a minifier is written for machines: no indentation, elements run together on a handful of enormous lines, and the nesting — the one thing you actually need to see — is invisible. An HTML formatter (also called a beautifier) rewrites that markup with consistent line breaks and indentation: every nested element steps in by one level, siblings line up, and the skeleton of the page becomes something you can read at a glance and diff without tears.

This one does a second job before it formats, the same discipline as this site's JSON tools: it checks the tag balance first. Unbalanced markup — a missing </div>, a </span> closed in the wrong order — is the single most common cause of layouts that "mysteriously" break, because browsers recover from it silently and unpredictably. If the structure does not check out, you get the line and column of the first problem instead of a confidently reformatted mess.

How to use this tool

  1. Paste your HTML into the box above (or press Load sample to see a worked example). You can also upload an .html file or drop one onto the box — the file is read in your browser and never sent anywhere.
  2. Choose an indent — 2 spaces is the common default for markup; 4 spaces and tabs are one click away.
  3. Press Format. If the markup is balanced you get the reformatted document and a line count. If it is not, you get the precise location of the first structural problem — fix that one and format again.
  4. Tick Auto-format as I type if you would rather not press the button: the result updates as you edit (very large inputs are still formatted on demand, to keep typing smooth). While the markup is mid-edit and unbalanced, the message line tells you so and your last good result stays on screen.
  5. Use Copy result or Download result to take the formatted document with you. Your input above is never modified — the result is a separate copy.

Checked first, then formatted

The balance check walks the document the way a browser's parser does, which means it knows the difference between markup and text. The contents of <script>, <style>, <textarea> and <title> are text, not tags: a </div> appearing inside a script string closes nothing, and a < in a comparison is not an error. Comments, doctypes and quoted attribute values (which may legitimately contain a >) are handled the same way. Inline SVG and MathML follow the XML rules that apply to them — self-closing elements, case-sensitive names — rather than the HTML rules around them.

The check also knows HTML's legal shorthand. Roughly a dozen elements may omit their end tag when the structure implies it: a new <li> closes the previous one, a block-level start tag closes an open <p>, a new table row closes the previous row's cells, and <html>, <head> and <body> need no closing tags at all. Markup that uses this shorthand passes the check, as it should. What fails is the genuinely ambiguous: an element still open when its parent closes, a closing tag with nothing to close, or a non-void element left open at the end of the document.

What formatting never changes

Formatting here is a layout rewrite, never a data rewrite. Tag names keep their spelling and case. Attributes are never reordered, added, removed or split across lines. Text content is carried across exactly; the contents of <pre> and <textarea>, where whitespace is part of the content, are preserved byte-for-byte. Comments survive. What changes is the whitespace between elements: indentation, the line breaks around block-level elements, and blank lines, of which at most one consecutive blank is kept, as authored. Inline runs — a sentence with links and emphasis inside a paragraph — stay together on a single line, so no new spaces appear inside your text.

Examples

This compressed fragment:

<section class="profile"><h2>Ada Lovelace</h2><p>Often called the first <strong>programmer</strong>.</p><ul><li>Notes</li><li>Letters</li></ul></section>

formats into:

<section class="profile">
  <h2>Ada Lovelace</h2>
  <p>Often called the first <strong>programmer</strong>.</p>
  <ul>
    <li>Notes</li>
    <li>Letters</li>
  </ul>
</section>

And this broken fragment — a <span> never closed inside its <div> — is reported with the span's opening position and the place where the problem surfaces, instead of being reformatted into a guess:

<div><span>Price: 42</div>

Common HTML mistakes this catches

Frequently asked questions

Is my HTML uploaded anywhere?

No. Checking and formatting happen in your browser, on this page. Nothing is sent to a server — you can disconnect from the network and the tool keeps working. Your draft is auto-saved in this browser only, for 7 days, and the Clear saved draft button deletes it immediately.

Why did the tool refuse to format my page?

Because the tag-balance check that runs first found a structural problem: a closing tag with no opening tag, an element left open, or an element closed in the wrong order. The error message gives the line and column of the problem (and, where relevant, where the unclosed element was opened). A formatter that cannot tell where an element ends has to guess — and a wrong guess silently restructures your page. Fix the first reported problem and format again; as with JSON, everything after the first error is usually a cascade.

What exactly does formatting change?

Only layout whitespace: indentation of nested elements, line breaks between block-level elements, and blank lines (at most one consecutive blank line is kept, as authored). Tag names, attribute order and values, and text content are never touched, and the contents of <pre> and <textarea> are preserved byte-for-byte, because whitespace is significant there.

Can formatting change how my page renders?

For ordinary markup, no: whitespace between block-level elements is not rendered, and runs of inline content — a sentence with <strong>, <em> and links inside a paragraph — are kept together on one line so no new rendered spaces appear. Two things deserve a glance after formatting: whitespace between inline elements does render as a space, and if your CSS displays an normally block-level element as inline, line breaks added around it can become visible spaces. Check the page once after a big reformat; the structure itself is unchanged.

Why is <div /> reported as never closed?

Because in HTML the trailing slash on a non-void element is ignored: <div /> opens a div that still needs its </div>. Only void elements — <br>, <img>, <input>, <hr> and their relatives, which can never have content — are complete without an end tag. Inside inline SVG or MathML the XML rules apply instead, and there the slash does close the element; this checker follows the same distinction.

Which end tags may I legally omit?

HTML allows the end tag to be omitted for a fixed list of elements when the structure makes the end unambiguous: li (a new li or the list's end closes it), p (most block-level start tags close it), td, th and tr in tables, option and optgroup, dt and dd, the table sections thead, tbody and tfoot, and the document-level html, head and body. This checker knows the list and the start tags that imply each close, so legal shorthand like <ul><li>one<li>two</ul> passes — while a missing </div> is still caught.

What happens to <script> and <style> contents?

Their contents are never mistaken for markup — a </div> inside a script string closes nothing — and they are re-indented along with the rest of the document using the standard formatting rules for each language, so an embedded script stays readable in context. If you want a large script formatted on its own, the JavaScript Formatter on this site gives it a page of its own.

Can I open an .html file instead of pasting?

Yes — use the Upload button or drag a file onto the input box. The file is read locally by your browser (it is never uploaded to a server), its contents land in the input box, and formatting runs immediately. Download result does the same job in the other direction.

Related tools