MohamedTammam's avatar

How to generate dynamic classes for all colors in Tailwind CSS?

I want for example to have a base .btn class with all its color variants like .btn-blue-500, .btn-red-600 etc.

Is there a way to achieve that?

0 likes
7 replies
Snapey's avatar

why not pass the color as a prop to the button?

MohamedTammam's avatar

@Snapey Because I want to build it with different class.

<button class="btn btn-full btn-primary"></button>
<button class="btn btn-sm btn-red-500"></button>
<button class="btn btn-outline btn-icon btn-red-500"></button>

So I would write the base classes like btn, btn-outline and btn-icon and then add the dynamic class for the color.

kokoshneta's avatar

@MohamedTammam Again, why not just use the normal colour class? What would be the difference between btn btn-outline btn-icon btn-red-500 and btn btn-outline btn-icon text-red-500? What would your btn-red-500 class do that text-red-500 doesn’t also do?

MohamedTammam's avatar

@kokoshneta I can pass it to the component of course, but I was trying to find a way to make it with just CSS.

Because it will not just be btn-red-500, it will be something like that.

block w-full bg-primary-500 hover:bg-primary-400 py-2 text-sm rounded text-white focus:outline-none focus:ring-2 focus:ring-primary-400 focus:ring-opacity-50 transition-colors

And I was thinking about something like Bootstrap that sets the font color according to the background color.

kokoshneta's avatar

@MohamedTammam You can use @apply in your CSS file to apply existing Tailwind classes; I don’t think there’s an easy way to automatically set text colour according to background colour – you have to specifically tell it which colour goes with which. Otherwise how would it know that, say, red goes with white text while yellow goes with black/dark grey text?

I’m still not clear on what exactly it is you want to accomplish. Which class would all those Tailwind classes be equivalent to in your system? Just .btn? If so, and if you’re using a preprocessor like Sass/SCSS, you might be able to do something like this (if I’m guessing your intent correctly):

.btn {
	@apply block w-full py-2 text-sm rounded text-white focus:outline-none focus:ring-2 focus:ring-opacity-50 transition-colors;
}

$colors:
	red white,
	blue white,
	yellow grey-700,
	[etc.]
}

@each $base, $text in $colors {
	.btn-#{$base} {
		@apply bg-#{$base}-500 hover:bg-#{$base}-400 focus:ring-#{$base}-400 text-#{$text};
	}
}

Then you could style your components like so:

<button class="btn bt-red">[content]</button>

And that should apply the bg-red-500 hover:bg-red-400 focus:ring-red-400 text-white (I think – unless Sass and Mix/Tailwind interfere with each other, which they might do).

[The code styler here is treating all the # character as comment starters; just ignore that. They’re not comments here, but part of the Sass syntax.]

MohamedTammam's avatar

@kokoshneta Thanks, it's what I'm trying to achieve but without using SASS. I will also consider your approach.

BTW, you can add a code block for css by adding css after the triple backticks like ```css

.just-#{css}-example {
	/* Here's a comment */
}
kokoshneta's avatar

@MohamedTammam I don’t think there’s a way to do it without a preprocessor or individually creating the styles for each colour.

(I know how to do comments in CSS. The problem is that the formatter that styles code snippets on this site here thinks that the character # always marks the beginning of a comment, so when you write .btn-#{$base} in a code block, it treats {$base} as a comment and makes it grey, even though it’s obviously not a comment, but part of the CSS code.)

Please or to participate in this conversation.