tailwind-escape-conflict Tailwind Templates

Tailwind Escape Conflict

Tailwind escape character collisions within JavaScript contexts

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.

Plain String, single escaped

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-[&quot;expand\_more&quot;]"></span>

✓ The generated CSS rule is as expected.

.before\:content-\[\"expand\\_more\"\]::before {
  --tw-content: "expand_more";
  content: var(--tw-content);
}

JavaScript String, single escaped

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-[&quot;expand_more&quot;]"></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);
}

JavaScript string, double escaped

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-[&quot;expand\_more&quot;]"></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);
}

Top categories

Loading Svelte Themes