← Back

Dealing with new lines in HTML and CSS

A deep dive into the white-space property

I've got 15 years of experience with CSS, but I've never really completely understood how the CSS property white-space works. This became apparent when working with new line characters that originated from a textarea. In my case it was a string returned from the database that had come from a textarea. The string looked like this: test↵with new line. The arrow represents a new line character. I had to display that string in a simple paragraph tag. But it displayed as a single line where the new line character is treated as a simple (white) space: "test with new line". I tried detecting the new line with JavaScript and replace it with a <br>, but I couldn't detect the new line properly. It took me a little while, but I eventually came across a small comment on StackOverflow that said "Just use white-space: pre-wrap".

Break on new lines

To break on new lines you have several options.

white-space: pre;

It breaks on new lines, but has some other behaviour you need to be aware of. It preserves spaces and tabs. You know how HTML normally collapses two spaces into one? This will preserve those. It also doesn't wrap. Like white-space: no-wrap. So when the line becomes wider than the parent element it is in, it just keeps on going.

See the Pen JjRLEpx by Paul van den Dool (@paulvddool) on CodePen.

white-space: pre-wrap;

This will also break on new lines, but unlike pre it will wrap within the parent element. And like pre, it will also preserve spaces and tabs, but will "hang" any spaces at the end of the line. See break-spaces next for more information.

See the Pen white-space: pre-wrap by Paul van den Dool (@paulvddool) on CodePen.

white-space: break-spaces;

This one is a lot like white-space: pre-wrap. It will break on new lines, it will wrap and it will preserve spaces and tabs. The only difference is with "end-of-line spaces". Spaces at the end of the sentence. With white-space: pre-wrap those spaces will "hang". This means that the space is preserved but if it causes the sentence to be wider than the width of the parent element, it will not wrap to a new line. It will "hang" over the side. With white-space: break-spaces it will wrap to a new line.

See the Pen white-space: break-spaces by Paul van den Dool (@paulvddool) on CodePen.

white-space: pre-line;

This one behaves the most like the default behaviour: white-space: normal. It will collapse spaces and tabs, it will wrap correctly and it removes end-of-line spaces. But unlike white-space: normal it will break on new lines.

See the Pen white-space: pre-line by Paul van den Dool (@paulvddool) on CodePen.

This last option is what I chose because of its default behaviour.

The other values

The white-space property takes five more values. Only two of those are what they call "keyword values" like the ones described above. The other three are "global values".

white-space: normal;

The default behaviour. It collapses new lines, so probably not the value you want if you are reading this. It also collapses any spaces and tabs into just a single space. It wraps so text stays within the parent container and any spaces at the end are removed.

See the Pen white-space: normal by Paul van den Dool (@paulvddool) on CodePen.

white-space: nowrap;

It behaves much the same as white-space: normal but doesn't wrap the text.

See the Pen white-space: nowrap by Paul van den Dool (@paulvddool) on CodePen.

white-space: inherit;

This will go searching up the DOM tree to the first parent element it can find that also has the white-space property declared.

white-space: initial;

This will set the value back to the default value. For the white-space property this is white-space: normal. You can use this in case you don't remember what the default value is.

white-space: unset;

The unset value in CSS resets a property to it's inherited value. If it doesn't have an inherited value, it will reset to it's initial value. For the white-space property this means that when you already have a block of CSS defining the white-space on an element but you don't want it to apply to that specific element while still maintaining any other styling, you can set the white-space to unset. It will then take any white-space styling from a parent element (inherit), or revert to white-space: normal (initial).

Here's a CodePen with all the examples in one place.

See the Pen The white-space property by Paul van den Dool (@paulvddool) on CodePen.

I liked writing this post, and I'm thinking of doing more of this kind of posts. Got a suggestion for a next deep dive? @ me on Twitter or send a pigeon.