Creating a DOM element
To create an element in the DOM you use the document.createElement() method. It creates a new element that you can then add to the page.
Theory
TL;DR
document.createElement('tag')creates a node in memory; it is not on the page yet.- Then you configure the element:
textContent,className,classList,id, attributes. - Inserting it into the document:
appendChild(),append(),prepend(),insertBefore(),after(),before(). insertBefore()lets you put the element at a specific position instead of only at the end.- Nested structures are assembled bottom up, and only one finished root is added to the document.
Quick example
const div = document.createElement('div'); // create a <div> element
div.textContent = 'Hello, world!'; // add the text
document.body.appendChild(div); // insert it at the end of bodyThe result in HTML:
<body>
<div>Hello, world!</div>
</body>The three steps of creating an element
Creating an element in the DOM always consists of three steps:
document.createElement('tag')creates the element.- You configure it: add text, attributes, classes and so on.
- You add it to the document with
appendChild(),prepend(),insertBefore(),after()orbefore().
Until the third step is done the element exists apart from the page: it is in memory, but it has no parent node and is not rendered.
Attributes, classes and content
const button = document.createElement('button');
button.textContent = 'Click me';
button.className = 'btn-primary';
button.id = 'myButton';
document.body.appendChild(button);This shows the three usual settings at once: the text through textContent, the class through className (or classList.add() when the class has to join existing ones), and the id. Arbitrary attributes are set with setAttribute('data-role', 'submit').
Nested elements
A more complex structure is assembled piece by piece, and only the finished root is added to the document:
const card = document.createElement('div');
card.classList.add('card');
const title = document.createElement('h2');
title.textContent = 'Card';
const desc = document.createElement('p');
desc.textContent = 'This is an example of a dynamically created block.';
card.appendChild(title);
card.appendChild(desc);
document.body.appendChild(card);This order pays off: the browser recalculates the layout once, when the fully built card enters the document, instead of after every nested element.
Inserting at a specific position
If the element has to go not at the end but, for example, before or after another element:
const newItem = document.createElement('li');
newItem.textContent = 'New item';
const list = document.querySelector('ul');
list.insertBefore(newItem, list.firstChild); // insert at the start of the listModern alternatives do the same thing more concisely:
| Method | Where it inserts |
|---|---|
parent.append(el) | at the end of the parent element |
parent.prepend(el) | at the start of the parent element |
parent.insertBefore(el, ref) | before the ref node inside parent |
ref.before(el) | before the ref element |
ref.after(el) | after the ref element |
Common mistakes
- Forgetting to insert the element into the document. After
createElementthe element is not attached anywhere, so it is not visible on the page even though the variable looks fine in the console. - Confusing
append()andappendChild().appendChild()takes a single node and returns it, whileappend()takes several nodes and strings but returns nothing. - Inserting HTML as a string through
innerHTML. For user supplied data this opens the door to XSS; for plain texttextContentis safer. - Adding elements one by one straight into the document inside a loop. Every insertion forces the browser to recalculate the layout; build the tree separately, or use a
DocumentFragment, and insert it once. - Expecting one node to end up in two places. Inserting an element that already exists moves it rather than copying it; to get a real copy use
cloneNode(true).
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.