concept Frontend & browsers
The browser DOM explained
The DOM is a tree of nodes representing a document. A browser builds it as it parses HTML, and scripts can update that tree after the initial parse.
What it means
HTML is markup; the DOM is the document structure built from it. Parsing creates nodes and parent–child relationships that scripts can inspect and update. Element nodes represent elements, while Text nodes hold characters within the document.
A child-node count is not an element count. The tiny example starts with one parent whose two direct children are a Text node and an empty Element. Both count as children. Changing the characters in the Text node can therefore update the document without changing its structure.
Try it
Example: start with Action = edit text node, Initial child nodes = 2 and Replacement text = Updated label. Inspect the result, then change only Action to append child. Select Compare with baseline to compare the documented baseline with the current result. No live document is changed.
Explore a tiny DOM tree
Change one condition and inspect the computed result, its cause, and the model boundary.
The first child, when present, is a Text node; remaining children are empty elements. This local representation is not the live page DOM.
Editing existing Text.data preserves the child-node count.
Result nodes: Text("Updated label"), Element
| Input | Supplied value |
|---|---|
| Action | edit text node |
| Initial child nodes | 2 |
| Replacement text | Updated label |
Synthetic local learning example. No account, real network, server, filesystem, credential, command or production change is accessed.
About this model
The first child, when present, is a Text node; remaining children are empty elements. This local representation is not the live page DOM.
These are bounded teaching rules. Actual behavior needs the linked subject specifications and independent observations. The examples are not live checks.
2 child node(s) after action. Editing existing Text.data preserves the child-node count. Result nodes: Text("Updated label"), Element.
Keep Initial child nodes = 2 and Replacement text = Updated label while changing Action. Each evaluation starts from the same two-child list; it does not continue from the previous result.
Reset restores Action = edit text node, Initial child nodes = 2 and Replacement text = Updated label. It clears input errors and the baseline comparison. There is no running clock or stored action history to reset. Your independently opened or closed FAQ answers and About this model panel stay as you left them.
How it works
The important distinction is between changing a node's data and changing which nodes belong to its parent. In this model, edit text node targets the first Text node. Replacing its characters leaves that node in the same child list, so the count stays unchanged. Appending or removing a child changes the list itself.
| Action | Target and structural effect |
|---|---|
| edit text node | Changes the first Text node's data without adding or removing children. |
| append child | Adds one empty Element at the end of the list. |
| remove child | Removes the last child, not necessarily an element. |
| replace textContent | Replaces all children with one Text node for nonempty text, or no children for an empty string. |
For an element, assigning textContent is therefore not shorthand for editing whichever Text node already exists. It replaces the child list. The assigned value is text, not markup to parse into new elements.
The empty-string boundary makes the difference especially clear: with three initial children, replace textContent and an empty Replacement text value produce zero child nodes. Editing an existing Text node's data to an empty string instead preserves that node and the surrounding child list. Empty text and an empty child list are different structures.
Worked example
This is a synthetic baseline, not a browser capture or production measurement.
| Input | Value |
|---|---|
| Action | edit text node |
| Initial child nodes | 2 |
| Replacement text | Updated label |
Before the action, the child list is Text("Original label"), Element. The selected action changes the first node's data to "Updated label"; it does not remove that node or its sibling.
The result is 2 child node(s) after action. Result nodes: Text("Updated label"), Element. The unchanged count follows from preserving both nodes, not from the replacement text having any particular length.
What changes when the condition changes
Change only Action to append child. Keep Initial child nodes = 2 and Replacement text = Updated label.
The result is 3 child node(s) after action. Result nodes: Text("Original label"), Element, Element.
Appending adds one empty Element to the starting list. It does not use Replacement text, so the first Text node still contains "Original label". This is not an append performed after the previous edit: each evaluation starts from the initial list again. The contrast therefore shows two different operations on the same starting structure, not a sequence of accumulated edits.
In practice
When debugging a page you own or are authorized to inspect, begin with a read-only examination of the current DOM. Identify the parent, its direct children and the property the relevant code assigns. A text label and the element containing it are different targets.
If neighboring elements unexpectedly disappear, look for an assignment to the parent's textContent rather than assuming that every text update preserves structure. If the child list stays intact but the page looks different, the count alone cannot explain the appearance; style and layout are separate evidence to examine.
Stop before editing application code if you cannot identify the target node or distinguish these operations. The safe next step is to reproduce the structure in an isolated local example, not to treat this model's result as a diagnosis of your page. No live-page mutation or console command is needed to use this lesson.
Limits and unknowns
The example represents only a parent's immediate child list. It is not the live page DOM, does not parse your HTML and makes no claim about visibility, performance or painted output. All controls act locally; no real page, account, server or network resource is changed.
Initial child nodes has a displayed range of 0–20. If an input is rejected as invalid, the previous calculated outcome is removed; correct the value or use Reset before interpreting a result. An empty Replacement text value is meaningful, not automatically an error.
With zero initial children, edit text node and remove child report No target child exists rather than inventing a successful operation. Choose a nonempty initial count to evaluate either action. A previous append does not supply a target for the next evaluation because actions do not accumulate. By contrast, append child and replace textContent can operate on an initially empty list.
The initial example and explanation remain readable without JavaScript. Interactive controls require JavaScript.
What to carry forward
Choose the observation that matches your question: a Text node's data for its characters, the parent's child list for document structure, and rendering evidence for appearance. Before changing code, identify the target node and property; the same intended label update can preserve neighboring elements or replace them, depending on that choice.
Frequently asked questions
Editorial questions, answered from the sources listed for this article.
Why can View Source disagree with the DOM inspector?
View Source describes the delivered HTML source; the DOM inspector shows the current node structure. Browser parsing and later script changes can make that structure differ from the source. Use the source to examine delivered markup and the inspector to examine the current document.
Does changing Text.data remove sibling elements?
No. Changing Text.data changes that existing Text node's character data; the assignment itself does not remove sibling elements. Be careful to distinguish the Text node from its parent element: assigning the parent's textContent has different child-list effects.
What happens when element.textContent is set to an empty string?
The element's existing children are removed, and no replacement Text node is inserted for the empty string. Its child-node count is therefore zero. That is structurally different from setting an existing Text node's data to an empty string: the empty Text node still counts as a child.
Does a DOM child count tell me how many items are visibly painted?
No. Child-node counts include Text nodes as well as elements, and presentation also depends on style and layout. A child-list count is not a count of visible boxes or a measurement of painted pixels; you need separate rendering evidence for that question.
Sources & model boundaries
Primary references used for this explanation. The interactive example is an educational model, not a live check.
- WHATWG DOM Living Standard
Node.textContent; string replace all; CharacterData. Element text replacement and editing a text node have different effects
Checked .
- MDN: Node.textContent
Value, differences and child replacement. textContent is text, not rendered appearance or HTML parsing
Checked .
- MDN: critical rendering path
DOM, CSSOM, render tree, layout and paint. Rendering has distinct dependencies and stages, not one universal timing formula
Checked .
- Chrome DevTools: DOM
Appendix: HTML versus the DOM; Elements panel. Distinguishes initial HTML from the parsed DOM and subsequent script changes. Inspection of DOM does not rewrite the response source.
Checked .
- Chrome DevTools: badges reference
View-source. The badge is an alternative to View Page Source and opens page source in Sources; Elements remains the DOM inspection surface.
Checked .