Back to ZapTools

ZapHTMLPreview

Live HTML / CSS / JS playground — edit and preview in real time

HTML
CSS
JS
Preview about:blank
Console 0
No console output yet.
', '' ].join('\n'); } // ---- Listen for console messages from iframe ---- window.addEventListener('message', function(e) { if (!e.data || !e.data.__zapConsole) return; appendConsoleMsg(e.data.type, e.data.args); if (e.data.type === 'error') { errorCount++; updateConsoleBadge(); } }); function appendConsoleMsg(type, args) { var lines = document.getElementById('consoleLines'); var empty = document.getElementById('consoleEmpty'); if (empty) empty.style.display = 'none'; var line = document.createElement('div'); var prefix = {log:'', info:'ℹ ', warn:'⚠ ', error:'✖ ', debug:'⚙ '}; var cls = {log:'log', info:'info', warn:'warn', error:'error', debug:'log'}; line.className = 'console-line console-line-' + (cls[type] || 'log'); line.textContent = (prefix[type] || '') + args.join(' '); lines.appendChild(line); lines.scrollTop = lines.scrollHeight; } function clearConsole() { var lines = document.getElementById('consoleLines'); lines.innerHTML = '
No console output yet.
'; errorCount = 0; updateConsoleBadge(); } function updateConsoleBadge() { var badge = document.getElementById('consoleBadge'); if (errorCount > 0) { badge.textContent = errorCount; badge.classList.add('visible'); } else { badge.classList.remove('visible'); } } function toggleConsole() { var panel = document.getElementById('consolePanel'); consoleOpen = !consoleOpen; if (consoleOpen) { panel.classList.remove('console-closed'); } else { panel.classList.add('console-closed'); } } // ---- Resizable editors / preview ---- (function() { var bar = document.getElementById('resizeBar'); var editors = document.getElementById('editorsRow'); var preview = document.getElementById('previewSection'); var wrap = document.getElementById('playgroundWrap'); var dragging = false; var startY, startEdH, startPrH; bar.addEventListener('mousedown', function(e) { dragging = true; startY = e.clientY; startEdH = editors.offsetHeight; startPrH = preview.offsetHeight; document.body.style.cursor = 'row-resize'; document.body.style.userSelect = 'none'; e.preventDefault(); }); document.addEventListener('mousemove', function(e) { if (!dragging) return; var dy = e.clientY - startY; var newEdH = Math.max(100, startEdH + dy); var newPrH = Math.max(80, startPrH - dy); editors.style.height = newEdH + 'px'; preview.style.height = newPrH + 'px'; }); document.addEventListener('mouseup', function() { if (dragging) { dragging = false; document.body.style.cursor = ''; document.body.style.userSelect = ''; } }); // Touch support bar.addEventListener('touchstart', function(e) { dragging = true; startY = e.touches[0].clientY; startEdH = editors.offsetHeight; startPrH = preview.offsetHeight; e.preventDefault(); }, {passive:false}); document.addEventListener('touchmove', function(e) { if (!dragging) return; var dy = e.touches[0].clientY - startY; var newEdH = Math.max(100, startEdH + dy); var newPrH = Math.max(80, startPrH - dy); editors.style.height = newEdH + 'px'; preview.style.height = newPrH + 'px'; }, {passive:false}); document.addEventListener('touchend', function() { dragging = false; }); })(); // ---- Tab key in editors ---- function handleTab(e) { if (e.key !== 'Tab') return; e.preventDefault(); var ta = e.target; var start = ta.selectionStart; var end = ta.selectionEnd; // Multi-line indent/unindent var val = ta.value; if (start === end) { ta.value = val.substring(0, start) + ' ' + val.substring(end); ta.selectionStart = ta.selectionEnd = start + 2; } else { // Indent selected lines var before = val.substring(0, start); var selected = val.substring(start, end); var after = val.substring(end); if (e.shiftKey) { selected = selected.replace(/^ {1,2}/gm, ''); } else { selected = selected.replace(/^/gm, ' '); } ta.value = before + selected + after; ta.selectionStart = start; ta.selectionEnd = start + selected.length; } onEdit(); } // ---- Templates ---- var TEMPLATES = { blank: { html: '', css: '', js: '' }, bootstrap: { html: [ '
', '
', '
', '
', '
', '

