Why Is CSS "content" Property Not Adding Space?

If you're trying to add space (U+0020) using the content property with CSS ::before and/or ::after pseudo-elements, it won't work in some cases depending on whether the spaces are collapsible in the content box or not. This depends on the value of the CSS white-space property:

white-space: Spaces & Tabs
normal Collapsible
nowrap Collapsible
pre Preserved
pre-wrap Preserved
pre-line Collapsible
break-spaces Preserved

When the CSS white-space property is set to normal, nowrap, or pre-line, the white-space characters are treated as collapsible. This means that sequences of white-space are collapsed into a single character, unless the collapsible spaces are at the beginning or end of a line (in which case they are removed).

In such case, if you wish to preserve spaces, then you can either specify a CSS white-space property value that preserves space, or you can use one of several unicode space characters to add spacing.

Consider for example the following, where collapsible spaces at beginning and end of line (added via ::before and/or ::after) are removed:

<span>foo</span>
span { border: 1px solid orange; }
span::before { content: ' '; }
span::after { content: ' '; }
white-space: Description Result
normal Collapsed spaces are removed from start and end of line. foo
pre Spaces at start and end of line are preserved. foo

In the following example, you can see that sequences of collapsible spaces (added via ::before and/or ::after) are collapsed into a single space:

<span>foo</span> bar
span { border: 1px solid orange; }
span::after { content: ' '; }
white-space: Description Result
normal Instead of having two spaces, there is only one space after "foo". foo bar
pre Spaces are preserved, so you see two spaces after "foo". foo bar

Similarly, spaces are collapsed into a single space even across multiple strings specified in the content property:

<span>foo</span>
span { border: 1px solid orange; }
span::after { content: 'bar ' ' baz'; }
white-space: Description Result
normal Instead of having two spaces, there is only one space after "foobar". foo
pre Spaces are preserved, so you see two spaces after "foobar". foo

To experiment around and learn more, you can use the following JavaScript snippet to find out what the computed value of the white-space property is on a given element:

const elem = document.getElementById('...');
const style = window.getComputedStyle(elem);
console.log(style.getPropertyValue('white-space')); // e.g. 'normal'

This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.