🧩 CSS Component Builder - Build with LEGO Blocks

Step 1: Paste HTML or Markdown

Step 2: Available Blocks

Extract components first...

Step 3: Build Template

Drag components here to build

Generated Code

Edit Component

`, order: components.length }); } } }); } displayComponents(); showStatus(`Extracted ${components.length} components!`); } catch (e) { showStatus(`Error: ${e.message}`, true); } } function displayComponents() { const list = document.getElementById('components-list'); if (components.length === 0) { list.innerHTML = '

No components found

'; return; } list.innerHTML = components.map(comp => `
${comp.name} #${comp.id}
${escapeHtml((comp.type === 'js' ? (comp.js || comp.html) : comp.css).substring(0, 150))}...
`).join(''); } function addToBuilder(compId) { const comp = components.find(c => c.id === compId); if (!comp) return; builderItems.push({...comp, builderId: `build-${Date.now()}-${Math.random()}`}); updateBuilder(); showStatus('Added to builder!'); } function dragStart(event, compId) { event.dataTransfer.effectAllowed = 'copy'; event.dataTransfer.setData('componentId', compId); } function dragOver(event) { event.preventDefault(); event.dataTransfer.dropEffect = 'copy'; document.getElementById('builder').classList.add('drag-over'); } function dragLeave(event) { document.getElementById('builder').classList.remove('drag-over'); } function dropComponent(event) { event.preventDefault(); document.getElementById('builder').classList.remove('drag-over'); const compId = event.dataTransfer.getData('componentId'); addToBuilder(compId); } function updateBuilder() { const builder = document.getElementById('builder'); if (builderItems.length === 0) { builder.innerHTML = '

Drag components here to build

'; generateOutput(); return; } builder.innerHTML = '

' + builderItems.length + ' component(s) added

' + builderItems.map((item, idx) => `
⋮⋮ ${item.name}
${item.selector}
${escapeHtml(item.type === 'js' ? (item.js || item.html) : item.css)}
`).join(''); generateOutput(); } function dragStartBuilder(event, idx) { event.dataTransfer.effectAllowed = 'move'; event.dataTransfer.setData('builderIndex', idx); } function dragOverBuilder(event) { event.preventDefault(); event.dataTransfer.dropEffect = 'move'; event.target.closest('.builder-item')?.classList.add('drag-over'); } function dragLeaveBuilder(event) { event.target.closest('.builder-item')?.classList.remove('drag-over'); } function dropInBuilder(event, targetIdx) { event.preventDefault(); event.target.closest('.builder-item')?.classList.remove('drag-over'); const sourceIdx = parseInt(event.dataTransfer.getData('builderIndex')); if (sourceIdx === targetIdx) return; // Reorder array const item = builderItems.splice(sourceIdx, 1)[0]; builderItems.splice(targetIdx, 0, item); updateBuilder(); showStatus('Reordered!'); } function editComponent(idx) { const item = builderItems[idx]; const modal = document.getElementById('edit-modal'); document.getElementById('edit-component-name').value = item.name; document.getElementById('edit-component-css').value = item.css; document.getElementById('edit-component-html').value = item.html; document.getElementById('edit-index').value = idx; modal.classList.add('show'); } function saveEdit() { const idx = parseInt(document.getElementById('edit-index').value); const name = document.getElementById('edit-component-name').value; const css = document.getElementById('edit-component-css').value; const html = document.getElementById('edit-component-html').value; builderItems[idx].name = name; builderItems[idx].css = css; builderItems[idx].html = html; document.getElementById('edit-modal').classList.remove('show'); updateBuilder(); showStatus('Component updated!'); } function cancelEdit() { document.getElementById('edit-modal').classList.remove('show'); } function saveTemplate() { if (builderItems.length === 0) { showStatus('No components to save', true); return; } const name = prompt('Template name:', 'My Template ' + new Date().toLocaleDateString()); if (!name) return; const templates = JSON.parse(localStorage.getItem('cssTemplates') || '{}'); templates[name] = { items: builderItems, created: new Date().toISOString(), componentCount: builderItems.length }; localStorage.setItem('cssTemplates', JSON.stringify(templates)); const status = document.getElementById('save-status'); status.textContent = `✓ Saved as "${name}"`; setTimeout(() => status.textContent = '', 3000); } function loadTemplate() { const templates = JSON.parse(localStorage.getItem('cssTemplates') || '{}'); const names = Object.keys(templates); if (names.length === 0) { showStatus('No saved templates', true); return; } const name = prompt(`Saved templates:\n\n${names.join('\n')}\n\nEnter template name to load:`); if (!name || !templates[name]) { showStatus('Template not found', true); return; } builderItems = templates[name].items; updateBuilder(); showStatus(`Loaded "${name}" (${templates[name].componentCount} components)`); } function removeBuilderItem(idx) { builderItems.splice(idx, 1); updateBuilder(); } function generateOutput() { const includeCSS = document.getElementById('include-css').checked; const includeJS = document.getElementById('include-js').checked; const cssItems = builderItems.filter(item => item.type === 'css'); const visibleItems = builderItems.filter(item => item.type !== 'js' || includeJS); const cssCode = cssItems.map(item => item.css).join('\n\n'); const htmlCode = visibleItems.map((item, idx) => `\n${item.html}` ).join('\n\n'); const responsiveCSS = `* { margin: 0; padding: 0; box-sizing: border-box; } html, body { width: 100%; height: auto; } body { font-size: 16px; line-height: 1.6; } button, a, input, textarea, select { font-size: 16px; } button { padding: 12px 20px; min-height: 44px; min-width: 44px; } img { max-width: 100%; height: auto; display: block; } h1, h2, h3, h4, h5, h6 { word-wrap: break-word; overflow-wrap: break-word; } p, li, dt, dd { word-break: break-word; } @media (min-width: 768px) { body { font-size: 18px; } } @media (min-width: 1024px) { body { font-size: 16px; } } @media (max-width: 768px) { .container, [class*="container"], [class*="wrapper"] { padding: 1rem !important; } button, .btn, [role="button"] { width: 100% !important; } }`; let fullCode = '\n'; fullCode += '\n'; fullCode += '\n'; fullCode += ' \n'; fullCode += ' \n'; fullCode += ' Built Template\n'; fullCode += ' \n'; fullCode += '\n'; fullCode += '\n'; fullCode += htmlCode + '\n'; fullCode += '\n'; fullCode += ''; document.getElementById('output-code').textContent = fullCode; } function copyComponent(compId) { const comp = components.find(c => c.id === compId); const text = comp.type === 'js' ? (comp.js || comp.html) : comp.css; navigator.clipboard.writeText(text).then(() => { showStatus(`${comp.type === 'js' ? 'JS' : 'CSS'} copied!`); }); } function copyTemplate() { const code = document.getElementById('output-code').textContent; navigator.clipboard.writeText(code).then(() => { showStatus('Template copied!'); }).catch(() => showStatus('Copy failed', true)); } function downloadTemplate() { const code = document.getElementById('output-code').textContent; const blob = new Blob([code], {type: 'text/html'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'template-' + Date.now() + '.html'; a.click(); URL.revokeObjectURL(url); } function downloadTemplateMobileForced() { if (builderItems.length === 0) { showStatus('No components to download', true); return; } const includeCSS = document.getElementById('include-css').checked; const includeJS = document.getElementById('include-js').checked; const cssItems = builderItems.filter(item => item.type === 'css'); const visibleItems = builderItems.filter(item => item.type !== 'js' || includeJS); let cssCode = cssItems.map(item => item.css).join('\n\n'); const htmlCode = visibleItems.map((item, idx) => `\n${item.html}` ).join('\n\n'); // Aggressive mobile forcing - strip all fixed dimensions let mobileForcedCSS = ''; if (includeCSS && cssCode) { mobileForcedCSS = cssCode .replace(/width\s*:\s*\d+px/gi, 'width: 100%') .replace(/max-width\s*:\s*\d+px/gi, 'max-width: 100%') .replace(/min-width\s*:\s*\d+px/gi, 'min-width: auto') .replace(/height\s*:\s*\d+px/gi, 'height: auto') .replace(/min-height\s*:\s*\d+px/gi, 'min-height: auto') .replace(/padding\s*:\s*[\d.]+rem/gi, 'padding: 0.5rem') .replace(/margin\s*:\s*[\d.]+rem/gi, 'margin: 0.5rem auto') .replace(/font-size\s*:\s*[\d.]+rem/gi, 'font-size: 1rem') .replace(/font-size\s*:\s*[\d.]+em/gi, 'font-size: 1em') .replace(/gap\s*:\s*[\d.]+rem/gi, 'gap: 0.5rem'); } const responsiveCSS = `* { margin: 0; padding: 0; box-sizing: border-box; } html, body { width: 100%; height: auto; overflow-x: hidden; } body { font-size: 16px; line-height: 1.6; padding: 0; margin: 0; } button, a, input, textarea, select { font-size: 16px; } button { padding: 12px 20px; min-height: 44px; min-width: 44px; width: auto; } img { max-width: 100%; height: auto; display: block; } h1, h2, h3, h4, h5, h6 { word-wrap: break-word; overflow-wrap: break-word; max-width: 100%; } p, li, dt, dd, span, div { word-break: break-word; max-width: 100%; } /* FORCE MOBILE - Remove all fixed dimensions */ [style*="width"], [style*="max-width"], [style*="min-width"] { width: 100% !important; max-width: 100% !important; min-width: auto !important; } [style*="height"] { height: auto !important; } .container, [class*="container"], [class*="wrapper"], [class*="content"], [class*="main"] { width: 100% !important; max-width: 100% !important; margin: 0 auto !important; padding: 1rem !important; } /* Flex and grid mobile stacking */ [style*="display: flex"], [style*="display: grid"] { flex-direction: column !important; grid-template-columns: 1fr !important; width: 100% !important; } /* Force full width buttons */ button, .btn, [role="button"], input[type="submit"], input[type="button"] { width: 100% !important; max-width: 100% !important; margin: 0.5rem 0 !important; } /* Force responsive tables */ table { width: 100% !important; overflow-x: auto !important; } /* Responsive iframes */ iframe { max-width: 100% !important; width: 100% !important; } /* Remove horizontal scroll */ body, html { max-width: 100vw !important; overflow-x: hidden !important; } @media (max-width: 768px) { body { font-size: 14px; padding: 0; } h1 { font-size: 1.5rem !important; } h2 { font-size: 1.3rem !important; } h3 { font-size: 1.1rem !important; } .container, [class*="container"], [class*="wrapper"] { padding: 1rem !important; } button, .btn { width: 100% !important; padding: 12px !important; } }`; let fullCode = '\n'; fullCode += '\n'; fullCode += '\n'; fullCode += ' \n'; fullCode += ' \n'; fullCode += ' \n'; fullCode += ' Built Template - Mobile Optimized\n'; fullCode += ' \n'; fullCode += '\n'; fullCode += '\n'; fullCode += htmlCode + '\n'; fullCode += '\n'; fullCode += ''; const blob = new Blob([fullCode], {type: 'text/html'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'template-mobile-' + Date.now() + '.html'; a.click(); URL.revokeObjectURL(url); showStatus('Downloaded with FORCE MOBILE MODE enabled!'); } function clearInput() { document.getElementById('html-input').value = ''; components = []; builderItems = []; document.getElementById('components-list').innerHTML = '

Extract components first...

'; document.getElementById('builder').innerHTML = '

Drag components here to build

'; document.getElementById('output-code').textContent = ''; } function clearBuilder() { builderItems = []; updateBuilder(); } function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // Initialize toggle listeners document.getElementById('include-css').addEventListener('change', generateOutput); document.getElementById('include-js').addEventListener('change', generateOutput);