388

I have an MVC3 app that has a details page. As part of that I have a description (retrieved from a db) that has spaces and new lines. When it is rendered the new lines and spaces are ignored by the html. I would like to encode those spaces and new lines so that they aren't ignored.

How do you do that?

I tried HTML.Encode but it ended up displaying the encoding (and not even on the spaces and new lines but on some other special characters)

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Dan dot net
  • 6,119
  • 5
  • 28
  • 25

7 Answers7

840

Just style the content with white-space: pre-wrap;.

div {
    white-space: pre-wrap;
}
<div>
This is some text   with some extra spacing    and a
few newlines along with some trailing spaces        
     and five leading spaces thrown in
for                                              good
measure                                              
</div>
pete
  • 24,141
  • 4
  • 37
  • 51
  • 3
    +1 This solution is clean, and I would recommend using [SecurityElement.Escape Method](http://msdn.microsoft.com/en-us/library/system.security.securityelement.escape.aspx) with it. – Ryan Gates Sep 06 '13 at 15:12
  • 84
    `white-space: pre-line;` if you don't want the first line of each paragraph indented. – Will Schoenberger Jun 25 '15 at 20:48
  • and if it still does not look the way you want it check the white space between your html elements ( or the thingy which generates them - for example a vue template ) ... – Yordan Georgiev Jul 10 '18 at 08:54
  • Is there a way to get the white space *after* each line (as opposed to before)? I tried `post-wrap` but no luck. Also checked [here](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) but can't see anything obvious. Any ideas? `pre-wrap` creates unwanted space before the next in my case (the rest of the text is good though) – stevec Aug 26 '19 at 11:11
  • @user5783745 by `after each line`, do you mean `after the newline character` or `any trailing whitespace before the newline character`? – pete Aug 26 '19 at 13:38
  • 2
    The css class you provide completely solves the problem of new lines not rendering. But I seem to get a little white space before the text that has the css class applied to it. For example, suppose the text is just `abcd`. If I do not include the css class, the text "abcd" appears at a certain place on the page. But when I include the css class the text "abcd" appears slightly lower on the page. Is there a way to avoid this? (I'm also not sure if this minor issue is specific to my app, but the app is small so I suspect it may not be) – stevec Aug 26 '19 at 13:47
  • @user5783745 I'd need to see a code example, can you post a new question with a code example or a fiddle? – pete Aug 26 '19 at 13:49
  • 1
    @user5783745 You have a trailing space and a newline immediately following the `
    ` (so it renders as `
    \n
    `. You can see it when you "view source". If this is **only** a problem after the `form`, then you could just drop the [`br` tag on L11](https://github.com/stevecondylios/kaggleraw/blob/master/app/views/kaggles/index.html.erb#L11), otherwise you'll want to change your render method to not emit any whitespace between the two divs (i.e., `
    `)
    – pete Aug 26 '19 at 14:13
  • Thanks so much @pete. After I put the ruby code on the same line, the space goes away. Thanks so much! I would upvote this answer again if I could – stevec Aug 26 '19 at 14:20
71

have you tried using <pre> tag.

 <pre>
    
    Text with
    
    multipel line breaks embeded between pre tag
    
    will work    and 
       also tabs..will work
    
it will preserve the formatting..
    </pre>
Liam
  • 27,717
  • 28
  • 128
  • 190
N30
  • 3,463
  • 4
  • 34
  • 43
51

You can use white-space: pre-line to preserve line breaks in formatting. There is no need to manually insert html elements.

.popover {
    white-space: pre-line;    
}

or add to your html element style="white-space: pre-line;"

rafalkasa
  • 1,743
  • 20
  • 20
7

You would want to replace all spaces with &nbsp; (non-breaking space) and all new lines \n with <br> (line break in html). This should achieve the result you're looking for.

body = body.replace(' ', '&nbsp;').replace('\n', '<br>');

Something of that nature.

Christoph Thiede
  • 707
  • 10
  • 16
Developer
  • 2,021
  • 12
  • 11
  • That would work, I guess I was thinking there would be something built in. Maybe I am over-thinking it. – Dan dot net Feb 29 '12 at 01:25
  • As far as I've seen there is not, it's not much overhead to do a simple replace though. I don't think performance would be a problem. – Developer Feb 29 '12 at 01:56
  • I guess the 'problem' with MVC is that if I change the string as you suggest it will display the ' ' instead of the spaces, unless I use @Html.Raw(). Then I have to be concerned about xss and the user entering bad html. I could however encode the strings on insert so that I could be less concerned about that. – Dan dot net Feb 29 '12 at 02:10
5

I was trying the white-space: pre-wrap; technique stated by pete but if the string was continuous and long it just ran out of the container, and didn't warp for whatever reason, didn't have much time to investigate.. but if you too are having the same problem, I ended up using the <pre> tags and the following css and everything was good to go..

pre {
font-size: inherit;
color: inherit;
border: initial;
padding: initial;
font-family: inherit;
}
Mohd Abdul Mujib
  • 13,071
  • 8
  • 64
  • 88
1

As you mentioned on @Developer 's answer, I would probably HTML-encode on user input. If you are worried about XSS, you probably never need the user's input in it's original form, so you might as well escape it (and replace spaces and newlines while you are at it).

Note that escaping on input means you should either use @Html.Raw or create an MvcHtmlString to render that particular input.

You can also try

System.Security.SecurityElement.Escape(userInput)

but I think it won't escape spaces either. So in that case, I suggest just do a .NET

System.Security.SecurityElement.Escape(userInput).Replace(" ", "&nbsp;").Replace("\n", "<br>")

on user input. And if you want to dig deeper into usability, perhaps you can do an XML parse of the user's input (or play with regular expressions) to only allow a predefined set of tags. For instance, allow

<p>, <span>, <strong>

... but don't allow

<script> or <iframe>
Mauricio Morales
  • 988
  • 1
  • 9
  • 16
0

Instead of using a div tag use a p tag inside a div tag which preserves line breaks.

But in case you have to use , you can inspire from this code:

<script>
  $( document ).ready(function() {
    var str = $("body").html();
    var regex = /[\n]/g;
    $("body").html(str.replace(regex, "<br>"));
  });
</script>
Nima Habibollahi
  • 360
  • 5
  • 16