Skip to content
Laviyx Learn

Try

JavaScript course menu

Creating and Removing DOM Elements: createElement, append, remove and Templates

Learn to add and remove elements with JavaScript: createElement, setting text and attributes, append, prepend, before, after and insertAdjacentHTML, removing elements, rendering lists from arrays, DocumentFragment, and the template element.

Intermediate8 min readUpdated
On this page

Real interfaces add and remove content all the time: new chat messages, items added to a cart, search results. JavaScript builds elements and inserts them into the DOM.

Creating an element#

Three steps: create, configure, insert:

HTML
<ul id="list">
  <li>Existing item</li>
</ul>
JavaScript
const li = document.createElement("li");       // 1. create
li.textContent = "Added with JavaScript";        // 2. configure
li.className = "new";
li.style.color = "seagreen";
document.querySelector("#list").append(li);     // 3. insert
Result

A created element is not visible until it is inserted into the document.

Where to insert#

HTML
<p>Before the list</p>
<ul id="list"><li>Middle</li></ul>
<p>After the list</p>
JavaScript
const list = document.querySelector("#list");
const make = (text) => Object.assign(document.createElement("li"), { textContent: text });

list.append(make("append: last child"));
list.prepend(make("prepend: first child"));
list.before("before: a text node before the list");
list.after("after: a text node after the list");
Result
MethodInserts
parent.append(...nodes)At the end, inside the parent
parent.prepend(...nodes)At the start, inside the parent
el.before(...nodes)Just before the element, outside it
el.after(...nodes)Just after the element, outside it
el.replaceWith(node)In place of the element

They accept elements and plain strings (which become text nodes) and can take several at once. Inserting an element that is already in the page moves it.

Removing elements#

HTML
<ul id="list">
  <li>Keep me</li>
  <li class="old">Remove me</li>
  <li>Keep me too</li>
</ul>
<button id="clean">Remove old items</button>
<button id="clear">Clear list</button>
JavaScript
document.querySelector("#clean").addEventListener("click", () => {
  document.querySelectorAll("#list .old").forEach((li) => li.remove());
});
document.querySelector("#clear").addEventListener("click", () => {
  document.querySelector("#list").replaceChildren();   // remove all children
});
Result
  • element.remove() removes the element itself.
  • parent.replaceChildren() with no arguments removes all children; with arguments, it replaces them.

Rendering a list from data#

A very common task: turn an array of data into elements:

HTML
<h3>Courses</h3>
<ul id="courses"></ul>
JavaScript
const courses = [
  { name: "HTML", lessons: 46 },
  { name: "CSS", lessons: 47 },
  { name: "JavaScript", lessons: 56 },
];

const list = document.querySelector("#courses");
const items = courses.map((course) => {
  const li = document.createElement("li");
  const strong = document.createElement("strong");
  strong.textContent = course.name;
  li.append(strong, ` (${course.lessons} lessons)`);
  return li;
});
list.replaceChildren(...items);
Result

Building elements and setting textContent is safe even if the data comes from users. (Inserting all items in one replaceChildren call, or through a DocumentFragment, also means the browser updates the layout once instead of once per item.)

insertAdjacentHTML#

For trusted markup, insertAdjacentHTML inserts HTML at a position without wiping the existing content (unlike innerHTML +=):

JavaScript
list.insertAdjacentHTML("beforeend", "<li><em>Static, trusted markup</em></li>");
// positions: "beforebegin", "afterbegin", "beforeend", "afterend"

The same XSS warning as innerHTML applies: never insert user input this way.

The template element#

For larger repeated structures, write the markup once in a <template>. Its contents are not shown on the page; you clone them in JavaScript:

HTML
<template id="card-template">
  <article style="border: 1px solid #ccc; border-radius: 8px; padding: 8px 12px; margin-bottom: 8px">
    <h3 class="name"></h3>
    <p class="role"></p>
  </article>
</template>
<div id="team"></div>
JavaScript
const team = [
  { name: "Asha", role: "Front-end developer" },
  { name: "Ravi", role: "Data analyst" },
];
const template = document.querySelector("#card-template");

for (const person of team) {
  const card = template.content.cloneNode(true);
  card.querySelector(".name").textContent = person.name;
  card.querySelector(".role").textContent = person.role;
  document.querySelector("#team").append(card);
}
Result

template.content.cloneNode(true) makes a deep copy of the template's contents each time.

Frameworks#

Creating and updating many elements by hand gets complicated as an app grows. Frameworks such as React, Vue and Svelte let you describe what the page should look like for given data, and update the DOM for you. They are built on exactly the operations in this lesson.

Practice#

Practice exercise

Build a simple to-do list: a text input, an "Add" button that adds the trimmed text as a new list item (ignore empty input and clear the field afterwards), and a "Delete" button inside each item that removes it.

Show solution
HTML
<input id="task" placeholder="New task">
<button id="add">Add</button>
<ul id="todo"></ul>
JavaScript
const input = document.querySelector("#task");
const list = document.querySelector("#todo");

document.querySelector("#add").addEventListener("click", () => {
  const text = input.value.trim();
  if (text === "") return;

  const li = document.createElement("li");
  const del = document.createElement("button");
  del.textContent = "Delete";
  del.addEventListener("click", () => li.remove());

  li.append(text + " ", del);
  list.append(li);
  input.value = "";
  input.focus();
});
Result

Key takeaway#

Finished this lesson?