The contenteditable "plaintext-only" attribute value combination is now Baseline Newly available

Published: Mar 20, 2025

When you want to allow the user to enter plaintext information, your first instinct might be to reach for a <textarea>. This works for many cases and requires no special effort to make it work with forms, but also has limitations.

One example is growing the <textarea> dynamically with the content without resolving to hacks. There's field-sizing: content, but it has limited browser support. This is where the contenteditable="plaintext-only" attribute value combination comes in. You can add it to generic elements like <div>, and have the element automatically take care of resizing.

Another limitation is styling. The CSS Custom Highlight API provides a mechanism for styling arbitrary text ranges on a document by using JavaScript to create the ranges, and CSS to style them. A <textarea> internally uses a <div> in the user agent shadow root, which is why styling the text with the CSS Custom Highlight API doesn't work. If used on an element like a <div> directly that you have made contenteditable, the CSS Custom Highlight API works just fine.

<style>   ::highlight(highlight) {     background-color: yellow;     color: black;   } </style>  <div contenteditable="plaintext-only">Edit me</div>  <script>   const parentNode = document.querySelector('div').firstChild;   const range = new Range();   range.setStart(parentNode, 0);   range.setEnd(parentNode, 3);   const highlight = new Highlight(range);   CSS.highlights.set('highlight', highlight); </script> 

Chrome DevTools Elements panel inspecting a textarea showing that it's using a div in a user-agent shadow root.

Here's a screenshot of the demo that shows this limitation. Note how the text in the <textarea> isn't styled, but the text in the two contenteditable generic <div> elements is.

Demo showing how the CSS Custom Highlight API only works with the contenteditable div elements, but not the textarea.