This project, bootstrapped with Create React App, demonstrates the following issue.
Tailwind's method of escaping underscores within arbitrary values conflicts with JavaScript when Tailwind classes are applied in a JavaScript context. For example, when using Tailwind classes in JSX as part of a ternary expression, or as a function argument for the popular classnames library.
JSX source:
<span className='before:font-symbols before:content-["expand\_more"]' />
✓ The generated HTML class is as expected.
<span class="before:font-symbols before:content-["expand\_more"]"></span>
✓ The generated CSS rule is as expected.
.before\:content-\[\"expand\\_more\"\]::before {
--tw-content: "expand_more";
content: var(--tw-content);
}
JSX source (note that this runs afoul of my ESLint/Prettier config, YMMV):
/* eslint-disable no-useless-escape, prettier/prettier */
<span className={'before:font-symbols before:content-["expand\_more"]'} />
✗ Because of the JS context, the slash has been removed from the HTML class.
<span class="before:font-symbols before:content-["expand_more"]"></span>
✓ The generated CSS rule is as expected, but of course it now doesn't match our slash-less HTML class.
.before\:content-\[\"expand\\_more\"\]::before {
--tw-content: "expand_more";
content: var(--tw-content);
}
JSX source:
<span className={'before:font-symbols before:content-["expand\\_more"]'} />
✓ The generated HTML class is now as expected since we escaped our escape character.
<span class="before:font-symbols before:content-["expand\_more"]"></span>
✗ However, the generated CSS rule now incorporates the extra slashes, so it doesn't match the HTML class.
.before\:content-\[\"expand\\\\_more\"\]::before {
--tw-content: "expand\_more";
content: var(--tw-content);
}