HTML to Markdown Converter

Paste an HTML snippet or a whole page and get readable Markdown for docs, a wiki, a README or an LLM prompt. The HTML is parsed in your browser and never sent to a server.

HTML → Markdown

Input

Settings

History

Load from URL

When to convert HTML to Markdown

Content often needs to move out of HTML: migrating a blog or a CMS to a static site generator, copying documentation into a Git repository, turning a web page into notes in Obsidian or Notion, or preparing text for a language model, where Markdown is far more compact than markup. Hand-converting is slow and easy to get wrong; this tool does it structurally, element by element.

How elements are translated

  • <h1>–<h6> become #-style headings.
  • <strong>/<b> become **bold**; <em>/<i> become _italic_; <del> and <s> become ~~strikethrough~~.
  • Links become inline [text](url "title"), and images become ![alt](src "title").
  • <ul> and <ol> become - and 1. lists, nested lists are indented, and an <ol start="3"> keeps its numbering. Two separate lists in a row get different markers (- then *) so Markdown does not merge them.
  • Checkbox list items become task items: - [x] done.
  • <pre><code class="language-py"> becomes a fenced code block tagged py; inline <code> becomes backticks.
  • <blockquote> becomes > quotes and <hr> becomes ---.
  • Tables become GitHub-flavored tables with padded, aligned columns; align="right" on header cells sets the column alignment.
  • <br> becomes a backslash line break, or stays <br> inside a table cell.

What is removed or simplified

  • <script>, <style>, <noscript>, <template> and the <head> are dropped entirely, as are HTML comments and embeds such as <iframe>.
  • Elements with no Markdown equivalent — <div>, <span>, <u>, <mark>, <kbd> and similar — are unwrapped, keeping their text.
  • Classes, IDs, inline styles and data attributes are discarded.
  • Table cells merged with colspan or rowspan cannot be expressed in Markdown and are flattened into single cells; tables without a header row get an empty header.
  • A <pre> without an inner <code> is converted as ordinary text rather than a fenced block.

Characters that Markdown would misread — a leading #, *, _, a < that looks like a tag, or & followed by an entity name — are backslash-escaped so the Markdown renders to the same text you saw.

Options and tips

There are no options; the output style (ATX headings, - bullets, fenced code, _ for emphasis, ** for bold) is fixed and matches what most linters prefer. For best results, paste the article’s main content rather than the full page, so navigation and footers do not end up in your Markdown. Check the result with the Markdown formatter, or render it again with Markdown to HTML to compare. The conversion runs locally in this tab.

Copying from a live site? Selecting text in the browser often loses structure, so open the developer tools, right-click the article element and choose “Copy outer HTML” instead.

Examples

Article snippet

Produces an ATX heading, an inline link with a title, a nested list and a fenced block tagged js.

Input
<h1>Release notes</h1>
<p>Paste on the left, <strong>pretty output</strong> on the right. See <a href="https://example.com/docs" title="Docs">the docs</a>.</p>
<ul>
  <li>Private</li>
  <li>Instant
    <ul><li>Even for 50&nbsp;MB files</li></ul>
  </li>
</ul>
<pre><code class="language-js">const x = 1;</code></pre>
Output
# Release notes

Paste on the left, **pretty output** on the right. See [the docs](https://example.com/docs "Docs").

- Private
- Instant
  - Even for 50 MB files

```js
const x = 1;
```
Open this example in the tool

Table with alignment

The right-aligned header cells set —: on those columns, and every column is padded so the raw Markdown lines up.

Input
<table>
  <thead><tr><th>Item</th><th align="right">Qty</th><th align="right">Price</th></tr></thead>
  <tbody>
    <tr><td>Keyboard</td><td>1</td><td>129.90</td></tr>
    <tr><td>Mouse</td><td>2</td><td>79.00</td></tr>
  </tbody>
</table>
Output
| Item     | Qty | Price  |
| -------- | --- | ------ |
| Keyboard | 1   | 129.90 |
| Mouse    | 2   | 79.00  |
Open this example in the tool

Page with scripts and styling

The head, style and script disappear, while the div, span, mark and kbd wrappers are unwrapped to plain text.

Input
<html><head><title>Docs</title><style>.note{color:red}</style></head>
<body>
<script>trackPageView()</script>
<div class="note"><span>Heads up:</span> <mark>tokens expire</mark> after 1 hour.</div>
<p>Use <kbd>Ctrl</kbd> + <kbd>K</kbd> to search.</p>
</body></html>
Output
Heads up: tokens expire after 1 hour.

Use Ctrl + K to search.
Open this example in the tool

Common errors and how to fix them

ErrorCauseFix
The HTML has no visible text content to convertThe input contains only scripts, styles or empty elements, all of which are removed.Copy the part of the page that holds the actual content, or view the page source to find it.
Code blocks come out as plain paragraphsThe source uses <pre> without an inner <code> element.Wrap the content as <pre><code>…</code></pre> before converting, or add the fences by hand.
A table loses merged cellsMarkdown tables cannot span columns or rows, so colspan and rowspan are flattened.Keep complex tables as raw HTML inside your Markdown file, which most renderers allow.

Frequently asked questions

Which Markdown flavour does it produce?

GitHub Flavored Markdown: CommonMark plus tables, strikethrough and task lists.

Are images kept?

Yes, as alt references to the original URLs. The images themselves are not downloaded.

Does it keep the language of code blocks?

Yes, when the code element has a class like language-python, the fence is tagged with that language.

What happens to inline styles and classes?

They are dropped, because Markdown has no way to express them. Only the text and its structure remain.

Can I paste a full web page?

Yes. The head, scripts and styles are stripped automatically, though navigation menus and footers in the body will still be converted.

Related tools