Skip to main content Accessibility Feedback

How to truncate text with vanilla JavaScript

The CSS text-overflow property provides a relatively easy way to truncate content.

It’s not without problems, though. It only works for a single line of text (you can’t truncate after several lines), and it will truncate in the middle of a word instead of at the end of one.

Today, I want to share a simple JavaScript approach to truncating content.

Setup our markup

First, let’s setup some simple markup to use. I went and grabbed some dummy text from the Pirate Ipsum website, and added it to a div with the .truncate class.

You can use any selector you’d like. Just make sure there’s a way to target the content to truncate.

<div class="truncate">
	Port tender gun spanker lanyard heave to topmast. Heave down draught piracy loaded to the gunwalls mizzenmast topsail Brethren of the Coast. Lanyard snow Jack Ketch swing the lead maroon spike black jack.
</div>

Creating a truncate() function

Let’s setup a truncate() function, and pass in two arguments.

The first, elem, will be the element whose content we want to truncate. The second, limit, will be the number of words to truncate the content by. If either of those is missing, we’ll end the function.

var truncate = function (elem, limit) {

	// Make sure an element and number of items to truncate is provided
	if (!elem || !limit) return;

};

If we, for example, wanted to limit our .truncate content to just seven words, we would do this.

var elem = document.querySelector('.truncate');
truncate(elem, 7);

Truncating the content

Next, we need a way to get the content from our element.

I often use innerHTML for this sort of thing, but we only want the text, not the markup. If we, for example, got content that had an opening div element, and split it before the closing element, we could cause layout issues.

For this, we’ll use the textContent property. Let’s also remove any leading or trailing whitespace with the trim() method.

var truncate = function (elem, limit) {

	// Make sure an element and number of items to truncate is provided
	if (!elem || !limit) return;

	// Get the inner content of the element
	var content = elem.textContent.trim();

};

Now we’re ready to truncate our content.

To do this, we’ll convert our string of text into an array, with each word as it’s own item. We’ll use the split() method, passing in a space as the character to split our string by.

var truncate = function (elem, limit) {

	// Make sure an element and number of items to truncate is provided
	if (!elem || !limit) return;

	// Get the inner content of the element
	var content = elem.textContent.trim();

	// Convert the content into an array of words
	content = content.split(' ');
	console.log(content);

};

If you logged content into the console, you would get back an array of words. See it in action here.

The .slice() method lets you create a new array, that’s a subset of another one. It accepts two arguments. The first is where to start, and the second is where to end.

We’ll pass in 0 as the starting point to start with the first word. We’ll pass in our limit argument as the ending point. We can chain this method to the split() method to keep the code smaller.

var truncate = function (elem, limit) {

	// Make sure an element and number of items to truncate is provided
	if (!elem || !limit) return;

	// Get the inner content of the element
	var content = elem.textContent.trim();

	// Convert the content into an array of words
	// Remove any words above the limit
	content = content.split(' ').slice(0, limit);
	console.log(content);

};

If you log content to the console now, you’ll notice it only has seven items instead of the original 33. Here’s an updated demo.

Injecting our truncated content back into the DOM

Now that we’ve truncated our content, we need to add it back into the DOM.

We’ll convert it back into a string using the join() method, which combines array items into a string. We’ll pass in a space as a delimiter (what it will add between each item).

var truncate = function (elem, limit) {

	// Make sure an element and number of items to truncate is provided
	if (!elem || !limit) return;

	// Get the inner content of the element
	var content = elem.textContent.trim();

	// Convert the content into an array of words
	// Remove any words above the limit
	content = content.split(' ').slice(0, limit);

	// Convert the array of words back into a string
	content = content.join(' ');

};

Now we can inject it back into the DOM with the same textContent property we used to get our content.

var truncate = function (elem, limit) {

	// Make sure an element and number of items to truncate is provided
	if (!elem || !limit) return;

	// Get the inner content of the element
	var content = elem.textContent.trim();

	// Convert the content into an array of words
	// Remove any words above the limit
	content = content.split(' ').slice(0, limit);

	// Convert the array of words back into a string
	content = content.join(' ');

	// Inject the content back into the DOM
	elem.textContent = content;

};

Here’s a demo with our new truncated content.

Adding trailing characters

There’s on weird thing about our new truncated content: it ends abruptly. Ideally, we would add some characters after it to indicate that it’s been truncated, like ellipsis (...);

Let’s add one more optional argument to our function: after.

If it exists, we’ll append our newly joined content with. Otherwise, we’ll just append an empty string. I’ll be using a ternary operator to keep the code a bit more compact.

var truncate = function (elem, limit, after) {

	// Make sure an element and number of items to truncate is provided
	if (!elem || !limit) return;

	// Get the inner content of the element
	var content = elem.textContent.trim();

	// Convert the content into an array of words
	// Remove any words above the limit
	content = content.split(' ').slice(0, limit);

	// Convert the array of words back into a string
	// If there's content to add after it, add it
	content = content.join(' ') + (after ? after : '');

	// Inject the content back into the DOM
	elem.textContent = content;

};

Now we can truncate our content like this.

var elem = document.querySelector('.truncate');
truncate(elem, 7, '...');

Here’s a demo of the final script in action.

Browser Compatibility

The textContent and trim() method both require IE9 or higher.

There’s a polyfill for trim() that pushes support back to at least IE6. Older versions of IE use the innerText property instead of textContent. You can modify the script to support IE6+ by checking which one is supported and using that.

/**
 * String.prototype.trim() polyfill
 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
 */
if (!String.prototype.trim) {
	String.prototype.trim = function () {
		return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
	};
}

var truncate = function (elem, limit, after) {

	// Make sure an element and number of items to truncate is provided
	if (!elem || !limit) return;

	// Get the inner content of the element
	var content = elem.textContent || elem.innerText;
	content = content.trim();

	// Convert the content into an array of words
	// Remove any words above the limit
	content = content.split(' ').slice(0, limit);

	// Convert the array of words back into a string
	// If there's content to add after it, add it
	content = content.join(' ') + (after ? after : '');

	// Inject the content back into the DOM
	if (elem.textContent) {
		elem.textContent = content;
	} else {
		elem.innerText = content;
	}

};