HTML Stripper
Free online HTML tag remover. Quickly strip HTML tags and get clean plain text. Optionally keep specific tags (br, p, b, i, a). All processing happens locally in your browser.
HTML to Plain Text: It Is Normalization, Not Just Deleting Tags
Many tutorials describe "stripping HTML" as "delete everything between < and > with a regex" and call it done. But a strict HTML-to-plain-text conversion is a normalization pipeline that must at least do four things: decode character entities, collapse runs of whitespace, insert line breaks for block-level elements, and discard scripts and styles. If you only delete tags while ignoring entities and whitespace, what you get is not "clean text" — it is a half-stripped blob carrying , & leftovers and odd indentation. This tool takes the lightweight regex route (it runs entirely in your browser and uploads nothing), which is great for quick cleanup; but you should know exactly where its boundary lies so you can judge whether the output is trustworthy.
On sourcing: HTML is an international standard defined by the W3C and the WHATWG HTML Living Standard. The entity table and the whitespace rules both come from that specification. One cross-locale gotcha worth flagging: the HTML non-breaking space (U+00A0) is not the same character as the CJK full-width space (U+3000) that appears in Chinese text. The tool treats both as ordinary characters and does not collapse them, so a Chinese page stripped here can show "spaces that will not go away" — that is expected, not a bug.
Table 1: HTML Entity Decoding Rules
A conforming HTML parser resolves character references into their Unicode code points at parse time. The WHATWG HTML Living Standard named-character-reference table holds 2,231 named references (HTML 4.01 defined only 252), plus two numeric forms — decimal &#nnn; and hexadecimal &#xNNN; — that can represent any Unicode code point. The most common ones and their real code points:
| Reference | Decodes to | Unicode | Category / use |
|---|---|---|---|
& | & | U+0026 | syntax char (must escape) |
< | < | U+003C | syntax char (tag start) |
> | > | U+003E | syntax char (tag end) |
" | " | U+0022 | attribute quote |
' | ' | U+0027 | apostrophe (added in HTML5) |
| no-break space | U+00A0 | typographic space (not collapsed) |
— | — | U+2014 | em dash |
© | © | U+00A9 | copyright sign |
£ | £ | U+00A3 | currency sign |
¥ | ¥ | U+00A5 | currency sign |
— | — | U+2014 | numeric reference (equals —) |
Note: this tool is a pure regex stripper and does not decode entities. So stays in the output as the literal text rather than becoming a space. To truly decode, use a browser DOM parser or a backend library. Example 3 below shows this directly.
Table 2: Block-Level Element Line-Break Rules
Plain text has no "tags", but humans expect "paragraphs". During rendering, different block-level elements should inject different numbers of line breaks when textified. The most-asked rules:
| Element | Adds break? | Where | Note |
|---|---|---|---|
<p> | yes | 1 line before & after | paragraph; common segmentation base |
<div> | yes (visually) | 1 line before & after | block container; add break when textifying |
<br> | yes | 1 line after only | hard break; no closing tag |
<li> | yes | 1 line before each item | list item; usually prefix "· " or "1. " |
<tr> | yes | 1 line after each row | table row; column alignment in Table 5 |
<h1>–<h6> | yes | 1 line before & after | heading; often blank line for emphasis |
<blockquote> | yes | 1 line before & after | quote block; prefix ">" |
<hr> | no (semantic) | use "---" instead | horizontal rule; no plain-text equivalent |
By default this tool does not add these breaks — it only deletes tags, so the default output paragraphs get "glued" together. To keep a sense of paragraphs, check "keep" for <p> or <br> (see Example 2).
Table 3: Elements to Discard vs Attributes to Keep
| Element / attribute | Handling | Reason |
|---|---|---|
<script> | drop entirely | executable code; plain text neither needs nor should keep it |
<style> | drop entirely | CSS; unrelated to content |
<!-- comment --> | drop entirely | author note; invisible to readers |
<noscript> | drop entirely | no-script fallback; meaningless once textified |
alt (img) | keep as text | alternative text; the only readable info for an invisible image |
title (element) | keep as text | hover hint; can fold into body or a bracket note |
<img> itself | drop tag | image cannot render as plain text, but alt should be textified |
This is where "drop formatting, keep content" lands: <script>/<style>/comments are removed, while semantic-bearing attributes like alt and title are restored to readable words.
Table 4: Whitespace Collapsing Rules (HTML white-space collapsing)
The HTML specification says that under default rendering, a run of whitespace characters (spaces, tabs, newlines) is collapsed to a single space, whitespace at element boundaries is collapsed, and leading/trailing whitespace on a line is removed. Common cases:
| Case | Spec behavior | Plain-text tip |
|---|---|---|
| runs of space / tab / newline | merge to one space | replace \s+ with single space |
| whitespace at tag boundary | collapsed | clear it after tag removal |
| leading / trailing whitespace | removed | trim() each line |
(U+00A0) | not collapsed | keep, or replace with normal space as needed |
| CJK full-width space (U+3000) | treated as a character | keep or convert per locale |
Note: collapsing applies only to ordinary whitespace. and the full-width space (U+3000) are excluded — which is exactly why you sometimes see "spaces that will not delete" after stripping.
Table 5: <table> to Plain Text Alignment Problem
Turning a table into plain text is hard not because of "removing tags" but because of "aligning columns". Plain text has no cell width, so these issues make output unreadable:
| Problem | Symptom | Tip |
|---|---|---|
| column alignment | cells vary in length; lines misalign | fixed-width pad or Markdown table |
colspan | one cell spans many columns; width math gets complex | merge and label |
rowspan | content spans rows vertically | repeat or leave blank per row |
| nested tables | table inside table | flatten inner first, then outer |
| empty cells | missing content shifts layout | pad with placeholder (e.g. "-") |
Verdict: if your goal is a "readable table", plain-text stripping is the wrong tool — hand it to a structure-preserving tool like Markdown Preview. Use this tool only when the goal is "format-free plain text".
Table 6: HTML Stripping vs Markdown Conversion
| Dimension | Plain-text strip (this tool) | Markdown conversion |
|---|---|---|
| structure | discarded | keeps headings / lists / quotes |
| links | anchor text only | keeps [text](URL) |
| headings | plain line | # prefix |
| lists | plain line | - / 1. prefix |
| bold / italic | lost | keeps ** / * |
| tables | misaligned (see above) | keeps pipe table |
In short: use this tool for "plain text", use Markdown Preview for "lightweight formatting". They are not substitutes; they serve different goals.
Three Worked Examples (using the page default input)
All three examples use the default HTML already in the tool's text box, so they match exactly what you see when you open the page. Output was verified character by character with a script.
Example 1: Strip all tags (no keep boxes checked)
The default input is 186 characters and contains 18 tags. After stripping all, the result is 88 characters:
Welcome to My Website This is bold and italic text. Item 1 Item 2 Learn more here.
Notice how the heading, paragraphs and list are "pressed" into continuous text, and the <li> leading spaces remain (no collapsing) — the typical product of "delete tags only".
Example 2: Keep <p> and <br>
With p and br kept, the output grows to 102 characters — the <p> tags are kept verbatim in the text:
Welcome to My Website <p>This is bold and italic text.</p> Item 1 Item 2 <p>Learn more here.</p>
Note: this tool's "keep" means keep the whole tag, not turn <p> into a line break. So what you see is the literal angled-bracket text <p>, not a real blank line. If you want paragraph breaks, post-process or switch to a structure-preserving tool.
Example 3: Entities are not decoded (key trap)
Input <p>Price: £10 & © 2026—end space</p> yields 55 characters with entities kept literally:
Price: £10 & © 2026—end space
A conforming parser would decode it to Price: £10 & © 2026—end space. The gap exists because entity decoding belongs to the HTML parse stage, which this tool does not perform. For clean output, decode entities first in another environment, or accept the literal residue and replace by hand.
Frequently Asked Questions
Why doesn't become a space after stripping?
Because this tool is a pure regex stripper that only deletes <...> tags and does not run HTML entity decoding. (U+00A0 no-break space) stays in the output as the literal text . To really turn it into a space, decode entities first with a browser DOM or a backend library, then strip tags.
After keeping <p>, why is the <p> text still in the result?
The keep logic is "keep the whole tag", meaning the matched <p> tag is left in the text as-is, not replaced by a line break. It suits debugging where you want to see the tag still present; for real paragraph breaks, post-process or use a structure-preserving tool.
Why does a <table> turn misaligned in plain text?
Plain text has no cell width, so uneven column lengths, colspan/rowspan, nested tables and empty cells all cause misalignment. Plain-text stripping only solves "remove tags"; the alignment problem needs fixed-width padding or a pipe table in Markdown Preview.
Should I strip HTML or convert to Markdown?
The goal decides: for format-free plain text (word counts, storage, feeding a model) use this tool; for lightweight formatting that keeps headings, lists, links and tables, use Markdown Preview. See Table 6 above.
Why do spaces look wrong after stripping a Chinese page?
Chinese pages mix two spaces: HTML (U+00A0, Western no-break space) and the CJK full-width space (U+3000). They are different characters and neither is covered by whitespace collapsing, so both survive stripping. Treat them deliberately — keep or convert to a half-width space — rather than assuming they will vanish.
Want to analyze the cleaned text further? Count characters with Word Counter, or compare before-and-after with Text Diff. For more hands-on tips, see the HTML Stripper guide.