innerText vs textContent in JavaScript

OpenJavaScript 0

Last updated: September 20, 2022.

innerText and textContent are two methods available in JavaScript for getting and setting text inside elements.

Though both methods are similiar in that they apply to text data, innerText and textContent work very differently under the hood. In practice, this can lead to very different outcomes when the are used.

Learn the differences and hwo not to get caught out by reading on!

Table of contents

A tale of two approaches

Both methods extract and set text.

The main difference, though, concerns formatting.

innerText respects and actively formats text to include its original formatting. For example:

  • When getting:
    • Surrounding non-text content (e.g. HTML tags) are removed
    • Non-visible text is excluded
  • When setting:
    • A string does not lose its (e.g. multi-line) formatting

You can think of innerText as actively working to get and set text as it appears to the human reader.

Examples

Getting text

Consider the following example, that includes some indentation:

<body>
    <div id="article">
        <h2>Hello there <span style="visibility: hidden;">world</span></h2>
        <div>The content...the content...the content</div>
    </div>
</body>

Here is the result of extracting the text from the article element using innerText:

const innerText = document.querySelector('#article').innerText;
console.log(innerText);
// Hello there 
// The content...the content...the content

The indentation in the markup has been removed and the hidden text world is not included.

In other words, the extracted text is roughly what the user sees on the page.

And here is the very different result you get with textContent:

console.log(textContent);
//    
//        Hello there world
//        The content...the content...the content
//    

It returns the text as it appears in the markup, including the indentation.

Non-text content is replaced by whitespace. And the hidden world text does appear.

This is because textContent does not actively attempt to get the text as it appears to the human reader.

Only textContent can get a text node

Usually, you are getting and setting text inside an element.

But sometimes, you may want to get text that exists outside an element, floating freely as a text node.

In this case, only textContent is able to get the text:

<body>
    <article>
        <h2>Article title</h2>
        <span>Content...content...content</span>
        Not William Shakespeare
    </article>
</body>
<script>

    console.log(document.querySelector('article').lastChild.innerText);
    // Returns: 
    // undefined
        
    console.log(document.querySelector('article').lastChild.textContent);
    // Returns:
    // 
    // Not William Shakespeare
    //     
    
</script>

Setting text

For writing a simple one-line string inside an element, the use of innerText and textContent lead to identical outcomes.

But as soon as a string contains formatting, outcomes differ.

For example, below is a multi-line address contained in a template string:

const address = `
123 Developer Avenue
Only Way is Essex
CB10 1FD
`;

Use innerText to write this to the DOM, and the multi-line formatting is maintained:

document.body.innerText = address;

// 123 Developer Avenue
// Only Way is Essex
// CB10 1FD
✔️

textContent, on the other hand, makes no active attempt to render the text as it would appear to a human reader. The result is that the address is returned on a single line:

document.body.textContent = address;

// 123 Developer Avenue Only Way is Essex CB10 1FD
😱

Performance differences

Because innerText actively formats text to appear as it would to a human reader, it is also more performance heavy.

innerText is especially slow relative to textContent when there is a lot of formatting needed to transform text from its state in the DOM or a string to make it like it appears to the human eye.

In the case of writing a simple, one-line string to the DOM ("Be a pineapple"), we found textContent to be almost twice as fast as innerText!

Results from jsben.ch test

Summary

The core difference between innerText and textContent:

  • innerText gets and sets text in the way it appears to a human reader
  • textContent gets and sets text without actively formatting it

While the extra work done by innerText to make text more presentable is welcome, this also makes it more performance-heavy than textContent.

Therefore, we recommend the following:

  • Use textContent in situations where textContent and innerText would lead to the same outcome for optimal performance
  • Use innerText when the preservation of human-readable formatting is needed

Related links