JavaScript createElement: Crear elementos DOM dinámicamente

¿Necesitas crear elementos HTML desde JavaScript? El método createElement es tu mejor amigo. En lugar de escribir HTML estático, puedes generar contenido dinámicamente según lo que necesite tu aplicación.

En este tutorial veremos createElement desde cero con ejemplos prácticos que puedes usar en tus proyectos reales.

🤔 ¿Qué es createElement y para qué sirve?

document.createElement() es un método de JavaScript que crea un nuevo elemento HTML desde código, sin necesidad de escribirlo en el HTML.

💡 ¿Cuándo es útil?

  • Listas dinámicas: Mostrar productos desde una API
  • Formularios dinámicos: Añadir campos según el usuario
  • Interfaz reactiva: Cambiar contenido sin recargar la página
  • Componentes reutilizables: Crear elementos modulares

🏗️ Sintaxis básica de createElement

Sintaxis básica 📋
const elemento = document.createElement('tagName');

Donde tagName es el tipo de elemento que quieres crear: 'div', 'p', 'button', 'img', etc.

Ejemplo básico: Crear un párrafo

JavaScript 📋
// 1. Crear el elemento
const parrafo = document.createElement('p');

// 2. Añadir contenido
parrafo.textContent = '¡Hola mundo desde JavaScript!';

// 3. Añadir al DOM
document.body.appendChild(parrafo);

Resultado: Se añade un párrafo al final de la página con el texto "¡Hola mundo desde JavaScript!"

⚠️ Importante

Crear un elemento con createElement NO lo añade automáticamente a la página. Necesitas usar appendChild, insertBefore o similar para que aparezca.

🎨 Añadir atributos y estilos

Un elemento sin atributos es como una casa sin puertas. Veamos cómo añadir clases, IDs, estilos y más.

Ejemplo: Crear un botón completo

JavaScript 📋
// Crear el botón
const boton = document.createElement('button');

// Añadir texto
boton.textContent = 'Haz clic aquí';

// Añadir atributos
boton.id = 'mi-boton';
boton.className = 'btn btn-primary';

// Añadir estilos CSS
boton.style.backgroundColor = '#007bff';
boton.style.color = 'white';
boton.style.padding = '10px 20px';
boton.style.border = 'none';
boton.style.borderRadius = '5px';

// Añadir al DOM
document.body.appendChild(boton);

Métodos alternativos para atributos

Diferentes formas de añadir atributos 📋
const imagen = document.createElement('img');

// Método 1: Acceso directo
imagen.src = 'https://via.placeholder.com/200';
imagen.alt = 'Imagen de ejemplo';

// Método 2: setAttribute()
imagen.setAttribute('width', '200');
imagen.setAttribute('height', '200');

// Método 3: classList para clases
imagen.classList.add('imagen-responsive', 'borde-redondo');

🎯 Añadir eventos a elementos creados

Los elementos dinámicos pueden tener eventos como cualquier elemento HTML. Aquí te muestro las mejores formas:

Ejemplo: Botón con evento click

JavaScript 📋
const botonContador = document.createElement('button');
let contador = 0;

botonContador.textContent = `Clicks: ${contador}`;

// Añadir evento
botonContador.addEventListener('click', function() {
    contador++;
    botonContador.textContent = `Clicks: ${contador}`;
    
    if (contador === 10) {
        alert('¡Has hecho 10 clicks!');
    }
});

document.body.appendChild(botonContador);

Ejemplo: Input con validación en tiempo real

JavaScript 📋
// Crear contenedor
const contenedor = document.createElement('div');

// Crear input
const input = document.createElement('input');
input.type = 'email';
input.placeholder = 'Escribe tu email';

// Crear mensaje de estado
const mensaje = document.createElement('p');

// Validación en tiempo real
input.addEventListener('input', function(e) {
    const email = e.target.value;
    const esValido = email.includes('@') && email.includes('.');
    
    if (email.length === 0) {
        mensaje.textContent = '';
    } else if (esValido) {
        mensaje.textContent = '✅ Email válido';
        mensaje.style.color = 'green';
    } else {
        mensaje.textContent = '❌ Email inválido';
        mensaje.style.color = 'red';
    }
});

