cf.completefrontendCode editorOpen lab
THE JAVASCRIPT FIELD GUIDE

The DOM tree

Learn how the browser turns HTML into a DOM tree of document, element, text, comment, and doctype nodes, including whitespace and parser repairs.

By the end, you can
  • 01
    Name the node kindsTell elements, text, comments, the document, and the doctype apart.
  • 02
    Read the treeUse childNodes, children, parents, and siblings without being surprised by whitespace.
  • 03
    Trust what the browser builtExplain why the DOM can differ from the HTML you typed.

A page becomes a tree

HTML starts as text: characters in a file or a server response. The browser reads that text with the HTML parser and builds the DOM, the Document Object Model: a live tree of objects JavaScript can inspect and change.

The root object is document. The page’s <html> element is available as document.documentElement, and inside it are document.head and document.body. One timing detail matters later: if a script in <head> runs before the parser reaches the body, document.body can still be null.

A tiny DOM skeletonText
document├─ <!DOCTYPE html>└─ HTML   ├─ HEAD   └─ BODY
Real-life analogyThe DOM is like a family tree

Once you see the page as relatives, navigation words become friendly: parent, child, sibling, ancestor, and descendant. The next lesson, Walking & searching the DOM, builds directly on those words.

In real life: Oldest ancestor
In JavaScript: document, the root document node
In real life: Child
In JavaScript: <html> is a child of the document
In real life: Parent and children
In JavaScript: <body> can contain headings, paragraphs, lists, and text
In real life: Siblings
In JavaScript: Two <li> elements in the same <ul>

Where the analogy stops: A real family can have complicated relationships. A DOM node has at most one parent, and moving a node moves that same node; it does not automatically create a copy.

Nodes and elements

SORT

Everything in the DOM tree is a node. An element is one kind of node: a tag such as <p>, <button>, or <br>. Text, comments, the document itself, and the doctype are nodes too, but they are not elements.

Common DOM node kinds
KindnodeTypeTypical nodeNameExample
Element1Uppercase tag names in HTML documents, like P; localName is lowercase<p>
Text3#textThe words inside an element, or whitespace between tags
Comment8#comment<!-- note -->
Document9#documentdocument
Document type10The doctype name, usually html<!DOCTYPE html>
Document fragment11#document-fragmentA lightweight container used by DOM APIs

Try sorting the cards. The trickiest one is class="x": attributes are reachable through element.attributes, but they are not child nodes in the tree.

Is it a node? Which kind?
  • <p>
  • the words inside it
  • <!-- note -->
  • <!DOCTYPE html>
  • document
  • the newline between two tags
  • class="x"
  • <br>
Try it yourself
0 of 8 correct

Decide whether each thing is a DOM node or not a child node.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Text, comments, and whitespace

STEP THROUGH

Text inside an element is not stored as a magic string on the element. It is a child text node. Whitespace between tags usually becomes text nodes too, which is why childNodes often contains more items than you expected. DevTools’ Elements panel hides whitespace-only text nodes by default in many views.

Real-life analogyBoxes inside boxes

When you write <p>Hello</p>, the paragraph element is the box and “Hello” is a text node inside it.

In real life: Outer box
In JavaScript: A parent element, such as <main>
In real life: Smaller box inside it
In JavaScript: A nested element, such as <p>
In real life: A note in the smallest box
In JavaScript: A text node: #text

Where the analogy stops: Boxes make nesting feel concrete, but the DOM also contains nodes that are not boxes, such as comments and the document node.

childNodes vs children
FeaturechildNodeschildren
IncludesAll child nodesElement children only
Can contain whitespace text?YesNo
Can contain comments?YesNo
Good forExact tree inspectionWorking with nested elements
Step through childNodes vs children
Step 0 of 3Ready
Your turn: follow the blue line

Step through why a parent can have more child nodes than element children.

Running in
  1. script
Next: line 1
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
  childNodes: ["#text", "P", "#comment", "BR"],  children: ["P", "BR"],};console.log(box.childNodes.length);console.log(box.children.length);
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

HTML → DOM tree viewer

INTERACTIVE

Time to inspect real parser output. The playground below runs in your browser after the page mounts. It uses new DOMParser().parseFromString(html, "text/html"), converts DOM nodes to a plain data shape, and renders rows as text. It never injects your HTML into the lesson page, and DOMParser does not run scripts from the string.

HTML → DOM tree viewer
Client-only parser sketchJavaScript
const parsed = new DOMParser().parseFromString(html, "text/html");const plainTree = convertDomNode(parsed);renderRows(treeToRows(plainTree, { hideWhitespace }));
Parsed DOM treeWhitespace shown
Try it yourself

Choose a preset, read the source, then select rows in the tree. The playground uses DOMParser after the page hydrates and renders the result as text rows, never as injected HTML.

DevTools often hides whitespace-only text nodes; the toggle lets you compare both views.

Autocorrected HTML

CHALLENGE

The HTML parser is like a teacher who silently fixes your essay before anyone reads it. Missing <html>, <head>, and <body> can be supplied. Rows directly in a table get a <tbody>. A <div> inside an open paragraph closes the paragraph first. Misnested formatting tags are repaired by rules sometimes nicknamed the adoption agency algorithm.

Real-life analogyA teacher who silently fixes your essay

When debugging, inspect the corrected copy: the DOM.

In real life: Your messy draft
In JavaScript: The HTML source you typed
In real life: Teacher’s corrected copy
In JavaScript: The DOM tree the parser built
In real life: Red marks you did not write
In JavaScript: Inserted or moved elements, like <tbody>

Where the analogy stops: The parser is not trying to understand your intention like a person. It follows detailed HTML rules, and truly invalid structures may still produce surprising trees.

