Free HTML to Image Converter

Paste your HTML and CSS code, see a live preview, then capture it as a PNG or JPG image. Adjust output width, scale, background color, and format. Use preset templates to get started fast. Runs 100% in your browser — no data leaves your device.

HTML + CSS Code

Editor

Live Preview

Preview

Captured Image

Captured HTML

Need something more powerful?

Let us build it for you. Custom APIs, dashboards, automations — whatever you need.

Start a Project →
Open source

NexTool on GitHub

269 free tools. No signup. Open source. Built by Christian Bucher.

Open Source — Free Forever Browse 269 Free Tools →

Related Tools

CSS Box Shadow Generator · Emoji Picker & Search · Free JSON to YAML Converter

'); doc.close(); } // Update preview when bg color changes document.getElementById('bgColor').addEventListener('input', function() { updatePreview(); }); // Initial preview setTimeout(updatePreview, 100); /* ---- Capture ---- */ async function captureImage() { var code = codeArea.value.trim(); if (!code) { showToast('Enter some HTML code first'); return; } if (typeof html2canvas === 'undefined') { showToast('Capture library is still loading. Please try again.'); return; } var captureBtn = document.getElementById('captureBtn'); captureBtn.disabled = true; captureBtn.textContent = 'Capturing...'; var format = document.getElementById('formatSelect').value; var width = parseInt(document.getElementById('widthInput').value) || 800; var scale = parseFloat(document.getElementById('scaleSelect').value); var bgColor = document.getElementById('bgColor').value; var mimeType = format === 'jpeg' ? 'image/jpeg' : 'image/png'; var ext = format === 'jpeg' ? 'jpg' : 'png'; try { // Create an off-screen container for rendering var container = document.createElement('div'); container.style.cssText = 'position:absolute;left:-99999px;top:0;width:' + width + 'px;background:' + bgColor + ';font-family:Inter,sans-serif;padding:16px;'; container.innerHTML = code; document.body.appendChild(container); // Add Inter font link for rendering var fontLink = document.createElement('link'); fontLink.href = 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap'; fontLink.rel = 'stylesheet'; container.prepend(fontLink); // Wait a moment for fonts to load await new Promise(function(r) { setTimeout(r, 200); }); var canvas = await html2canvas(container, { scale: scale, backgroundColor: bgColor, useCORS: true, logging: false, width: width }); document.body.removeChild(container); var dataUrl = canvas.toDataURL(mimeType, 0.92); lastBlob = await new Promise(function(resolve) { canvas.toBlob(function(b) { resolve(b); }, mimeType, 0.92); }); lastFileName = 'html-capture.' + ext; resultImg.src = dataUrl; document.getElementById('resultMeta').textContent = canvas.width + ' x ' + canvas.height + 'px | ' + formatBytes(lastBlob.size) + ' | ' + ext.toUpperCase(); resultArea.classList.add('active'); resultArea.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); showToast('Image captured successfully'); } catch (err) { showToast('Capture failed: ' + err.message); } captureBtn.disabled = false; captureBtn.textContent = 'Capture as Image'; } function downloadImage() { if (!lastBlob) { showToast('No image to download. Capture first.'); return; } var url = URL.createObjectURL(lastBlob); var a = document.createElement('a'); a.href = url; a.download = lastFileName; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } async function copyToClipboard() { var code = codeArea.value; if (!code.trim()) { showToast('Nothing to copy'); return; } try { await navigator.clipboard.writeText(code); showToast('HTML code copied to clipboard'); } catch (err) { showToast('Could not copy to clipboard'); } } async function copyResultToClipboard() { if (!lastBlob) { showToast('No image to copy. Capture first.'); return; } try { // ClipboardItem requires PNG var pngBlob = lastBlob; if (lastBlob.type !== 'image/png') { // Convert to PNG for clipboard var img = new Image(); img.src = resultImg.src; await new Promise(function(r) { img.onload = r; }); var c = document.createElement('canvas'); c.width = img.naturalWidth; c.height = img.naturalHeight; c.getContext('2d').drawImage(img, 0, 0); pngBlob = await new Promise(function(resolve) { c.toBlob(function(b) { resolve(b); }, 'image/png'); }); } await navigator.clipboard.write([ new ClipboardItem({ 'image/png': pngBlob }) ]); showToast('Image copied to clipboard'); } catch (err) { showToast('Could not copy image. Try downloading instead.'); } } function clearEditor() { codeArea.value = ''; updatePreview(); resultArea.classList.remove('active'); lastBlob = null; document.querySelectorAll('.template-btn').forEach(function(b) { b.classList.toggle('active', b.textContent === 'Custom'); }); } function formatBytes(bytes) { if (bytes === 0) return '0 B'; var k = 1024, sizes = ['B', 'KB', 'MB', 'GB']; var i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; } function showToast(msg) { var t = document.getElementById('toast'); t.textContent = msg; t.classList.add('show'); setTimeout(function() { t.classList.remove('show'); }, 2500); } var observer = new IntersectionObserver(function(entries) { entries.forEach(function(entry) { if (entry.isIntersecting) { entry.target.classList.add('visible'); observer.unobserve(entry.target); } }); }, { threshold: 0.1 }); document.querySelectorAll('.fade-in').forEach(function(el) { observer.observe(el); });