Hello, Bootstrap!

', '

This is a Bootstrap 5 starter template loaded from ZapHTMLPreview.

', ' ', ' ', '
', '
', '
', '
', '
' ].join('\n'), css: [ '/* Bootstrap CDN is loaded via in the head */', 'body {', ' background: #f8f9fa;', '}' ].join('\n'), js: [ "document.getElementById('demoBtn').addEventListener('click', function() {", " var alert = document.getElementById('alert');", " alert.style.display = alert.style.display === 'none' ? 'block' : 'none';", " console.log('Button toggled!');", "});" ].join('\n'), extraHead: '' }, landing: { html: [ '
', ' ', '
', '', '
', '
', '

Ship Faster.
Build Better.

', '

The all-in-one platform for modern development teams. Launch in minutes, not months.

', '
', ' ', ' ', '
', '
', '
', '', '
', '

Why teams love us

', '
', '
', '
🚀
', '

Blazing Fast

', '

Deploy globally in under 30 seconds with zero configuration.

', '
', '
', '
🔒
', '

Secure by Default

', '

Enterprise-grade security built in — no setup required.

', '
', '
', '
📊
', '

Real-time Analytics

', '

Understand your users with powerful built-in analytics.

', '
', '
', '
', '', '

Also from ZapTools

Free business tools for freelancers & small teams

📄 Invoice Generator 🧾 Receipt Maker 📝 Proposal Builder 📜 Contract Generator ⚡ All 120+ Tools
' ].join('\n'), css: [ '*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }', 'body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #0d0d0d; color: #e5e5e5; line-height: 1.6; }', 'a { color: inherit; text-decoration: none; }', '', '/* Nav */', 'header { padding: 1rem 2rem; border-bottom: 1px solid #222; }', 'nav { display: flex; align-items: center; justify-content: space-between; max-width: 1100px; margin: 0 auto; }', '.logo { font-size: 1.2rem; font-weight: 800; color: #22C55E; }', '.nav-links { display: flex; gap: 1.5rem; align-items: center; font-size: .9rem; color: #aaa; }', '.nav-links a:hover { color: #fff; }', '.cta-nav { background: #22C55E; color: #000 !important; padding: .4rem .9rem; border-radius: 6px; font-weight: 700; }', '.cta-nav:hover { background: #16a34a; }', '', '/* Hero */', '.hero { padding: 6rem 2rem; text-align: center; background: radial-gradient(ellipse at 50% 0%, rgba(34,197,94,.12) 0%, transparent 70%); }', '.hero-content { max-width: 700px; margin: 0 auto; }', '.hero h1 { font-size: clamp(2.5rem, 6vw, 4rem); font-weight: 900; letter-spacing: -.03em; line-height: 1.1; }', '.hero p { color: #aaa; font-size: 1.15rem; margin: 1.25rem 0 2rem; }', '.hero-btns { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; }', '.btn-primary { background: #22C55E; color: #000; border: none; padding: .75rem 1.75rem; border-radius: 8px; font-weight: 700; font-size: 1rem; cursor: pointer; transition: background .15s; }', '.btn-primary:hover { background: #16a34a; }', '.btn-secondary { background: transparent; color: #e5e5e5; border: 1px solid #333; padding: .75rem 1.75rem; border-radius: 8px; font-weight: 600; font-size: 1rem; cursor: pointer; transition: border-color .15s; }', '.btn-secondary:hover { border-color: #666; }', '', '/* Features */', '.features { padding: 5rem 2rem; max-width: 1100px; margin: 0 auto; }', '.features h2 { text-align: center; font-size: 2rem; font-weight: 800; margin-bottom: 3rem; }', '.feature-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.5rem; }', '.feature-card { background: #141414; border: 1px solid #222; border-radius: 12px; padding: 1.75rem; transition: border-color .2s; }', '.feature-card:hover { border-color: #22C55E; }', '.icon { font-size: 2rem; margin-bottom: .75rem; }', '.feature-card h3 { font-size: 1.1rem; font-weight: 700; margin-bottom: .5rem; }', '.feature-card p { color: #888; font-size: .9rem; }', '', '/* Footer */', 'footer { text-align: center; padding: 2rem; border-top: 1px solid #222; color: #555; font-size: .85rem; }' ].join('\n'), js: [ 'function handleCTA() {', ' alert("Welcome! Sign up flow would go here.");', ' console.log("CTA clicked");', '}' ].join('\n') }, flexbox: { html: [ '

