Published on

Why Tailwind CSS Doesn't Detect Dynamic Classes & How to Fix It

Authors
  • Name
    Ripal & Zalak
    Twitter

Why Tailwind CSS Doesn't Detect Dynamic Classes & How to Fix It

Tailwind CSS is a utility-first framework that optimizes your styles by generating only the classes that exist in your source files. However, this means dynamically generated class names may not be detected, leading to missing styles in your final build.

The Problem: Tailwind Doesn’t Recognize Dynamic Classes

Consider the following Vue example:

<div v-for="item in items" :key="item.id" :class="'text-' + item.color + '-600'">
  {{ item.name }}
</div>

Even though the class attribute updates dynamically in the browser, Tailwind doesn’t detect text-{color}-600 because it cannot parse dynamically constructed strings.

Solution 1: Use Full Class Names

Instead of dynamically constructing class names, define them explicitly:

<div
  v-for="item in items"
  :key="item.id"
  :class="{
    'text-red-600': item.color === 'red',
    'text-blue-600': item.color === 'blue',
    'text-green-600': item.color === 'green',
  }"
>
  {{ item.name }}
</div>

This ensures Tailwind detects and includes all required styles.

Solution 2: Use the safelist Option in tailwind.config.js

Tailwind provides a safelist option to manually include certain classes:

// tailwind.config.js
module.exports = {
  safelist: ['text-red-600', 'text-blue-600', 'text-green-600'],
}

This forces Tailwind to generate these styles even if they’re not found explicitly in your files.

Solution 3: Use a JavaScript-Based Approach to Generate Class Names

If you have a larger set of dynamic classes, automate the safelist generation:

const colors = ['red', 'blue', 'green', 'yellow', 'purple']

module.exports = {
  safelist: colors.map((color) => `text-${color}-600`),
}

This dynamically adds all necessary color classes to the Tailwind build.

Solution 4: Tailwind Merge for Managing Dynamic Classes in JS Frameworks

For React and Vue projects, you can use libraries like tailwind-merge to manage dynamic class combinations:

import clsx from 'clsx'
import { twMerge } from 'tailwind-merge'

const Button = ({ color }) => {
  return (
    <button className={twMerge(clsx('rounded px-4 py-2', `text-${color}-600`))}>Click Me</button>
  )
}

FAQs

1. Why doesn’t Tailwind detect my dynamically generated class?

Tailwind scans source files for static class names but cannot parse dynamic string concatenation.

2. How can I ensure Tailwind includes my dynamic classes?

Use full class names, add them to safelist, or generate them dynamically in tailwind.config.js.

3. Can I use Tailwind’s @apply with dynamic classes?

No, @apply only works with predefined Tailwind utility classes.

4. What is the best way to manage Tailwind classes in Vue or React?

Use conditional class application (clsx, tailwind-merge, or Vue’s object syntax) instead of dynamic string concatenation.