// Añadir al contenedor
contenedor.appendChild(input);
contenedor.appendChild(mensaje);
document.body.appendChild(contenedor);

📋 Crear listas dinámicas

Uno de los usos más comunes de createElement es generar listas desde arrays de datos. Ideal para mostrar productos, usuarios, tareas, etc.

Ejemplo: Lista de tareas interactiva

JavaScript 📋
// Array de tareas
const tareas = [
    { id: 1, texto: 'Aprender createElement', completada: false },
    { id: 2, texto: 'Hacer la compra', completada: true },
    { id: 3, texto: 'Llamar al médico', completada: false }
];

// Crear lista
const lista = document.createElement('ul');
lista.style.listStyle = 'none';
lista.style.padding = '0';

// Función para crear cada item
function crearItemTarea(tarea) {
    const li = document.createElement('li');
    li.style.padding = '10px';
    li.style.border = '1px solid #ddd';
    li.style.marginBottom = '5px';
    li.style.borderRadius = '5px';
    li.style.display = 'flex';
    li.style.justifyContent = 'space-between';
    li.style.alignItems = 'center';
    
    // Texto de la tarea
    const texto = document.createElement('span');
    texto.textContent = tarea.texto;
    
    if (tarea.completada) {
        texto.style.textDecoration = 'line-through';
        texto.style.color = '#888';
    }
    
    // Botón de completar
    const botonCompletar = document.createElement('button');
    botonCompletar.textContent = tarea.completada ? '❌' : '✅';
    botonCompletar.style.border = 'none';
    botonCompletar.style.background = 'transparent';
    botonCompletar.style.cursor = 'pointer';
    botonCompletar.style.fontSize = '18px';
    
    // Evento para cambiar estado
    botonCompletar.addEventListener('click', function() {
        tarea.completada = !tarea.completada;
        actualizarLista();
    });
    
    li.appendChild(texto);
    li.appendChild(botonCompletar);
    
    return li;
}

// Función para actualizar la lista
function actualizarLista() {
    lista.innerHTML = ''; // Limpiar lista
    
    tareas.forEach(tarea => {
        const item = crearItemTarea(tarea);
        lista.appendChild(item);
    });
}

// Cargar lista inicial
actualizarLista();
document.body.appendChild(lista);

🔧 Ejemplo práctico: Generador de tarjetas de producto

Veamos un ejemplo más complejo: crear tarjetas de productos dinámicamente, como si fuera un e-commerce.

JavaScript - Generador de productos 📋
// Datos de productos (podrían venir de una API)
const productos = [
    {
        id: 1,
        nombre: 'Laptop Gaming',
        precio: 899.99,
        imagen: 'https://via.placeholder.com/300x200?text=Laptop',
        descuento: 15
    },
    {
        id: 2,
        nombre: 'Mouse Inalámbrico',
        precio: 29.99,
        imagen: 'https://via.placeholder.com/300x200?text=Mouse',
        descuento: 0
    },
    {
        id: 3,
        nombre: 'Teclado Mecánico',
        precio: 79.99,
        imagen: 'https://via.placeholder.com/300x200?text=Teclado',
        descuento: 25
    }
];

