139

I want to be able to say

$(someElem).text('this\n has\n newlines);

and it renders with newlines in the browser. The only workaround I have found is to set the css property 'white-space' to 'pre' on someElem. This almost works, but then I have an annoyingly large padding between the text and the top of someElem, even when I set padding to 0. Is there a way to get rid of this?

Joe Armstrong
  • 1,551
  • 2
  • 10
  • 5
  • 3
    wrapping it with `
    ` tags (and using .html() instead of .text()) is the easiest and best solution for maintaining line breaks from a text file or from plain text in my opinion (this is suggested by Karim's answer below). 
    HOWEVER: The newer alternative to this is to use `white-space: pre-wrap;` as suggested in cleong's answer
    – edwardtyl Jul 24 '15 at 17:09
  • 2
    why not use `append()` instead of `test()` and `
    ` instead of `\n` ? like this - `$(someElem).append("this
    has
    newlines");`
    – Erfan Ahmed Jun 11 '18 at 04:07
  • Possible duplicate here: https://stackoverflow.com/q/18071164/1066234 – Avatar Jun 23 '23 at 15:02

9 Answers9

160

It's the year 2015. The correct answer to this question at this point is to use CSS white-space: pre-line or white-space: pre-wrap. Clean and elegant. The lowest version of IE that supports the pair is 8.

https://css-tricks.com/almanac/properties/w/whitespace/

P.S. Until CSS3 become common you'd probably need to manually trim off initial and/or trailing white-spaces.

cleong
  • 7,242
  • 4
  • 31
  • 40
  • I would agree with your premise, except some of us aren't blessed with systems that let us (easily) arbitrarily customize the CSS. For example, I'm maintaining a LightSwitch system which requires me to do all customization in post-render javascript, so that's another piece of strange code behind the scenes. – Liam Dawson Jun 21 '16 at 02:47
  • if you copy paste the pre-wrapped content from the browser to a word processor -> line breaks are lost – r3mark Oct 13 '16 at 02:08
  • This is a good solution to handle multi-line text output. [MDN - white-space](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) – Nick Tsai Dec 21 '18 at 05:31
  • 2
    i'm a bit confused, how does this answer allow you to 'control' where the breaks occur? doesn't this answer simply integrate line wrap? also how can this possibly be the answer when the OP says they tried this already and it doesn't do what they are looking for? – greenhouse Apr 12 '21 at 02:40
  • I usually don't like CSS "hacks" but ya know what, this is a great solution in my case. Using `.html()` is too insecure, so I'm going with this. – Gavin Oct 06 '22 at 15:54
72

If you store the jQuery object in a variable you can do this:

var obj = $("#example").text('this\n has\n newlines');
obj.html(obj.html().replace(/\n/g,'<br/>'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="example"></p>

If you prefer, you can also create a function to do this with a simple call, just like jQuery.text() does:

$.fn.multiline = function(text){
    this.text(text);
    this.html(this.html().replace(/\n/g,'<br/>'));
    return this;
}

// Now you can do this:
$("#example").multiline('this\n has\n newlines');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="example"></p>
Polyana Fontes
  • 3,156
  • 1
  • 27
  • 41
37

Here is what I use:

function htmlForTextWithEmbeddedNewlines(text) {
    var htmls = [];
    var lines = text.split(/\n/);
    // The temporary <div/> is to perform HTML entity encoding reliably.
    //
    // document.createElement() is *much* faster than jQuery('<div></div>')
    // http://stackoverflow.com/questions/268490/
    //
    // You don't need jQuery but then you need to struggle with browser
    // differences in innerText/textContent yourself
    var tmpDiv = jQuery(document.createElement('div'));
    for (var i = 0 ; i < lines.length ; i++) {
        htmls.push(tmpDiv.text(lines[i]).html());
    }
    return htmls.join("<br>");
}
jQuery('#div').html(htmlForTextWithEmbeddedNewlines("hello\nworld"));
Peter V. Mørch
  • 13,830
  • 8
  • 69
  • 103
  • 1
    In fact, it is superior to Mark's suggestion because it isn't at risk of a XSS attack. – Andrew B. May 30 '12 at 22:03
  • I think you could create the div (i.e.: document.createElement('div')) out of the function and just use it for all calls right? – Fabio Zadrozny Dec 06 '12 at 19:57
  • @FabioZadrozny: Yes, you're right! I've edited the answer (almost) accordingly. The div is created inside the function but outside the loop now. It could be outside the function entirely, but then it gets cumbersome to use. – Peter V. Mørch Dec 11 '12 at 08:38
  • 1
    I believe @cleong's answer is the best solution for this – minillinim Sep 04 '15 at 03:29
  • If you have explicit newline characters in your text, then you might want to split using `text.split(/\\n/)`, or even `text.split(/\\\\n|\\n|\n/)`. I encountered this while passing around text in JSON format with an API which embedded literal `\n` control characters in strings. – D. Visser Mar 25 '16 at 11:46
23

Alternatively, try using .html and then wrap with <pre> tags:

$(someElem).html('this\n has\n newlines').wrap('<pre />');
karim79
  • 339,989
  • 67
  • 413
  • 406
15

You can use html instead of text and replace each occurrence of \n with <br>. You will have to correctly escape your text though.

x = x.replace(/&/g, '&amp;')
     .replace(/>/g, '&gt;')
     .replace(/</g, '&lt;')
     .replace(/\n/g, '<br>');
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • 7
    Some people reading this answer are likely to not know how dangerous this is. Never use this solution with user-supplied text. Peter Mørch's solution is preferable. – Andrew B. May 30 '12 at 22:02
  • 1
    @kulebyashik Peter's solution use `text` while this answer use `html` directly. – John Xiao Dec 21 '15 at 03:33
5

Try this:

$(someElem).html('this<br> has<br> newlines);
daCoda
  • 3,583
  • 5
  • 33
  • 38
1

I would suggest to work with the someElem element directly, as replacements with .html() would replace other HTML tags within the string as well.

Here is my function:

function nl2br(el) {
  var lines = $(el).text().split(/\n/);
  $(el).empty();
  for (var i = 0 ; i < lines.length ; i++) {
    if (i > 0) $(el).append('<br>');
    $(el).append(document.createTextNode(lines[i]));
  }
  return el;
}

Call it by:

someElem = nl2br(someElem);
JochenJung
  • 7,183
  • 12
  • 64
  • 113
  • 1
    NOTE TO THE READER: This answer especially useful if you plan on developing a Firefox add on. innerHTML or (.html() if using jQuery) is frowned on by the W3C and Mozilla, and the code above is very helpful in clearing the review process. For more info see Security considerations @ https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML – Delicia Brummitt Mar 28 '14 at 21:02
0

Using the CSS white-space property is probably the best solution. Use Firebug or Chrome Developer Tools to identify the source of the extra padding you were seeing.

Andrew B.
  • 1,225
  • 1
  • 13
  • 18
-1

For me it works when using jquerys .html() function instead of .text() function. Then you can add <br/> for linebreaks.

var msg = someString + "<br/>" + anotherString;
$(elem).html(msg);
Ruwen
  • 3,008
  • 1
  • 19
  • 16