innerHTML, textContent, & innerTextJavaScript offers multiple properties to inspect and update the HTML content or text inside DOM element nodes: textContent, innerText, innerHTML, and outerHTML.
flowchart TD
ContentReq["Updating Element Content"] --> TypeCheck{"Injecting Raw Text or HTML Markup?"}
TypeCheck -- "Plain Text (XSS Safe)" --> TextChoice{"Need Performance or Rendered Style?"}
TextChoice -- "Performance & Raw Text" --> TextContent["textContent (Fast, Safe, Preserves Hidden Text)"]
TextChoice -- "Aware of CSS Visibility" --> InnerText["innerText (Reflects rendered layout & styles)"]
TypeCheck -- "HTML Markup Injection" --> HTMLChoice{"Replace Inside or Entire Node?"}
HTMLChoice -- "Inner Markup" --> InnerHTML["innerHTML"]
HTMLChoice -- "Entire Outer Node" --> OuterHTML["outerHTML"]
| Property | Parses HTML Tags? | Triggers Layout Reflow? | XSS Safe? | Performance |
|---|---|---|---|---|
textContent |
No (Escapes tags) | Minimal | Yes | Extremely Fast |
innerText |
No (Escapes tags) | Yes (Reads layout) | Yes | Slower |
innerHTML |
Yes (Parses HTML) | Yes | No (Vulnerable to XSS) | Heavy |
outerHTML |
Yes (Replaces host too) | Yes | No | Heavy |
// Demonstrating textContent vs innerText vs innerHTML
document.addEventListener("DOMContentLoaded", () => {
const container = document.createElement("div");
container.innerHTML = `
<style>.hidden { display: none; }</style>
<p id="demo">Visible Text <span class="hidden">Hidden Text</span></p>
`;
document.body.appendChild(container);
const demoEl = document.getElementById("demo");
// 1. Comparing textContent vs innerText
console.log(`textContent: "${demoEl.textContent.trim()}"`); // "Visible Text Hidden Text"
console.log(`innerText: "${demoEl.innerText.trim()}"`); // "Visible Text" (Aware of display:none!)
// 2. Safe Text Update with textContent (XSS Prevention)
const userComment = "<img src='x' onerror='alert("XSS")'>";
const safeBox = document.createElement("div");
safeBox.textContent = userComment; // Escapes markup cleanly!
document.body.appendChild(safeBox);
// 3. Injecting HTML with innerHTML
const cardBox = document.createElement("div");
cardBox.innerHTML = `<h3 class="title">Safe Formatted Card</h3>`;
document.body.appendChild(cardBox);
});
textContent for Plain Text: Using textContent prevents Cross-Site Scripting (XSS) because it escapes all HTML tags and does not trigger expensive layout calculations.innerHTML: Never pass unsanitized user input into innerHTML.innerHTML += Trap: Writing el.innerHTML += "<span>text</span>" destroys and recreates all existing child DOM nodes and event listeners attached inside el. Use insertAdjacentHTML() or appendChild() instead.Why does element.textContent = "<h1>Hi</h1>" display literal string <h1>Hi</h1> on the screen instead of rendering a heading?
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.