Flexbox Explorer

', '', '
', ' ', ' ', ' ', ' ', '
', '', '
', '
1
', '
2
', '
3
', '
4
', '
5
', '
' ].join('\n'), css: [ 'body { font-family: -apple-system, sans-serif; background: #111; color: #e5e5e5; padding: 1.5rem; }', 'h1 { font-size: 1.3rem; margin-bottom: 1rem; color: #22C55E; }', '', '.controls { display: flex; flex-wrap: wrap; gap: .75rem; margin-bottom: 1.25rem; }', 'label { font-size: .8rem; color: #aaa; display: flex; flex-direction: column; gap: .25rem; }', 'select { background: #1e1e1e; border: 1px solid #333; color: #e5e5e5; border-radius: 6px; padding: .3rem .5rem; font-size: .8rem; outline: none; cursor: pointer; }', 'select:focus { border-color: #22C55E; }', '', '.flex-container {', ' display: flex;', ' justify-content: center;', ' align-items: center;', ' flex-direction: row;', ' flex-wrap: nowrap;', ' background: #1a1a1a;', ' border: 2px dashed #333;', ' border-radius: 10px;', ' min-height: 200px;', ' padding: 1rem;', ' gap: .75rem;', ' transition: all .3s;', '}', '.flex-item { background: #22C55E; color: #000; border-radius: 8px; padding: 1rem 1.5rem; font-weight: 700; font-size: 1rem; min-width: 50px; text-align: center; }', '.flex-item.tall { padding: 2rem 1.5rem; }', '.flex-item.wide { padding: 1rem 3rem; }' ].join('\n'), js: [ 'var box = document.getElementById("flexBox");', 'function setJustify(v) { box.style.justifyContent = v; console.log("justify-content:", v); }', 'function setAlign(v) { box.style.alignItems = v; console.log("align-items:", v); }', 'function setDirection(v){ box.style.flexDirection = v; console.log("flex-direction:", v); }', 'function setWrap(v) { box.style.flexWrap = v; console.log("flex-wrap:", v); }' ].join('\n') }, animation: { html: [ '
', '
', '
', '
', '
', '
', '
', '
', '
', '', '
', ' ', ' ', '
' ].join('\n'), css: [ '*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }', 'body { background: #03020f; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; font-family: -apple-system, sans-serif; color: #aaa; }', '', '.scene { position: relative; width: 280px; height: 280px; }', '', '.sun {', ' position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);', ' width: 60px; height: 60px; border-radius: 50%;', ' background: radial-gradient(circle at 35% 35%, #ffe066, #ff9800, #e53935);', ' box-shadow: 0 0 40px 10px rgba(255,160,0,.5), 0 0 80px 20px rgba(255,100,0,.3);', ' z-index: 2;', '}', '', '.orbit {', ' position: absolute; top: 50%; left: 50%;', ' width: 220px; height: 220px; margin: -110px 0 0 -110px;', ' border: 1px dashed rgba(255,255,255,.12);', ' border-radius: 50%;', ' animation: revolve 4s linear infinite;', '}', '', '.planet {', ' position: absolute; top: -14px; left: 50%; margin-left: -14px;', ' width: 28px; height: 28px; border-radius: 50%;', ' background: radial-gradient(circle at 35% 30%, #60a5fa, #2563eb, #1e3a8a);', ' box-shadow: 0 0 12px rgba(96,165,250,.5);', '}', '', '.moon-orbit {', ' position: absolute; top: -14px; left: 50%; margin-left: -14px;', ' width: 28px; height: 28px;', ' animation: moonRevolve 1.2s linear infinite;', '}', '', '.moon {', ' position: absolute; top: -22px; left: 50%; margin-left: -5px;', ' width: 10px; height: 10px; border-radius: 50%;', ' background: radial-gradient(circle at 40% 30%, #e0e0e0, #888);', '}', '', '@keyframes revolve { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }', '@keyframes moonRevolve { from { transform: rotate(0deg) translateY(-14px); } to { transform: rotate(360deg) translateY(-14px); } }', '', '.controls { margin-top: 2rem; display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; justify-content: center; }', 'button { background: rgba(96,165,250,.15); border: 1px solid rgba(96,165,250,.3); color: #60a5fa; border-radius: 8px; padding: .5rem 1.25rem; cursor: pointer; font-size: .85rem; transition: background .15s; }', 'button:hover { background: rgba(96,165,250,.25); }', 'label { font-size: .8rem; display: flex; gap: .5rem; align-items: center; }', 'input[type=range] { accent-color: #22C55E; }' ].join('\n'), js: [ 'var paused = false;', 'function togglePause() {', ' paused = !paused;', ' var els = document.querySelectorAll(".orbit, .moon-orbit");', ' els.forEach(function(el) {', ' el.style.animationPlayState = paused ? "paused" : "running";', ' });', ' console.log("Animation", paused ? "paused" : "resumed");', '}', '', 'function setSpeed(v) {', ' var orbit = document.querySelector(".orbit");', ' var moon = document.querySelector(".moon-orbit");', ' orbit.style.animationDuration = (4 / v) + "s";', ' moon.style.animationDuration = (1.2 / v) + "s";', ' console.log("Speed set to", v + "x");', '}' ].join('\n') } }; function loadTemplate(name) { if (!name) return; var t = TEMPLATES[name]; if (!t) return; htmlEl.value = t.html || ''; cssEl.value = t.css || ''; jsEl.value = t.js || ''; clearConsole(); updateLineCounts(); // For bootstrap template, we need to inject the extra tag // We handle this in buildDocument by checking a global window._extraHead = t.extraHead || ''; updatePreview(); document.getElementById('templateSelect').value = ''; showToast('Template "' + name + '" loaded'); } // Override buildDocument to support extraHead var _origBuild = buildDocument; buildDocument = function(html, css, js) { var consoleBridge = [ ' ', '' ].join('\n'); }; // ---- Clear all ---- function clearAll() { htmlEl.value = ''; cssEl.value = ''; jsEl.value = ''; window._extraHead = ''; updateLineCounts(); clearConsole(); frame.src = 'about:blank'; document.getElementById('previewUrl').textContent = 'about:blank'; } // ---- Export as HTML file ---- function exportFile() { var doc = buildDocument(htmlEl.value, cssEl.value, jsEl.value); var blob = new Blob([doc], {type:'text/html'}); var a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'playground.html'; a.click(); setTimeout(function(){ URL.revokeObjectURL(a.href); }, 1000); showToast('Exported as playground.html'); } // ---- Share via URL (base64-encode content) ---- function copyShareLink() { try { var data = { h: htmlEl.value, c: cssEl.value, j: jsEl.value, x: window._extraHead || '' }; var encoded = btoa(unescape(encodeURIComponent(JSON.stringify(data)))); var url = window.location.href.split('?')[0] + '?z=' + encoded; navigator.clipboard.writeText(url).then(function() { showToast('Share link copied to clipboard!'); }, function() { // Fallback prompt('Copy this link:', url); }); } catch(e) { showToast('Could not generate share link.'); } } // ---- Restore from URL param ---- function restoreFromUrl() { var params = new URLSearchParams(window.location.search); var z = params.get('z'); if (!z) return; try { var data = JSON.parse(decodeURIComponent(escape(atob(z)))); htmlEl.value = data.h || ''; cssEl.value = data.c || ''; jsEl.value = data.j || ''; window._extraHead = data.x || ''; updateLineCounts(); updatePreview(); showToast('Playground restored from shared link'); } catch(e) { console.warn('Could not restore from URL:', e); } } // ---- Copy pane ---- function copyPane(which, btn) { var val = which === 'html' ? htmlEl.value : which === 'css' ? cssEl.value : jsEl.value; if (!val) return; navigator.clipboard.writeText(val).then(function() { var orig = btn.innerHTML; btn.classList.add('copied'); btn.innerHTML = 'Copied!'; setTimeout(function(){ btn.innerHTML = orig; btn.classList.remove('copied'); }, 1500); }); } // ---- Theme toggle ---- function toggleTheme() { isDark = !isDark; if (isDark) { document.body.classList.remove('light'); document.getElementById('themeBtnLabel').textContent = 'Light'; } else { document.body.classList.add('light'); document.getElementById('themeBtnLabel').textContent = 'Dark'; } localStorage.setItem('zapHtmlTheme', isDark ? 'dark' : 'light'); } // ---- Toast ---- function showToast(msg) { var t = document.getElementById('toast'); t.textContent = msg; t.classList.add('show'); setTimeout(function(){ t.classList.remove('show'); }, 2200); } // ---- Init ---- (function init() { // Restore theme preference var saved = localStorage.getItem('zapHtmlTheme'); if (saved === 'light') { isDark = false; document.body.classList.add('light'); document.getElementById('themeBtnLabel').textContent = 'Dark'; } // Try restore from URL restoreFromUrl(); // Load default starter if nothing loaded from URL var hasContent = htmlEl.value || cssEl.value || jsEl.value; if (!hasContent) { // Load a gentle starter htmlEl.value = [ '
', '

Hello, ZapHTMLPreview! ⚡

', '

Edit the HTML, CSS, and JS panes above — the preview updates live.

', ' ', '

', '
' ].join('\n'); cssEl.value = [ '*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }', 'body {', ' font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;', ' background: #0a0a0a;', ' color: #e5e5e5;', ' min-height: 100vh;', ' display: flex;', ' align-items: center;', ' justify-content: center;', '}', '.center {', ' text-align: center;', ' padding: 2rem;', '}', 'h1 {', ' font-size: 2rem;', ' color: #22C55E;', ' margin-bottom: 1rem;', '}', 'p { color: #aaa; margin-bottom: 1rem; }', 'button {', ' background: #22C55E;', ' color: #000;', ' border: none;', ' padding: .6rem 1.4rem;', ' border-radius: 8px;', ' font-size: 1rem;', ' font-weight: 700;', ' cursor: pointer;', ' transition: background .15s;', ' margin-bottom: 1rem;', '}', 'button:hover { background: #16a34a; }' ].join('\n'); jsEl.value = [ 'var clicks = 0;', 'function handleClick() {', ' clicks++;', ' document.getElementById("msg").textContent =', ' "Clicked " + clicks + " time" + (clicks !== 1 ? "s" : "") + "!";', ' console.log("Button clicked! Total:", clicks);', '}' ].join('\n'); updateLineCounts(); updatePreview(); } })();
Share this tool: