blog

Whitespace and line wrapping in JSX

Say you have a line like this in your JSX project:

<p>Contact us at <a href="mailto:[email protected]">[email protected]</a></p>

That line would render and wrap as you expect – taking as much space as parent container allows and wrapping words in second line if not enough space. In fact, here’s a demo:

See the Pen by Teo Dragovic (@teodragovic) on CodePen.

Problem when formatting code

But see what happens if you format code like so:

<p>
Contact us at
<a href="mailto:[email protected]">[email protected]</a>
</p>

See the Pen by Teo Dragovic (@teodragovic) on CodePen.

All newlines are removed. This includes the ones added after opening and before closing p tag and the one between the first part of the string and the link. This is per specs:

JSX removes whitespace at the beginning and ending of a line. It also removes blank lines. New lines adjacent to tags are removed; new lines that occur in the middle of string literals are condensed into a single space.

What might cause confusion is the fact that if this string didn’t include an anchor inside a paragraph, inserting one or more newlines in the middle of the sentence would get transformed into a single space (this differs from HTML).

These two examples would output the same thing:

<p>
Contact us at
[email protected]
</p>

<p>Contact us at [email protected]</p>

But every HTML element inside JSX represents new node. So space between the text node (Contact us at) and the link is thus omitted. This behavior is purposely added in React 0.9.

Check transpiled code to see distinction more clearly.

How to add whitespace in JSX?

There are several options to add whitespace in this case.

Using padding or margin

<p>
Contact us at
<a className="pl-1" href="mailto:[email protected]">[email protected]</a>
</p>

Here I’m using Tailwind class to apply left padding to the anchor element. There are two problems with this approach:

  1. Padding or margin value might not match the size of a single space character making text either too close or too far away.

  2. We applied spacing visually but not in markup. This means when we resize the screen to smaller viewport word at and mail address would try to stay together in a single line and it would by default overflow before breaking into a new line.

  3. Words that render together in markup will be read together by assistive technologies.

Using non-breaking space

<p>
Contact us at&nbsp;
<a href="mailto:[email protected]">[email protected]</a>
</p>

Adding non-breaking space character (&nbsp;) immediately after at would produce space and it would be of exact size. But, as the name suggests, non-breaking space would also avoid breaking into a new line and would keep at and the link on the same line.

Using extra tags

<p>
<span>Contact us at </span>
<a href="mailto:[email protected]">[email protected]</a>
</p>

Wrapping the first part in span would make sure that space is preserved. But adding markup for the sake of preserving code formatting is Not Very Nice. Maintenence could also prove difficult and error-prone when dealing with long paragraphs broken over multiple lines and other inline elements.

Explicitly adding space

<p>
Contact us at
{ ' ' }
<a href="mailto:[email protected]">[email protected]</a>
</p>

Adding space using { ' ' } would both produce space (no extra tags) and break on smaller screens. This is desired behavior and my recommended method to add whitespace in JSX.

Finally, here’s a pen with all examples collected:

See the Pen by Teo Dragovic (@teodragovic) on CodePen.