How to convert HTML to SVG

SVG is a drawing format and HTML is a layout format, so there is no direct conversion. Three routes get you close, each with a real limit. Knowing which limit you can live with is the whole decision.

There is no clean way to convert HTML to SVG, and the reason is structural. HTML describes a layout that a browser resolves at render time, and SVG describes shapes and text at fixed coordinates.

Anything that converts between them has to run a layout engine first, then translate the result into shapes. Three approaches exist, and each one has a limit you should know before you start.

An SVG containing a foreignObject, rendering correctly in a browser tab and blank in a vector editor.
An SVG containing a foreignObject, rendering correctly in a browser tab and blank in a vector editor.

Three ways to convert HTML to SVG

Route Output Main limit
foreignObject wrapper HTML inside an SVG shell Only renders in browsers
Layout engine converter Real SVG shapes and text Supports a subset of CSS
Extract existing SVG The chart or icon alone Only works if SVG is already there

Read down the limit column first. It decides the route more often than the output column does.

Route 1: wrap the HTML in foreignObject

SVG can carry markup from another namespace inside a <foreignObject> element. The result is a valid .svg file that contains your HTML.

<svg xmlns="http://www.w3.org/2000/svg" width="600" height="320">
  <foreignObject width="100%" height="100%">
    <div xmlns="http://www.w3.org/1999/xhtml"
         style="font:16px system-ui;padding:24px">
      <h1>Weekly summary</h1>
      <p>Signups are up on last week.</p>
    </div>
  </foreignObject>
</svg>

Two rules make it work. The inner element needs the XHTML namespace declared on it, and the markup must be well formed XML, so every tag closes and every attribute is quoted.

The styling has to be inline or inside a <style> element within the SVG. An external stylesheet will not travel with the file.

The limit. Browsers render foreignObject. Many other SVG consumers do not, including common command line rasterisers and several design tools. You get a blank rectangle there.

That makes this route right for an SVG that will be viewed in a browser, and wrong for one that goes into a design file or a print workflow.

Route 2: a converter with a layout engine

Some libraries implement a subset of CSS layout themselves and emit real SVG: <text>, <rect>, <path>. Satori is the common one, used to generate social preview images.

Because the output is genuine SVG, it renders anywhere, including in the tools that ignore foreignObject. The text stays selectable.

The limit. These converters support a subset of CSS. Flexbox is usually supported, floats and grid often are not, and unusual properties are ignored silently.

Treat that as a constraint on how you write the source. A page authored with flexbox, absolute sizes and an embedded font converts well. A page that relies on the full cascade does not.

SVG produced by a layout engine converter, with the text visible as selectable characters rather than an image.
SVG produced by a layout engine converter, with the text visible as selectable characters rather than an image.

Route 3: take the SVG that is already there

Often the thing you want as SVG is already SVG. Charting libraries render to SVG, and so do icon sets.

  1. Open the page and inspect the chart or icon.
  2. Find the enclosing <svg> element in the Elements panel.
  3. Right click and copy the outer HTML.
  4. Paste into a file, add xmlns="http://www.w3.org/2000/svg" if the attribute is missing, and save with an .svg extension.

Check for two things afterwards. Whether the styling came from a stylesheet outside the SVG, in which case you inline it. And whether the chart uses a web font, in which case the text falls back unless you embed it.

SVG in HTML covers the reverse direction and the namespace rules in more detail.

When SVG is the right answer

  • The image must scale. A logo or diagram on a poster and on a favicon, from one file.
  • The text should stay text. Selectable, searchable, and readable by a screen reader.
  • The content is lines and flat colour. Diagrams compress far better as shapes than as pixels.
  • A designer will open it. Vector paths can be edited; a PNG cannot.

When it is not

If the page is a dense dashboard of mixed content, an SVG version is large, fragile and no better looking than a PNG at double density.

Capture it as PNG instead, or use the HTML to image tool and take the image from there.

The same applies when someone wants the page in a design tool. Going through SVG loses structure. Converting HTML to Figma covers the routes that keep layers intact.

Checking the file before you rely on it

An SVG that looks right in one viewer can be empty in another. Test in more than one place.

The same SVG opened in a browser tab and dropped into a file viewer, side by side.
The same SVG opened in a browser tab and dropped into a file viewer, side by side.

Open it in a browser tab, which is the most permissive renderer. Then open it in whatever tool it is actually going to, which is the one that matters.

If the second one is blank, the content is inside a foreignObject and you need route two or a raster format.

When the goal was sharing, not the format

People often reach for SVG because a PNG looked soft when someone zoomed in, and the real requirement is that the page stays readable at any size.

A page at an address does that natively. It reflows for the screen it is on, the text stays selectable, and nothing is cut off at the edge of a capture.

Paste the HTML into a NOS document and it renders as written, with its own link. Turning HTML into a link is that step, and it takes one paste rather than a conversion pipeline.

Questions people ask

Can you convert HTML to SVG directly?

Not in the way you can convert HTML to PNG. SVG describes shapes and text at coordinates, while HTML describes a layout that a browser resolves. A converter has to run a layout engine first and then emit shapes.

What is foreignObject?

An SVG element that holds markup from another namespace, usually XHTML. Browsers render it, so an SVG with a foreignObject looks right in a browser tab. Many non-browser SVG tools ignore it and show a blank area.

Why is my SVG blank in Inkscape or a design tool?

Almost always because the content is inside a foreignObject. Those renderers do not implement HTML layout, so the element renders as nothing. Rasterise to PNG, or produce the SVG with a converter that emits real shapes.

Is SVG worth it over PNG?

It is when the image must scale without blurring, when the text should stay selectable and searchable, or when the file is a diagram of lines and flat colour. For a dense page screenshot, PNG is simpler and often smaller.

Keep reading