HTML Formatter & Beautifier

Free HTML formatter and beautifier. Pretty-print and indent HTML, or minify to remove whitespace and comments. Quote-aware, handles void tags. No upload.

Advertisement

HTML formatter: re-indent minified markup, or collapse it back down

Paste HTML into the box on the left and the formatted result appears on the right immediately — there is no "Format" button to press and nothing is uploaded. The whole tokenizer and printer run as JavaScript in your own browser tab, so build output, page source containing customer data, or a template you are not allowed to paste into a third-party service can all be reformatted without leaving the machine.

Two modes share the same parser. Beautify puts each element on its own line and indents by nesting depth, using 2 spaces, 4 spaces, or a tab — whichever you pick from the Indent menu. Minify removes the line breaks and indentation again, drops comments, and gives you a single line. The counter above the panes tells you which happened: Beautified 47 tokens, or Minified 1,204 → 968 chars (−236).

The usual reason people arrive here: unreadable build output

A bundler, a template engine, or a "view source" on a production page hands you one enormous line. Nothing is wrong with it — browsers do not care — but you cannot find the element you are looking for. That is what Beautify is for. The tool's own sample input is exactly this case:

<!DOCTYPE html><html><head><title>Demo</title><meta charset="utf-8"></head><body><nav class="main"><ul><li><a href="/?a=1&b=2">Home</a></li>…

Beautified with 2-space indent, that becomes a nested outline: <html> at column 0, <head> and <body> one level in, <title>Demo</title> collapsed onto a single line because it is a tag containing nothing but text, and <meta charset="utf-8"> sitting flat rather than opening a level of its own. Minifying the same sample goes from 297 characters to 279 — a small saving, because the only removable material is the HTML comment and the whitespace between tags. That ratio is worth internalising before you reach for minification as a performance fix: on real pages the wins come from compression and from the assets, not from the angle brackets.

What each mode does to each kind of token

TokenBeautifyMinify
Tags and attributesKept byte-for-byte, then indentedRuns of whitespace inside the tag collapse to one space
Text between tagsWhitespace collapsed, placed on its own lineWhitespace collapsed to one space
Whitespace-only textDroppedDropped
<!-- comments -->Kept, on their own lineRemoved
<!DOCTYPE>Kept verbatimKept verbatim
Void tags (<br>, <img>…)Own line, no extra indent levelKept
Bodies of script, style, pre, textareaEmitted verbatim, unindentedEmitted verbatim, byte-for-byte

Void elements, and why indentation stays sane

A naive indenter treats every opening tag as a level and every closing tag as a level back — then meets <br> or <img>, never sees a matching close tag, and marches the rest of the document off the right-hand side of the screen. HTML's void elements have no closing tag by definition, and this formatter knows all of them: area, base, br, col, embed, hr, img, input, link, meta, param, source, track, wbr. Each one is printed on its own line at the current depth and the depth is left alone. Explicitly self-closed tags — anything ending in />, which is how inline SVG is usually written — are treated the same way, so <path d="M0 0"/> inside an <svg> block does not derail the indent either.

The tag scanner is quote-aware, which matters more often than people expect. A > inside an attribute value — title="a>b", or a comparison operator inside an inline handler — does not end the tag early, because the scanner tracks whether it is inside a " or ' string while it looks for the closing bracket.

Whitespace that matters: pre, textarea, script, style

Everywhere else in an HTML document, a run of spaces, tabs, and newlines renders as a single space, so a formatter can move things around freely. Inside four elements it cannot. <pre> and <textarea> render their whitespace literally — re-indenting them visibly changes the page, adding leading spaces to every line of a code sample or silently editing a form's default value. <script> and <style> hold raw text rather than markup at all, and a < inside them (if (a < b)) is a less-than sign, not the start of a tag.

This tool captures the body of all four verbatim, from the opening tag to the matching close tag, and never touches the contents. In Minify mode the bytes come through exactly as they went in — your <pre> block keeps its trailing spaces and internal newlines. In Beautify mode the body is emitted at its original column rather than re-indented, with one small exception worth knowing: a leading newline and any trailing whitespace on the block are trimmed. If you need a byte-identical round trip of a <pre> block, use Minify.

Inline elements: beautify can add a space, minify can remove one

This is the one behaviour that genuinely changes how a page looks, and it is worth ten seconds of attention because it bites in both directions.

Beautify puts adjacent inline tags on separate lines. Give it <p><span>a</span><span>b</span></p> and each <span> lands on its own indented line. The newline and indentation are whitespace, and a browser renders whitespace between inline elements as a space — so what read as ab now reads as a b. On flowing prose that is invisible and harmless. On a run of inline-block cells, an icon sitting flush against a label, or digits joined to a superscript, it is a real one-space shift in the layout.

Minify drops whitespace-only text nodes entirely. The mirror image: <span>a</span> <span>b</span> minifies to <span>a</span><span>b</span> and the words run together. Note the precise rule — a text node that is only whitespace is removed, while a text node with any content keeps one space at each end. That is why <p>10 <sup>3</sup> m</p> survives minification unchanged (the spaces belong to the text nodes 10  and  m) while a lone space between two tags does not.

If a gap between inline elements is load-bearing, express it in CSS with margins or gap rather than relying on a whitespace text node, and neither mode can move it.

What minify changes inside your tags