Observed parser repairs
  • Rows written directly inside <table> appeared inside an automatic <tbody>.
  • A <div> inside an open <p> closed the paragraph first; the later closing paragraph created an empty paragraph in the tested parse.
  • Text after </body> ended up inside body.
  • Misnested <b> and <i> formatting tags were repaired into a valid tree.
Autocorrect challenge
Reveal codeJavaScript
const parsed = new DOMParser().parseFromString(snippet, "text/html");const tree = convertDomNode(parsed);const html = parsed.documentElement.outerHTML;
<table><tr><td>A</td></tr></table>
Browser resultWaiting

Choose a prediction, then reveal the parser’s corrected DOM.

Try it yourself

Pick the result you expect, then reveal. These results are parsed live in your browser.

Observed in-browser with DOMParser. The exact serialization can differ in harmless quote or case details across tools, but the tree relationships are the lesson.

Exploring in DevTools

TRY IT

The fastest way to build DOM intuition is to inspect a real page. Most browsers have an Elements or Inspector panel and a Console that can talk to the selected node.

  1. Open DevTools, then open the Elements or Inspector panel.
  2. Choose Inspect and click a heading, paragraph, or button on this page. Hovering nodes highlights their boxes on the page.
  3. Open the Console. In most browsers, $0 means “the node currently selected in Elements.” Try $0.nodeName and $0.localName.
  4. Compare $0.childNodes with $0.children. Expand both results.
  5. Right-click a node or logged value and look for “Store as global variable.” Most browsers create a temporary name such as temp1.
  6. Edit HTML live in the Elements panel. Notice that you are changing the DOM tree, not rewriting the original server file.
Mini mission on this page

Select the heading of this section. In the Console, run $0.nodeName, $0.childNodes, and $0.children. Then select the list above and compare the two collections again.

Where you will use this

DOM tree knowledge shows up whenever code needs to find a nearby element, remove a message, insert a new card, read text, or debug “why did my selector find that?” You will also use it when a framework renders UI: React may hide direct DOM work most days, but the browser still receives a tree.

Reading the tree in real codePop out in the code editor (opens in a new tab)JavaScript
const list = document.querySelector("ul");

console.log(list.children.length);     // element children
console.log(list.childNodes.length);   // elements, text, comments...

for (const item of list.children) {
  console.log(item.localName, item.textContent.trim());
}

In production code, prefer element-focused APIs when you want elements. Reach for node-focused APIs when text nodes and comments matter, such as writing an editor, serializer, or teaching tool like the viewer above.

Common misconceptions

  • “The DOM is the same as my source file.” The DOM is the parsed, repaired, live tree.
  • “Every node is an element.” Text, comments, the doctype, fragments, and the document are nodes too.
  • “Whitespace between tags disappears.” It often becomes text nodes, though the parser drops some whitespace in special places such as before <head>.
  • “Attributes are children.” They are reachable through attributes, but they are not child nodes.
  • “DevTools shows every node exactly as JavaScript sees it.” DevTools is excellent, but it may hide whitespace-only text nodes for readability.
  • “The parser throws an error for broken HTML.” HTML parsing is forgiving; it repairs many mistakes into a DOM tree.

Practice exercises

5 EXERCISES
Exercise 1 · Warm-upSpot the invisible node

Between two list items there is a newline and spaces. What kind of node can that whitespace become?

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · PracticePredict the two counts

    Run the program mentally. What two numbers are printed?

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    const childNodes = ["#text", "P", "#comment", "BR"];
    const children = ["P", "BR"];
    console.log(childNodes.length);
    console.log(children.length);

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeFind the bug in the mental model

      A teammate says comments are not in the DOM. Which nodeType number proves comments are nodes?

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticePredict the parser repair

        What element will the browser insert around the row?

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        <table><tr><td>Total</td></tr></table>

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeInspect this lesson page

          Use DevTools on this page. Select a list, store it as a global variable if you like, and compare its child node collection with its element children.

          Starter codePop out in the code editor (opens in a new tab)JavaScript
          // Try these in the Console after selecting an element in Elements:
          $0
          $0.nodeName
          $0.childNodes
          $0.children

            Check your understanding

            7 QUESTIONS
            The DOM tree quiz · 7 questionsScore: first tries count
            1. Question 1 of 7Which object is the root of the DOM tree for the current page?

              Choose an answer to see the explanation.

            2. Question 2 of 7What does this print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              console.log(1);
              console.log(3);
              console.log(8);

              Choose an answer to see the explanation.

            3. Question 3 of 7Which collection includes whitespace-only text nodes and comments?

              Choose an answer to see the explanation.

            4. Question 4 of 7In an HTML document, what is nodeName for a <p> element?

              Choose an answer to see the explanation.

            5. Question 5 of 7What does a browser normally insert for rows written directly inside <table>?

              Choose an answer to see the explanation.

            6. Question 6 of 7What is true about document.body while a script in <head> runs before the body is parsed?

              Choose an answer to see the explanation.

            7. Question 7 of 7Which statement about attributes is accurate?

              Choose an answer to see the explanation.

            Key takeaways

            • The DOM is the browser’s live, parsed tree of nodes.
            • Elements are nodes, but text, comments, the doctype, fragments, and the document are nodes too.
            • childNodes includes every child node; children includes only element children.
            • The HTML parser repairs many broken structures, so the DOM can differ from source HTML.
            • Use DevTools and $0 to connect what you see with JavaScript objects.

            One-line definition: the DOM tree is the browser’s corrected, live object tree for a document.

            Up next: Walking & searching the DOM.

            CompleteFrontend Clear concepts. Working examples.