// Función para crear una tarjeta de producto
function crearTarjetaProducto(producto) {
    // Contenedor principal
    const tarjeta = document.createElement('div');
    tarjeta.style.border = '1px solid #e1e5e9';
    tarjeta.style.borderRadius = '10px';
    tarjeta.style.padding = '20px';
    tarjeta.style.maxWidth = '300px';
    tarjeta.style.margin = '10px';
    tarjeta.style.boxShadow = '0 2px 10px rgba(0,0,0,0.1)';
    tarjeta.style.transition = 'transform 0.3s';
    
    // Efecto hover
    tarjeta.addEventListener('mouseenter', () => {
        tarjeta.style.transform = 'translateY(-5px)';
    });
    tarjeta.addEventListener('mouseleave', () => {
        tarjeta.style.transform = 'translateY(0)';
    });
    
    // Imagen del producto
    const imagen = document.createElement('img');
    imagen.src = producto.imagen;
    imagen.alt = producto.nombre;
    imagen.style.width = '100%';
    imagen.style.borderRadius = '5px';
    imagen.style.marginBottom = '15px';
    
    // Nombre del producto
    const nombre = document.createElement('h3');
    nombre.textContent = producto.nombre;
    nombre.style.margin = '0 0 10px 0';
    nombre.style.color = '#333';
    
    // Contenedor de precios
    const contenedorPrecio = document.createElement('div');
    contenedorPrecio.style.marginBottom = '15px';
    
    if (producto.descuento > 0) {
        // Precio original tachado
        const precioOriginal = document.createElement('span');
        precioOriginal.textContent = `${producto.precio.toFixed(2)}`;
        precioOriginal.style.textDecoration = 'line-through';
        precioOriginal.style.color = '#999';
        precioOriginal.style.marginRight = '10px';
        
        // Precio con descuento
        const precioDescuento = producto.precio * (1 - producto.descuento / 100);
        const precioFinal = document.createElement('span');
        precioFinal.textContent = `${precioDescuento.toFixed(2)}`;
        precioFinal.style.color = '#e74c3c';
        precioFinal.style.fontWeight = 'bold';
        precioFinal.style.fontSize = '18px';
        
        // Badge de descuento
        const badgeDescuento = document.createElement('span');
        badgeDescuento.textContent = `-${producto.descuento}%`;
        badgeDescuento.style.backgroundColor = '#e74c3c';
        badgeDescuento.style.color = 'white';
        badgeDescuento.style.padding = '2px 8px';
        badgeDescuento.style.borderRadius = '12px';
        badgeDescuento.style.fontSize = '12px';
        badgeDescuento.style.marginLeft = '10px';
        
        contenedorPrecio.appendChild(precioOriginal);
        contenedorPrecio.appendChild(precioFinal);
        contenedorPrecio.appendChild(badgeDescuento);
    } else {
        // Solo precio normal
        const precio = document.createElement('span');
        precio.textContent = `${producto.precio.toFixed(2)}`;
        precio.style.fontSize = '18px';
        precio.style.fontWeight = 'bold';
        precio.style.color = '#27ae60';
        
        contenedorPrecio.appendChild(precio);
    }
    
    // Botón de compra
    const botonComprar = document.createElement('button');
    botonComprar.textContent = '🛒 Añadir al carrito';
    botonComprar.style.width = '100%';
    botonComprar.style.padding = '12px';
    botonComprar.style.backgroundColor = '#3498db';
    botonComprar.style.color = 'white';
    botonComprar.style.border = 'none';
    botonComprar.style.borderRadius = '5px';
    botonComprar.style.cursor = 'pointer';
    botonComprar.style.fontSize = '14px';
    botonComprar.style.fontWeight = 'bold';
    botonComprar.style.transition = 'background-color 0.3s';
    
    // Eventos del botón
    botonComprar.addEventListener('mouseenter', () => {
        botonComprar.style.backgroundColor = '#2980b9';
    });
    botonComprar.addEventListener('mouseleave', () => {
        botonComprar.style.backgroundColor = '#3498db';
    });
    botonComprar.addEventListener('click', () => {
        alert(`¡${producto.nombre} añadido al carrito!`);
    });
    
    // Ensamblar la tarjeta
    tarjeta.appendChild(imagen);
    tarjeta.appendChild(nombre);
    tarjeta.appendChild(contenedorPrecio);
    tarjeta.appendChild(botonComprar);
    
    return tarjeta;
}

// Crear contenedor para las tarjetas
const contenedorProductos = document.createElement('div');
contenedorProductos.style.display = 'flex';
contenedorProductos.style.flexWrap = 'wrap';
contenedorProductos.style.justifyContent = 'center';
contenedorProductos.style.gap = '20px';
contenedorProductos.style.padding = '20px';

// Generar todas las tarjetas
productos.forEach(producto => {
    const tarjeta = crearTarjetaProducto(producto);
    contenedorProductos.appendChild(tarjeta);
});

// Añadir al DOM
document.body.appendChild(contenedorProductos);

🧹 Buenas prácticas con createElement

✅ Haz esto

  • Usa funciones reutilizables: Crea funciones que generen elementos similares
  • Separa lógica y presentación: Una función para crear, otra para estilos
  • Usa classList.add(): Mejor que className para múltiples clases
  • Valida datos: Siempre verifica que los datos existen antes de usarlos

❌ Evita esto

  • Estilos inline excesivos: Mejor usa clases CSS
  • Añadir elementos al body: Usa contenedores específicos
  • No limpiar event listeners: Puede causar memory leaks
  • Crear muchos elementos sin organizar: Estructura tu código en funciones

📍 ¿Dónde añadir los elementos creados?

Los elementos creados con createElement deben añadirse a un contenedor HTML existente. Nunca los añadas directamente al body porque se meten con todo lo demás.

Ejemplo: HTML + JavaScript trabajando juntos

HTML - Estructura base
<html>
<head>
    <title>Mi página</title>
</head>
<body>
    <h1>Mi aplicación</h1>
    
    <!-- ✅ Contenedor donde añadir elementos dinámicos -->
    <div id="contenedor-dinamico">
        <!-- Aquí van los elementos creados por JavaScript -->
    </div>
    
    <p>Este párrafo no se ve afectado</p>
    
    <script>
        // JavaScript aquí
    </script>
</body>
</html>
JavaScript - Añadir al contenedor específico
// 1. Buscar el contenedor donde queremos añadir
const contenedor = document.getElementById('contenedor-dinamico');

// 2. Crear elemento
const boton = document.createElement('button');
boton.textContent = 'Soy dinámico';

// 3. Añadir al contenedor (NO al body)
contenedor.appendChild(boton);

// ❌ MAL: document.body.appendChild(boton);
// ✅ BIEN: contenedor.appendChild(boton);

Diferentes formas de encontrar el contenedor

Métodos para seleccionar contenedores
// Por ID (más común)
const contenedor1 = document.getElementById('mi-contenedor');

// Por clase (el primero que encuentre)
const contenedor2 = document.querySelector('.contenedor-productos');

// Por etiqueta
const contenedor3 = document.querySelector('main');

// Crear elemento y añadir
const elemento = document.createElement('div');
contenedor1.appendChild(elemento);

Ejemplo práctico: Página de productos

HTML estructura
<body>
    <header>
        <h1>Mi tienda</h1>
    </header>
    
    <main>
        <div id="productos">
            <!-- Los productos se crean aquí -->
        </div>
    </main>
    
    <footer>
        <p>© 2025 Mi tienda</p>
    </footer>
</body>
JavaScript - Crear productos
// Buscar contenedor
const contenedorProductos = document.getElementById('productos');

// Crear producto
const producto = document.createElement('div');
producto.className = 'producto';

const titulo = document.createElement('h3');
titulo.textContent = 'Laptop Gaming';

const precio = document.createElement('p');
precio.textContent = '€899';

// Anidar elementos
producto.appendChild(titulo);
producto.appendChild(precio);

// Añadir al contenedor específico
contenedorProductos.appendChild(producto);

// El header y footer no se ven afectados

🚀 Resumen y siguientes pasos

Con createElement ya puedes crear interfaces dinámicas completas. Los conceptos clave que hemos visto:

Patrón básico que siempre funciona
// 1. Crear elemento
const elemento = document.createElement('tagName');

// 2. Configurar propiedades
elemento.textContent = 'Contenido';
elemento.className = 'mi-clase';

// 3. Añadir eventos (opcional)
elemento.addEventListener('click', miFuncion);

// 4. Añadir al DOM
contenedor.appendChild(elemento);

Lo que puedes hacer ahora:

Siguiente nivel: Aprende sobre Web Components, Virtual DOM y frameworks como React que hacen esto mismo pero de forma más avanzada.

🚀 ¿Te gustó este tutorial?

Únete a StudyCode Pro para más tutoriales como este, roadmaps completos y acceso a nuestra comunidad de developers que te ayudará a conseguir tu primer trabajo en tech.

📬 Únete Gratis