0Pricing
Frontend Academy · Lesson

Creating and Appending Elements

Use createElement, setAttribute, append, and remove to build and modify the DOM structure dynamically.

Creating and Appending Elements is a free Frontend Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Frontend Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

createElement

document.createElement(tagName) creates a new element in memory — it's not in the DOM yet. You then set its properties and append it to the tree.

const btn = document.createElement('button');
btn.textContent = 'Click Me';
btn.classList.add('btn-primary');
btn.setAttribute('type', 'button');
// btn is in memory, not yet in the page

append and appendChild

parent.append(child) adds a node or string to the end of parent's children. appendChild is the older equivalent, but append is more flexible — it accepts multiple nodes and strings.

const list = document.querySelector('ul');
const item = document.createElement('li');
item.textContent = 'New item';
list.append(item); // adds to end of list

prepend, before, after

parent.prepend() adds at the start. element.before() inserts before the element. element.after() inserts after it.

const header = document.querySelector('.card-header');
const icon = document.createElement('img');
icon.src = 'icon.svg';
header.prepend(icon); // icon goes before all other children

const divider = document.createElement('hr');
header.after(divider); // divider goes after the header

insertAdjacentHTML

element.insertAdjacentHTML(position, htmlString) inserts HTML at a specified position without replacing existing content. Positions: 'beforebegin', 'afterbegin', 'beforeend', 'afterend'.

const container = document.querySelector('.list');
container.insertAdjacentHTML('beforeend', `
  <li class="item">
    <span class="name">Alice</span>
  </li>
`);
// Still avoid with user input — XSS risk

cloneNode

element.cloneNode(true) creates a deep copy of an element including all its children. Pass false for a shallow copy. Useful for duplicating template elements.

const template = document.querySelector('.card-template');
const clone = template.cloneNode(true);
clone.querySelector('.card-title').textContent = 'New Card';
container.append(clone);

removeChild and remove()

element.remove() removes the element from the DOM. The older parent.removeChild(child) also works. Removed elements can still be referenced in variables and re-appended.

const item = document.querySelector('.to-delete');
item.remove(); // clean modern syntax

replaceWith

oldElement.replaceWith(newElement) replaces the old element in the DOM with the new one. More convenient than the older replaceChild pattern.

const old = document.querySelector('.old-banner');
const fresh = document.createElement('div');
fresh.className = 'new-banner';
fresh.textContent = 'Updated!';
old.replaceWith(fresh);

DocumentFragment for Batch Inserts

A DocumentFragment is a lightweight container that doesn't exist in the DOM. Build a subtree inside it, then append it in one operation — this causes only one reflow instead of N.

const fragment = document.createDocumentFragment();
users.forEach(user => {
  const li = document.createElement('li');
  li.textContent = user.name;
  fragment.append(li);
});
// One DOM write:
document.querySelector('ul').append(fragment);

The &lt;template&gt; Element

The HTML <template> element holds markup that isn't rendered until cloned with JavaScript. Better than building strings or cloning visible elements.

<template id="card-tpl">
  <div class="card">
    <h3 class="card-title"></h3>
    <p class="card-body"></p>
  </div>
</template>

Setting Properties vs Attributes

Element properties (el.href, el.src, el.value) are often the most direct and performant way to set values. Attributes (setAttribute) are best for custom or ARIA attributes that don't have a corresponding DOM property.

// Property (preferred for standard HTML attributes):
img.src = '/photo.webp';
link.href = '/about';

// setAttribute (for ARIA and custom attributes):
button.setAttribute('aria-expanded', 'true');
div.setAttribute('data-index', '3');

Avoiding innerHTML with User Content

When building elements from user-provided data, always use DOM methods (createElement, textContent, setAttribute) rather than building an HTML string and using innerHTML. Never interpolate user input into HTML strings.

// DANGEROUS:
container.innerHTML = `<p>${userComment}</p>`;

// SAFE:
const p = document.createElement('p');
p.textContent = userComment;
container.append(p);

Quick Check

You need to add 100 list items to a <ul> without causing 100 reflows. Which approach is best?

Recap: Creating DOM Elements

createElement creates in memory. append/prepend/before/after insert into the tree. remove() deletes an element. DocumentFragment batches inserts for performance. The