Format HTML into readable, indented markup without running it.
What it does
HTML Formatter rewrites HTML source so that its structure is easier to read: nested elements are indented and attributes are written consistently. The result is plain text. Nothing in your HTML is executed, fetched or previewed, so scripts do not run, and images, stylesheets, frames and links are not loaded.
Use it when HTML arrives on one long line, or when hand-edited markup has uneven indentation and you want to see how the elements nest. It is a formatter, not a repair tool: it never fixes or removes anything, and it refuses markup it cannot read as well-formed.
What it supports
- A whole HTML page or a fragment, such as a few elements or just text. Comments, attributes and non-English text are kept, and so are doctypes, apart from the small changes listed under “Names and quotes”.
- The result is always source text. There is no preview, so nothing in your HTML is run or loaded.
- The JavaScript inside script elements and the CSS inside style elements are laid out too, but never run, applied or minified. If that code has a syntax error, or the element holds something else, such as JSON data (<script type="application/ld+json">), a template or TypeScript, its content is kept exactly as written.
- The content of pre and textarea elements is kept as written.
- Attribute values, inline event handlers such as onclick, comments and character references such as & and © are left as they are.
- Indentation of 2 or 4 spaces, never tabs. Line breaks in the result are always the same kind, whatever your text used.
Good to know
- Malformed HTML is refused, not repaired. A closing tag that matches nothing, closing tags in the wrong order, a tag or an attribute value that never ends, and a character reference that HTML does not define, such as &foo;, all stop the tool at the problem. It never fixes, completes or removes markup for you.
- It formats only. It does not check your HTML against the HTML standard, optimize it, or remove or reorder anything. Besides indentation and line breaks, it makes only the changes listed next.
- Spaces: a run of spaces and line breaks in text collapses into one space or line break, except inside pre and textarea. Where inline elements or text touch each other with no space between them, none is added. The tool assumes the standard display of each element, for example that div, p and li are blocks and span, a and em are inline. If your own CSS changes that, a line break the tool adds between two elements can change spacing on the page.
- Names and quotes: element names are written in lowercase (DIV becomes div), and so are standard attribute names such as CLASS. Other attribute names, such as onClick, keep the case you wrote. Attribute values written without quotes get quotes. In a doctype, the name html is written in lowercase (<!DOCTYPE HTML> becomes <!DOCTYPE html>), and in an old-style doctype with public or system identifiers each run of whitespace becomes one space. <!DOCTYPE html> and <!doctype html> stay exactly as written.
- Void elements such as br, img and input are written with a closing slash, for example <br />, and end tags that HTML lets you leave out, such as </li> and </p>, are written out in full.
- A line break right after the start tag of pre or textarea can be added or dropped. HTML ignores that first line break, so the content is the same.
- Minified HTML is spread out where it is safe to do so: block elements such as div, p, ul and li each start on their own line. Inline elements and text that touch each other stay together, so a run of them can stay on one long line.
- A > can still start a line, but only in one case: a long run of inline elements or text with no space between them, which the tool cannot break at a space. The break then goes inside a tag, which leaves the > of a tag at the start of the next line. The text is still ordinary HTML and means the same thing.
- If indentation would make the result far larger than the size limit, the tool stops before formatting. Use 2 spaces or less nesting.
How to use it
- Paste or type your HTML in the input box. It can be a whole page or just a few elements. Nothing runs while you type.
- Choose the indentation (“2 spaces” or “4 spaces”) and press “Format”.
- Read the result next to your input. It is shown as text, never as a rendered page. If your HTML is refused, the message says where the problem is.
- Press “Copy” to put the result on your clipboard, or “Download” to save it as formatted.html.
Examples
Format markup with line breaks
Paste this HTML and press “Format” with “2 spaces” selected. The tag name DIV is written in lowercase, the unquoted value card gets quotes, the run of spaces in the paragraph becomes one space, and the img tag gets a closing slash. Your line breaks between elements are kept, so each element sits on its own indented line.
<DIV class=card>
<h1>Title</h1>
<p>Some text with <em>emphasis</em>.</p>
<img src=logo.png>
</DIV><div class="card">
<h1>Title</h1>
<p>Some text with <em>emphasis</em>.</p>
<img src="logo.png" />
</div>
A closing tag with nothing to close
The closing </span> has no opening <span> before it. The tool does not guess or repair markup, so it refuses, says where the problem is and shows no result.
<div>
<p>Hello</p>
</span>The HTML is not well-formed at this point. For example, a closing tag has no matching opening tag, a tag or attribute value is never finished, or a character reference such as &foo; is unknown. HTML is never repaired for you, so fix the markup and run the action again.
Line 3, column 1
Tags with nothing between them
This list has no spaces or line breaks between its tags. Block elements such as ul and li can each start on their own line without changing how the page looks, so the tool gives each one its own indented line. Inline elements such as em or a are different: a space between two of them can show up in the page, so the tool never adds one.
<ul><li>Tea</li><li>Coffee</li></ul><ul>
<li>Tea</li>
<li>Coffee</li>
</ul>
Scripts and preformatted text
The content of pre is kept exactly as written, so the indentation of “line 2” does not change. The JavaScript inside script is laid out like code: “let a=1;” becomes “let a = 1;” and is indented under its tag. The CSS inside style is laid out the same way, and nothing is run or applied.
<div>
<pre>
line 1
line 2</pre>
<script>
let a=1;
</script>
</div><div>
<pre>
line 1
line 2</pre>
<script>
let a = 1;
</script>
</div>
Limits and privacy
Size limits
- Input: up to 2,000,000 bytes of UTF-8 text (about 2 MB). Accented letters and emoji take more than one byte each. Larger input is rejected.
- Result: also up to 2,000,000 bytes. If the complete result would be larger, the tool shows only an incomplete preview of the first 100,000 bytes, and that preview cannot be copied or downloaded.
- Nesting: up to 128 levels of elements (a root is level 1; self-closing and void elements count too) inside each other. Deeper HTML is refused because it is beyond what the tool processes.
- Time: a run that takes longer than its time limit is stopped. Try a smaller input.
Your privacy
The text you type or paste, or open from a local file, is processed locally in your browser, in a dedicated Web Worker. It is never uploaded or sent to the server (a file you open is read in your browser only), and it is not written to storage, cookies or the address bar.
“Copy” puts the result on your clipboard and “Download” saves it as a file, but only when you press the button. The file is created in your browser, so nothing is uploaded.
For the full details, see the Privacy Policy
Related tools and pages
Your text stays in the page when you switch tools in the same tab, so you can try the same text in another tool. Reloading or closing the tab ends it.