HTML Formatter
Paste minified or messy HTML and get it back cleanly indented, with pre, textarea, script and style content left exactly as written.
About the HTML Formatter
This is the opposite direction from the HTML Minifier: instead of stripping whitespace, this tool adds it back. It runs a small tag-aware parser over your markup that tracks opening tags, closing tags, self-closing tags, comments and text nodes, then reprints everything with two-space indentation that deepens on nesting. Void elements like <br> or <img> never get an indent bump or a closing tag, and anything inside <pre>, <textarea>, <script> or <style> is copied through untouched, since reindenting it could change what it means. The result is written to the page as plain text, never parsed as live markup, so pasting something like a stray <script> tag just shows up as text instead of running.
Why script and style content needs entirely different handling
Inside a <script> or <style> tag, a < character usually doesn't mean "start a new HTML tag", it might just be a JavaScript less-than comparison, like if (a < b). The seeded example in the input box deliberately includes exactly that case. Rather than running the normal tokenizer inside these elements, this formatter switches to a dedicated raw-text mode: once it hits an opening <script> or <style> tag, it searches directly for the matching closing tag with a targeted regex and treats everything in between as one untouched, unparsed block. This mirrors how real browsers actually parse HTML, script and style content is fundamentally different from normal markup content and has its own separate parsing mode in the HTML spec.
Why the tag scanner has to understand quoted attributes
A naive approach to finding where a tag ends would just search for the next > character, but that breaks the moment an attribute value itself contains a literal >, which can genuinely happen inside an inline event handler or certain URL query strings. This formatter's tag scanner tracks whether it's currently inside a single- or double-quoted attribute value as it reads character by character, and only treats an unquoted > as the real end of the tag. Without that quote-awareness, a tag with a stray > buried in an attribute would get cut off early and the rest of the markup would come out corrupted.
Why comments and the doctype get special-cased before anything else
Both HTML comments (<!-- ... -->) and the doctype declaration (<!DOCTYPE html>) are checked for explicitly, before the tokenizer even attempts general tag parsing, because both use delimiter syntax that doesn't follow normal tag-opening rules. Comments are copied through as one opaque block regardless of what text or tag-like characters they contain internally, since a commented-out chunk of markup shouldn't be reformatted or accidentally split apart. The doctype line is always placed at the very start of a line with no indentation at all, reflecting that it's a document-level directive sitting outside the actual element tree, not a nested piece of markup.
Why collapsing whitespace in ordinary text is safe here
For a normal text node (the words between tags), this formatter collapses any run of whitespace, including line breaks, down to a single space. That's safe precisely because HTML's own rendering rules already do the same thing, browsers collapse whitespace in ordinary text content when displaying a page, so reformatting the underlying markup's whitespace doesn't change what a visitor actually sees. The one place this collapsing is deliberately skipped is inside <pre> and <textarea>, where whitespace is exactly the opposite, semantically significant and preserved by the browser exactly as written, which is why those two elements get the same raw, untouched treatment as script and style content.
Why pasted script tags can't execute inside this tool
The formatted result is written into the page using textContent, not innerHTML, which means the browser treats the entire output as inert plain text rather than markup to be parsed and rendered. Paste a snippet containing an actual <script> tag with executable code into the input, and the formatted output will display that script tag as visible text in the result box, it will never actually run. This is a meaningful safety property for a tool that's explicitly designed to accept arbitrary, possibly untrusted HTML input.
Frequently Asked Questions
Why does the formatter leave JavaScript inside <script> tags completely untouched?
A "<" character inside JavaScript often means a less-than comparison, not the start of a new HTML tag. Rather than running the normal HTML tokenizer inside script and style content, this formatter searches directly for the matching closing tag and treats everything between as one opaque, unparsed block, mirroring how real browsers parse these elements.
Can a stray ">" inside an attribute value break the formatting?
No, the tag scanner tracks whether it's inside a quoted attribute value as it reads character by character, and only treats an unquoted > as the real end of a tag. This prevents a > buried inside an inline event handler or URL from prematurely cutting off a tag.
Why doesn't the doctype declaration get indented like other elements?
The doctype is a document-level directive, not a nested piece of markup, so it's always placed at the very start of a line with no indentation, reflecting that it sits outside the actual element tree rather than being part of it.
Does collapsing whitespace in regular text change how the page actually looks?
No, browsers already collapse whitespace runs in ordinary text content down to a single space when rendering, so reformatting the underlying markup's whitespace doesn't change what a visitor sees. This collapsing is skipped inside pre and textarea, where whitespace is meaningful and preserved exactly.
Is it safe to paste HTML containing a script tag into this formatter?
Yes, the output is written using textContent rather than innerHTML, so the entire result is treated as inert plain text by the browser. Any script tags in your input will appear as visible text in the output, they will never actually execute.
Will HTML comments ever get split apart or reformatted internally?
No, comments are detected before general tag parsing and copied through as one complete, untouched block regardless of what text or tag-like characters appear inside them, since a commented-out section shouldn't be restructured.