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. <ul>and<ol>become-and1.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 taggedpy; 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
colspanorrowspancannot 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.
<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 MB files</li></ul>
</li>
</ul>
<pre><code class="language-js">const x = 1;</code></pre># 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;
```
Table with alignment
The right-aligned header cells set —: on those columns, and every column is padded so the raw Markdown lines up.
<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>| Item | Qty | Price |
| -------- | --- | ------ |
| Keyboard | 1 | 129.90 |
| Mouse | 2 | 79.00 |
Page with scripts and styling
The head, style and script disappear, while the div, span, mark and kbd wrappers are unwrapped to plain text.
<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>Heads up: tokens expire after 1 hour.
Use Ctrl + K to search.
Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
The HTML has no visible text content to convert | The 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 paragraphs | The 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 cells | Markdown 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 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.