How to Preserve Line Breaks of Textarea Values with CSS
CSS is all you need
The textarea element is a useful native HTML element for allowing users to write multiline text. Unlike a regular input element, textarea can contain line breaks.
A common use case is to render the content of a textarea as plain text. Frameworks such as Angular, React and Vue.js make it easy to render text based on a property. E.g. with Angular you can do something like this:
<textarea *ngIf="!readonly" [(ngModel)]="description"></textarea>
<div *ngIf="readonly">{{ description }}</div>
A potentially surprising issue is that line breaks may not be rendered as expected. See the example below:
As you can tell, line breaks are ignored and text is rendered as one big block even though the textarea itself looks fine. Line breaks in textarea elements are typically stored as\n
. And frameworks like Angular sanitize content rendered via data binding which is a good thing for various reasons like security.
Let’s investigate this issue and see how we can solve this with ease.
CSS to the rescue
A native approach could be to insert HTML. It is simple to use the innerHTML
property or one of the DOM APIs to insert the text programmatically. However, we should avoid inserting raw HTML if possible as that can introduce the possibility of injection and it feels like shooting birds with cannons.
Luckily, there’s a simple CSS property called white-space
we can use to solve our little issue. This property can take a couple of different values but I found pre-line
to be what I’d typically need.
/* preserve line breaks for text originating from a textarea */
.preserveTextareaLineBreaks {
white-space: pre-line;
}
Now let’s have another look at our simple example after applying our white-space
change:
As you can tell, we can now see line breaks in the rendered text thanks to our little CSS change. If this is something we need more than a few times it may make sense to create a global CSS class that can be referenced across our application.
Conclusion
Thanks for reading this short post! Simple problem, simple solution — is that not what we want? Let me know in the comments about alternative approaches you have taken.