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
Why Doesn't the CSS Calc() Function Work For Me
How to Scale CSS Sprites When Used as Background-Image
Ie7 Z-Index Issue - Context Menu
Fixed Sidebar Navigation in Fluid Twitter Bootstrap 2.0
How to Select All Children of an Element Except the Last Child
Can You Add Noise to a CSS3 Gradient
What Is the Correct "-Moz-Appearance" Value to Hide Dropdown Arrow of a <Select> Element
How Does #Iefix Solve Web Fonts Loading in IE6-IE8
Bootstrap 4 Card-Deck with Number of Columns Based on Viewport
Background Image for Select (Dropdown) Does Not Work in Chrome
How to Include a Font Awesome Icon in My Svg
Height:100% VS Min-Height:100%
Is a Relative Path in a CSS File Relative to the CSS File
Css Best Practice About Id and Class