HTML Beautifier & Minifier — Free Online Tool
Indent minified HTML or strip it back down. Seven indent presets, void-element aware, and pre/script/style/textarea content is preserved byte for byte.
Use this free online HTML Beautifier & Minifier directly in your browser. No signup required, no data leaves your device. Part of Utilier — a collection of 133+ developer utilities.
What is HTML Beautifier & Minifier?
Beautifying HTML means putting every tag and text run on its own line and indenting it by nesting depth, so the tree structure of a document becomes visible at a glance. This tool does that with a tag-level tokeniser rather than a full parser: it splits the source on angle brackets, tracks depth as it opens and closes elements, and knows which elements never close. Minify runs the same protection logic in reverse, collapsing inter-tag whitespace and deleting comments.
- Two actions, one input: Beautify indents by depth using the width you pick. Minify strips HTML comments, collapses whitespace between tags, joins the document onto one line, and reports the resulting character count in the status line.
- Raw-text elements are protected: Before anything else runs, the contents of <pre>, <textarea>, <script> and <style> are lifted out and substituted back afterwards untouched. That is what stops a beautifier from breaking the visible layout of preformatted text or corrupting a template literal inside a script.
- Void-element aware: Fourteen element names — area, base, br, col, embed, hr, img, input, link, meta, param, source, track and wbr — never increase the indent level, because they have no end tag. Self-closing syntax (/>) is treated the same way.
- Seven indent presets: 1, 2, 3, 4 and 8 spaces, plus 1 tab and 2 tabs. Two spaces matches the Google HTML/CSS style guide; tabs are emitted as real U+0009 characters.
- Input sanity check: Both actions require the input to contain something that looks like a tag. Paste plain prose and you get "Input doesn't appear to be valid HTML. Expected HTML tags." rather than a mangled result.
Why use the HTML beautifier?
Server-rendered and bundled HTML arrives as one enormous line, and no amount of horizontal scrolling makes a nesting bug obvious. Indentation is what turns that into a readable tree.
- Unclosed tags become visible: A missing </div> shows up as an indent level that never comes back to the left margin. That is far faster than reading a validator's error list, because you can see exactly which subtree swallowed the rest of the page.
- Makes View Source usable: Copy the markup a framework actually shipped, beautify it, and you can compare what you wrote against what the server or hydration produced — including injected wrappers, reordered attributes, and elements the parser moved.
- Turns diffs into something reviewable: Two minified templates diff as one changed line. Beautify both with the same indent width and a review comment can point at a specific element instead of "somewhere in line 1".
- Measures the cost of markup: Minify reports the character count, so you can see what comments, indentation and blank lines actually cost before compression. Useful when auditing an email template or an inlined critical-path fragment.
- Stays on your machine: Everything runs in the page. Markup pulled from an authenticated admin view, a staging environment, or a customer's page can be inspected without sending it anywhere.
When to use the HTML beautifier
Reach for it when markup is unreadable, when you suspect the structure is wrong, or when you need to know what the bytes cost.
- Reading server-rendered output copied out of View Source or the Elements panel, where the whole document is a single line.
- Hunting an unclosed or mismatched tag that is causing a layout to collapse or a section to nest inside the wrong parent.
- Reviewing a change to a template that a build step has already minified, so a normal diff is useless.
- Cleaning up markup exported from a CMS, a WYSIWYG editor, or an email builder before checking it into a repository.
- Preparing a fragment for documentation or a bug report, where readers need to see structure rather than a wall of text.
- Minifying a small standalone page, an AMP-style fragment, or an inline critical-path snippet where you want the byte count without adding a build step.
- Comparing the markup two browsers or two framework versions produce for the same component.
How to use the HTML beautifier
One input, one output, two buttons. The indent setting only affects Beautify.
- Paste or upload the markup: Paste into the "HTML in" pane, or press Upload .html to load a file (the picker accepts .html and .htm, and the file is checked for tag-like content before it loads).
- Choose an indent width: Pick 1, 2, 3, 4 or 8 spaces, or 1 or 2 tabs. Two spaces is the common web default; match whatever your editor config and the rest of the repository already use.
- Press Beautify: Each tag and each text run is placed on its own line, indented by nesting depth. Doctypes, comments and processing instructions are emitted at the current level. The status line confirms "Beautified".
- Or press Minify: Comments are removed, whitespace between tags is deleted, runs of spaces and tabs collapse to one, and newlines go. The status reports the resulting length, for example "Minified (412 chars)".
- Check what was preserved: Look at any <pre>, <textarea>, <script> or <style> block in the output — its contents should be byte-identical to the input. If it is not, the opening and closing tags were mismatched in the source.
- Copy or download the result: Use the controls on the output pane. Re-run Beautify after editing to confirm the indentation still resolves back to the left margin at the end of the document.
Key features
- Raw-text preservation: <pre>, <textarea>, <script> and <style> contents are extracted before formatting and restored afterwards unchanged, so whitespace-significant and code content survives both actions.
- Depth tracking with a void list: Fourteen void element names plus explicit /> syntax are excluded from depth increments, which keeps <img>, <br> and <input> from indenting everything after them.
- Comment stripping on minify: All <!-- … --> comments outside protected blocks are removed, including conditional-comment leftovers and build markers.
- Character-count feedback: Minify reports the exact output length in the status line, so you can measure a template before and after a change.
- Seven indent presets: 1/2/3/4/8 spaces and 1/2 tabs, with tabs written as real tab characters rather than expanded to spaces.
- File upload with a content check: Upload .html loads a file from disk and rejects anything that does not contain tag-like markup, so a mis-picked file fails loudly instead of silently.
Common use cases
- Reading production output: Beautify the single-line HTML a server or SSR framework emitted to see the real element tree.
- Finding structural bugs: Spot an unclosed element by the indent level that never returns to zero.
- Template code review: Format both sides of a minified template change so reviewers can comment on specific elements.
- CMS and email cleanup: Normalise markup pasted out of a WYSIWYG editor or an email builder before committing it.
- Byte auditing: Minify a fragment to see what comments and indentation cost before compression is applied.
- Teaching and documentation: Produce clean, indented snippets for a tutorial, style guide, or issue report.
Examples
Actual output from this tool. Indent is 2 spaces unless noted.
Beautify a minified fragment
<div class="card"><h2>Title</h2><img src="a.png" alt=""><ul><li>One</li><li>Two</li></ul></div><div class="card"> <h2> Title </h2> <img src="a.png" alt=""> <ul> <li> One </li> <li> Two </li> </ul>
</div>Text runs get their own line, so the structure is maximally explicit. <img> is void, so nothing after it is indented further — compare that with what happens if you hand-write </img>.
Minify, with comments removed and <pre> intact
<!-- nav -->
<div class="card"> <p>Hello <b>world</b></p> <pre>keep me</pre>
</div><div class="card"><p>Hello <b>world</b></p><pre>keep me</pre></div>The comment is gone and the three spaces before <b> collapse to one, but the newline and indentation inside <pre> survive exactly, because <pre> content is protected before minification starts.
An unclosed tag, made obvious
<section><header><h1>Docs</h1></section><footer>End</footer><section> <header> <h1> Docs </h1> </section> <footer> End </footer><header> never closes, so </section> is consumed as its closer and lands at depth 1 instead of column zero — and everything after it stays indented. Output that never returns to the left margin is the signature of a missing end tag.
Inline elements gain whitespace
<p>Total: <strong>42</strong><span>%</span></p><p> Total: <strong> 42 </strong> <span> % </span>
</p>Rendered, this now reads "42 %" with a space, because whitespace between inline elements collapses to one space instead of vanishing. Beautify markup you are reading, not markup you are shipping, when inline spacing matters.
Technical reference
The HTML rules this tool relies on:
- Specification
- WHATWG HTML Standard, §13.1 "Writing HTML documents" (syntax) — a living standard, not a versioned one
- Void elements
- area, base, br, col, embed, hr, img, input, link, meta, source, track, wbr in the current spec. This tool also treats the legacy param as void
- Raw text / escapable raw text
- <script> and <style> are raw text; <textarea> and <title> are escapable raw text. Their contents are not parsed as markup
- Preformatted content
- <pre> and <textarea> render whitespace and newlines literally (white-space: pre), so reindenting inside them changes what the user sees
- Inline whitespace
- Whitespace between inline-level elements collapses to a single rendered space rather than disappearing, which is why adding newlines can change layout
- Comment syntax
- <!-- … --> ; the text must not start with > or ->, and must not contain -- or end with -
- Self-closing syntax
- A trailing / is permitted on void elements and on foreign (SVG/MathML) elements only. On an ordinary HTML element such as <div /> it is ignored, and the element stays open
- Indent convention
- The Google HTML/CSS Style Guide specifies 2 spaces per level and no tabs; this tool offers 1–8 spaces and tabs so you can match any house style
Common mistakes to avoid
Beautifying markup that is whitespace-sensitive and then shipping it
Why it happens: Whitespace between inline-level boxes is not discarded — the HTML/CSS rendering model collapses it to a single space. So inserting newlines between </strong> and <span>, or between two inline-block items in a grid built from inline-blocks, adds visible gaps that were not there before. This is the classic cause of "the layout shifted after I formatted the template" and of stray spaces appearing inside buttons and badges.
How to avoid it: Use Beautify to read and audit markup, and keep the minified or original form as the artefact you deploy. When you do need to reformat production templates, set white-space or display explicitly on the affected containers, use flex or grid instead of inline-block layouts, or keep inline runs on a single line. Verify visually after reformatting rather than assuming HTML whitespace is free.
Writing end tags or /> on void elements
Why it happens: Void elements have no end tag, so </img> or </br> is a parse error the browser discards, and <div /> does not close the div at all — the trailing slash is only meaningful on void and foreign elements. Authors coming from XHTML or JSX carry the habit over, and the result is markup where the depth a formatter computes and the DOM a browser builds disagree.
How to avoid it: Write void elements as a single start tag: <img src="…" alt="…">, <br>, <input>, <hr>. A trailing slash is harmless on those if a linter or template language requires it, but never add one to a container element. If beautified output shows an element indenting everything after it that should not, check whether it is a container you closed with /> instead of a real end tag.
Minifying HTML that relies on significant spaces between tags
Why it happens: Minify deletes whitespace between tags entirely (>\s+< becomes ><). That is exactly what you want for block layout, and exactly wrong where a single space was doing visual work — between two inline links, around a separator like <span>·</span>, or between adjacent inline-block cards. The page renders, so nothing fails; the words simply run together.
How to avoid it: Put deliberate spacing in CSS (margin, gap, or word-spacing) rather than in the markup, so it cannot be minified away. Where a literal space must survive, use — an entity is a character, not whitespace, and is preserved. Always compare the rendered result before and after minifying a template that contains inline content.
Expecting a formatter to fix or validate broken markup
Why it happens: This tool tracks depth from the tags it sees; it does not implement the HTML parsing algorithm, so it cannot apply implied end tags, foster-parent misplaced table content, or reorder elements the way a browser does. Mismatched tags produce mismatched indentation rather than an error, and a document a formatter happily indents can still be invalid. A browser's DOM may differ from the indentation you are looking at.
How to avoid it: Treat the beautified output as a hypothesis about structure and confirm it against the real DOM in the Elements panel, or run the document through the W3C validator for a conformance verdict. Fix reported errors in the source, then re-beautify: correct markup returns to column zero at the end of the document, which is a quick sanity check you can apply without leaving the page.
Frequently asked questions
How do I format minified HTML so it is readable again?
Paste it into the input, choose an indent width, and press Beautify. Every tag and text run is placed on its own line and indented by nesting depth, so the element tree becomes visible. The contents of <pre>, <textarea>, <script> and <style> are preserved byte for byte, so scripts and preformatted text are not damaged. Note that this is a formatting operation for reading and reviewing, not a round trip you should deploy: the added whitespace between inline elements is rendered as a space, so keep the original for production.
Does beautifying HTML change how the page looks?
It can. Whitespace between block-level elements has no visual effect, but whitespace between inline-level elements collapses to a single rendered space rather than disappearing. So splitting <strong>42</strong><span>%</span> across lines turns "42%" into "42 %". Content inside <pre> and <textarea> is protected here precisely because it is whitespace-significant. The safe pattern is to beautify for inspection and review, and to control real spacing with CSS margin, gap or word-spacing so that reformatting cannot alter it.
Which HTML elements are void elements?
The current WHATWG HTML Standard lists thirteen: area, base, br, col, embed, hr, img, input, link, meta, source, track and wbr. They have a start tag only — an end tag is a parse error — and they cannot contain child nodes. This tool treats those thirteen plus the legacy param as void, so none of them increases the indent level. Knowing the list matters when reading beautified output: if an element you expected to be self-contained is indenting everything below it, it is not a void element and needs a real closing tag.
Is <div /> valid HTML5?
No, not in the sense people usually mean. A trailing slash is permitted on void elements and on foreign elements from SVG and MathML, where it genuinely closes the element. On an ordinary HTML element the slash is ignored by the parser, so <div /> opens a div that stays open and swallows the following content. JSX and XHTML both allow self-closing on any element, which is where the habit comes from. In HTML you must write <div></div>. Beautified output makes the mistake obvious, because the div's subtree never ends.
Should I minify HTML if the server already uses gzip or Brotli?
The gain is real but modest. Compression handles repeated indentation and comments very efficiently, so minifying typically saves a few percent of the compressed size rather than the 20–30% the raw character count suggests. It is still worth doing in a build step because it is free at runtime, and it matters more for content that is not compressed — HTML email, inlined critical fragments, or documents served from a source that has compression disabled. Use Minify here to get the before-and-after character counts for your own markup.
Why does my <script> or <style> block come out unchanged?
That is deliberate. <script> and <style> are raw-text elements: their contents are not markup, so a tag-level formatter must not touch them. Both actions extract those blocks — along with <pre> and <textarea> — before formatting and substitute them back afterwards verbatim, which prevents a stray < inside a string or a regular expression from being mistaken for a tag. If you want the embedded code formatted too, run it through the CSS Beautifier or JavaScript Beautifier separately and paste the result back.
References
Privacy and availability
- Runs entirely in your browser — zero server processing
- No signup or account required
- Works offline once loaded
- Fast, lightweight, no external dependencies
- Available as a browser extension for Chrome and Firefox