Reputation: 3037
In my Vue 3 app, I want to highlight words in a text, such as in the following HTML:
span {
background-color: yellow;
}
<span>foo</span>
<span>bar</span>
baz
qux
However, Vue removes the whitespace between tags, so the gaps between the <span>
s disappear:
span {
background-color: yellow;
}
<span>foo</span><span>bar</span> baz qux
How can I preserve the whitespace between the <span>
s? I cannot use
as the spaces should break and none of the other white space entities has the same size as a usual space.
Upvotes: 12
Views: 7213
Reputation: 4737
IMO this is totally a bug, because:
There is a vue compilerOptions
option called whitespace
that according to the documentation should default to 'preserve'
, but it does not.
To set it to 'preserve'
in webpack use this config:
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
compilerOptions: {
// preserve is supposed to be the default
// see: https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler#options
// but as of 2022-01-13 (vue 3.2.26)
whitespace: 'preserve',
},
},
},
Or if you are rendering your components on the fly (with dom templates) use this:
const app = Vue.createApp({...});
app.config.compilerOptions.whitespace = 'preserve';
app.mount('#app');
The documentation (at the time of writting):
whitespace
- Type: string
- Valid values: 'preserve' | 'condense'
- Default: 'preserve'
The default value
'preserve'
handles whitespaces as follows:
- A whitespace-only text node between element tags is condensed into a single space.
- All other whitespaces are preserved as-is.
If set to
'condense'
:
- A whitespace-only text node between element tags is removed if it contains new lines. Otherwise, it is condensed into a single space.
- Consecutive whitespaces inside a non-whitespace-only text node are condensed into a single space.
Using condense mode will result in smaller compiled code size and slightly improved performance. However, it will produce minor visual layout differences compared to plain HTML in certain cases.
Upvotes: 18
Reputation: 3037
Okay, so apparently, I'm not the first one to stumble across that behavior, which I would name a bug:
https://github.com/vuejs/vue-next/pull/1600
By default, Vue removes whitespace between elements for compression purposes - other than browsers, which reduce such whitespace to a single space. In Vue 2 it was possible to change the config to preserve whitespace. In Vue 3 this is not possible (yet).
However, there are some workarounds and as mentioned in a comment [1], whitespace is only removed if it contains linebreaks. Therefore, by removing the linebreaks in the above example's source code, the snippet behaves as expected:
<span>foo</span> <span>bar</span>
baz
qux
[1] https://github.com/vuejs/vue-next/pull/1600#issuecomment-747162894
Upvotes: 10