Minify collapses whitespace runs inside a tag to a single space. That is what turns a tag whose attributes are spread over five lines back into one line, and it is usually exactly what you want. It also means that whitespace inside a quoted attribute value is collapsed: title="a    b" comes out as title="a b". Attribute values are single-line text almost all the time, so this rarely surfaces — but if you keep a multi-line JSON blob in a data- attribute, or a content= meta description with deliberate double spacing, check that attribute after minifying.

Everything else about your tags is left alone. Attribute order is preserved. Quoting style is preserved — src=x stays unquoted and single quotes stay single. Tag and attribute case is preserved, so <DIV CLASS="a"> does not become lowercase. Entities are never rewritten: &amp; stays &amp; and &b=2 in a query string is not "helpfully" escaped. Boolean attributes are not shortened, redundant attributes are not stripped, and no tag is ever removed for being optional. This is a whitespace-and-comments minifier, not an HTML optimiser in the mould of the aggressive build-time tools, and the output is markup you can still recognise as yours.

Broken markup: forgiving, but the indent tells on you

HTML is the most error-tolerant format in common use, and this formatter matches it: there is no error panel, because it never rejects input. It tokenizes what is there and prints it. That is a feature when you are formatting a fragment — a snippet with a stray </div>, a partial template, a chunk copied out of the middle of a page — and it means you never have to make a fragment well-formed just to read it.

The cost is that structural mistakes show up as indentation rather than as a message. Unclosed containers are the common case: <div><p>one<p>two</div> keeps stepping right, because each <p> opens a level that nothing closes. Browsers apply implied end tags here and would treat the two paragraphs as siblings; the formatter does not, and shows you the nesting you literally wrote. If beautified output drifts steadily rightward down the page, read that as a diagnosis: you have an unclosed element above the point where the drift starts. The same applies in reverse — a surplus close tag pulls the following content out to the left. If you need something that judges your markup rather than just re-indenting it, an HTML validator is the right tool; this one only reports what it sees.

Template syntax and conditional comments

Handlebars, Jinja, Liquid, ERB and friends are not HTML, but their delimiters are just text as far as the tokenizer is concerned, so they pass through unharmed. {{#each items}}, {% if user %} and {{ user.name }} come out identical — each on its own line when beautified, back inline when minified. What the formatter will not do is understand them, so a {% if %} that opens a <div> in one branch and not in the other will indent according to the literal tags in the file.

Legacy conditional comments are the one construct minification deletes outright. <!--[if IE]>…<![endif]--> is syntactically an HTML comment, so it is removed along with the rest. If you are still shipping one, minify around it rather than through it.

Questions people ask before pasting

  • Is my HTML uploaded anywhere? No. There is no network request — the parser, printer and minifier are all client-side JavaScript, and the page keeps working if you disconnect after it loads.
  • Is beautifying lossless? Structurally yes, textually almost: tags and their attributes are preserved exactly, but whitespace between elements is normalised, which can add a rendered space between adjacent inline tags as described above.
  • Is minifying safe to ship? For ordinary page markup, yes — it removes comments and inter-tag whitespace and nothing else. Check two things first: gaps between inline elements that you depend on, and whitespace inside attribute values.
  • Can I round-trip — minify, then beautify back? You will get equivalent, readable markup, not the original file. Comments are gone for good, and your original line breaks were discarded in the first pass. Beautify from the source you keep in version control, not from a minified copy, when it matters.
  • Does it reformat the CSS and JavaScript inside my page? No, deliberately — those blocks are passed through untouched. Run them through a dedicated CSS or JavaScript formatter and paste the result back.
  • How big a file can I paste? The limit is your browser's, not ours; the work is a single pass over the text. Very large documents will simply take a moment to redraw as you type.

If the markup you are cleaning up is really a data payload rather than a page, the XML formatter is the closer fit — XML is strict where HTML is forgiving, and it reports the parse errors that this tool intentionally does not.

Frequently Asked Questions

What is the difference between an HTML formatter and an HTML beautifier?+

They refer to the same thing. "HTML formatter" and "HTML beautifier" both describe re-indenting and pretty-printing HTML so the nested structure is easy to read. This tool does that in beautify mode and also offers a minify mode that goes the other direction by stripping whitespace and comments.

Does the formatter change how my page renders?+

No. Beautifying only adds or normalizes whitespace between tags, and browsers ignore insignificant whitespace, so the rendered page looks the same. Minifying removes whitespace and comments while preserving the single spaces that inline content needs, so the visible result is also unchanged.

Is my HTML uploaded anywhere?+

No. The entire formatter runs in your browser using JavaScript. Your markup never leaves your device, which makes it safe to format proprietary templates, client work, or anything confidential.

Will it break my inline scripts or styles?+

No. The contents of script, style, pre, and textarea elements are treated as raw text and preserved exactly as written, so JavaScript containing comparison operators or strings, and CSS inside style blocks, are never reflowed or corrupted.

Can it handle attributes that contain angle brackets?+

Yes. The tokenizer is quote-aware, so a greater-than or less-than character inside a quoted attribute value does not prematurely close the tag. This is a common failure point for regex-based formatters that this tool avoids.

Related tools

This tool is provided for informational and educational purposes only. All processing happens in your browser — no data is sent to or stored on our servers. While we strive for accuracy, we make no warranties about the completeness or reliability of results.