How to Use Template Literals in Tailwindcss to Change Classes Dynamically

How to use template literals in tailwindcss to change classes dynamically?

Do it like this:

<div className={`absolute inset-0 ${click ? 'translate-x-0' : '-translate-x-full'} transform z-400 h-screen w-1/4 bg-blue-300`}></div>

// Alternatively (without template literals):
<div className={'absolute inset-0 ' + (click ? 'translate-x-0' : '-translate-x-full') + ' transform z-400 h-screen w-1/4 bg-blue-300'}></div>

Just keep in mind not to use string concatenation to create class names, like this:

<div className={`text-${error ? 'red' : 'green'}-600`}></div>

Instead you can select complete class name:

<div className={`${error ? 'text-red-600' : 'text-green-600'}`}></div>

// following is also valid if you don't need to concat the classnames
<div className={error ? 'text-red-600' : 'text-green-600'}></div>

As long as a class name appears in your template in its entirety, Tailwind will not remove it from production build.


There are some more options available for you like using a library like classnames or clsx, or maybe Tailwind specific solutions like twin.macro, twind, xwind.

Further Reading:

  • React.js conditionally applying class names
  • How to dynamically add a class to manual class names?
  • Correct way to handle conditional styling in React
  • Embedding Expressions in JSX
  • Template literals - MDN
  • Optimizing for Production - Writing purgeable HTML - Tailwind CSS

BackgroundImage is not changing dynamically using tailwind & nextjs

TailwindCSS doesn't allow you to generate classes dynamically. So when you use the following to generate the class…

`lg:bg-${changebackground("snow")}`

…TailwindCSS will not pick that up as a valid TailwindCSS class and therefore will not produce the necessary CSS.

Instead, you must include the full name of the class in your source code. I'd recommend using an object to quickly get the correct class:

const backgroundClasses = {
day_snow: 'lg:bg-day_snow',
day_sun: 'lg:bg-day_sun',
// ...
}

Then use your function to lookup the correct class from that object.

By doing it this way, the entire string for every class is in your source code, so TailwindCSS will know to generate the applicable CSS.

Read more: https://tailwindcss.com/docs/content-configuration#class-detection-in-depth

Dynamically build classnames in TailwindCss

So after finding out that this way of working is not recommended and that JIT doesn't support it (Thanks to the generous commenters). I have changed the approach to a more 'config' based approach.

Basically I define a const with the basic configuration for the different props and apply those to the component. It's a bit more maintenance work but it does the job.

Here is the example of a config. (Currently without typing) and up for some better refactoring but you'll get the idea.

const buttonConfig = {
// Colors
primary: {
bgColor: 'bg-primary-500',
color: 'text-white',
outline:
'border-primary-500 text-primary-500 bg-opacity-0 hover:bg-opacity-10',
},
secondary: {
bgColor: 'bg-secondary-500',
color: 'text-white',
outline:
'border-secondary-500 text-secondary-500 bg-opacity-0 hover:bg-opacity-10',
},

// Sizes
small: 'px-3 py-2',
medium: 'px-4 py-2',
large: 'px-5 py-2',
};

Then I just apply the styling like so:

  <motion.button
whileTap={{ scale: 0.98 }}
className={`
rounded-lg font-bold transition-all duration-100 border-2 focus:outline-none
${buttonConfig[size]}
${outlined && buttonConfig[color].outline}
${buttonConfig[color].bgColor} ${buttonConfig[color].color}`}
onClick={onClick}
type="button"
tabIndex={0}
>
{children}
</motion.button>

How to dynamically append tailwindcss classes to each list item in JavaScript

If you want to append to a node as child, i think use appendChild() like this:

const array1 = ['one', 'two', 'three', 'four', 'five']

for (let i = 0; i < array1.length; i++) {
let li = document.createElement('li')
li.innerHTML = array1[i]
li.classList.add('block', 'p-6', 'max-w-sm', 'bg-white', 'rounded-lg', 'border', 'border-gray-200', 'shadow-md', 'hover:bg-gray-100', 'dark:bg-gray-800', 'dark:border-gray-700', 'dark:hover:bg-gray-700')
document.querySelector('#newList').appendChild(li)
}

Dynamic class + variables in VueJS / Tailwind

Because you use template literals which returns the string. So show is boolean true and it returns "true" as a string.

If you want to toggle class according to show variable, you must use object way.

<div
class="w-0 h-2 transition-all duration-1000 ease-out bg-indigo-600 rounded-lg"
:class="{ [`w-${percent}/12`]: show }"
>
YOUR CONTENT
</div>

How to dynamically populate tailwindcss grid-cols-x property?

So I finally found the source to the issue. It seems that tailwindcss performs an optimization on classes brought in and if you are not using the class anywhere in your html, it doesn't include those classes. So I not only needed to return my dynamic string with the expected class, but I also needed to add all the classes I would possibly be using into my tailwind.config.js file under the safelist key.

So my config now looks like this and it is working as expected:

module.exports = {
content: [
'./pages/**/*.{js,ts,jsx,tsx}',
],
safelist: [
{
pattern: /grid-cols-./,
}
],
theme: {
extend: {},
},
plugins: [],
}

More information can be found here:
https://tailwindcss.com/docs/content-configuration#using-regular-expressions

Thanks again Mohit for your assistance.



Related Topics



Leave a reply



Submit