"HTML to Figma" sounds like one thing, but it splits into two very different outcomes. One gives you a picture of the page. The other gives you the page — frames, text, fills, and vectors you can actually edit. The gap between them decides whether the conversion saves you an afternoon or wastes one.
Converting HTML to Figma should rebuild your markup as native layers — live text, image fills, vectors — measured from the real render. If the result is a flat image you can't select into, it isn't a conversion. It's a screenshot.
Two things people mean by "HTML to Figma"
When someone asks how to get HTML into Figma, they usually have one of two results in mind — and they're worlds apart.
The first is a flattened image. A tool renders your markup, snaps a picture, and drops that picture on the canvas. It looks correct. But click it and there's nothing inside: no editable text, no adjustable spacing, no recolourable fill. You've imported a JPEG with a Figma frame around it.
The second is a real layer tree. The same markup comes back as structured Figma nodes — a frame for each block, live text with its true font and weight, photos as image fills, icons as vectors. Every node selectable, every value editable. This is the version you can design with, and it's the only one worth the name "conversion."
A screenshot tells you what the page looked like. A layer tree lets you change what it looks like next.
For the wider picture of every route into Figma — file, paste, and live URL — see how to import a website into Figma. This piece zooms in on the markup-to-layers path specifically.
What a good conversion captures
When HTML and CSS are rebuilt properly, far more comes across than people expect. A faithful importer reads the values the browser actually computed and reproduces them:
- Text with the right weight. "ExtraBold" and "Extra Bold" resolve to the same weight; Inter 800 doesn't silently collapse to a default. The copy stays live and editable.
- Structure as frames. Each block becomes a frame positioned exactly where the browser drew it — not a soup of overlapping shapes.
- Per-side borders. A
border-bottomstays one thin line, not a four-sided rectangle drawn around the element. - Image fills and CSS backgrounds. Referenced images and
background-imageURLs download and embed as proper Figma image fills. - Gradients, shadows, blurs, blend modes. The decorative layer —
linear-gradient,box-shadow,backdrop-filter,mix-blend-mode— comes through as real Figma effects. - Inline SVG as vectors. Icons arrive as editable vector paths scaled to their rendered size, not rasterised.
Measured, not guessed
The reason a conversion can be faithful at all is that the browser has already done the hard part. By the time a page is on screen, the layout engine has resolved every position, size, font weight, and line-height into concrete pixels. A good importer doesn't re-interpret your CSS — it reads what the browser produced: every getBoundingClientRect() and getComputedStyle() value, straight from the real render.
That's the difference between measuring and guessing. If the browser drew the card at 312 pixels wide, the import is 312 pixels wide — not 310, not "about 300." Nothing drifts, because nothing was estimated.
What's genuinely hard to convert
Honesty is part of the craft, so here's where even a good conversion meets its limits:
- Fonts you don't have. A plugin can't load a typeface that isn't installed — that's a Figma constraint, not a missing feature. If a page uses a font you don't own, the text falls back to one you do. The careful approach keeps each line's width frozen so the layout doesn't re-wrap, and tells you what was substituted, rather than swapping silently.
- Canvas and WebGL. Content drawn with low-level graphics — 3D scenes, shader backgrounds, some charts — has no DOM for an importer to read, so it can only be captured as an image, if at all.
- States that need interaction. A dropdown that only opens on click, or content that loads on scroll, is captured as it was at the moment of the trace. What's on screen is what comes across.
The rule of thumb: anything the browser rendered from real markup converts cleanly; anything it painted with raw graphics, or hid behind a click, is the hard case.
How to convert HTML to Figma, step by step
- Open Figma and run an importer plugin that rebuilds layers (not one that flattens to an image).
- Choose your source: paste HTML & CSS for a single component, drop an
.htmlfile for a saved page, or enter a live URL for a whole site. - Let it render and measure. The markup comes back as a frame full of editable nodes.
- Select anything and edit — retype the text, recolour a fill, nudge the spacing. It's a design now, not a document.
If you're going the other direction — turning a Figma design into code — that's a different job with different tools, and we compare them in Figma to HTML vs. HTML to Figma. And if your source is a live page rather than a snippet, importing a URL into Figma covers the CORS questions that come with it.
The bottom line
Converting HTML to Figma is only worth doing if you end up with something editable. Demand a layer tree, not a snapshot — text you can retype, frames you can restyle, vectors you can reshape. That's the whole point of bringing code back into a design tool: to design with it again.