I have created a VueJS button component using TailwindCSS. My goal is to provide that button component with some base styles (using tailwindcss classes), with the option to override them when need be (again, using tailwind css classes).
For example, here is a simplified version of the Button
component:
// Button.vue
<template>
<button class="bg-green-500 text-white py-2 px-4 rounded">
Click Me
</button>
</template>
And here is an example of my using that component in another file:
// index.vue
<Button></Button>
<Button class="bg-red-600"></Button>
<Button class="bg-blue-600"></Button>
The problem is that this only half-works. That is to say, bg-blue-600
does override the bg-green-500
that I set up as a default in Button.vue
. But bg-red-600
does not override the background color (presumbably, because bg-red-600
comes earlier in the css source code.
As such, I am wondering how can I properly set this up? That is to say, how can I give the Button
component some base styles (again, using tailwind css classes) while also providing the option to override those styles using tailwind css classes.
Thanks.
Due to the fact that the order of CSS class names in the class HTML attribute does not matter, the only way to override existing classes in an element is to remove all of the previous classes that clash with the new one.
Tailwind forces an extra HTML-based abstraction layer for a CSS job. This is always going to be an anti-pattern. On balance, I think it's slightly worse than just using inline CSS – either via Styled Components or "vanilla CSS". At least inline CSS doesn't force me to memorize a bunch of new class names.
Installing Tailwind in a Vue CLI app is probably the easiest experience available. There is a CLI plugin that does everything we need, including installing Tailwind, and configuring PostCSS for us. Even better, it works for both Vue 2 and 3!
Today we explore how we can use Tailwind CSS with Vue.js. In this article, we identify potential pitfalls when using utility-first CSS frameworks and how to avoid them. Most importantly, we find out how to use Vue.js functional components to create abstractions for repeating patterns like cards and headlines, for example.
This principle is true, no matter if you use Tailwind CSS or some other methodology. But I think it’s particularly tempting to violate it when working with utility classes. Let’s consider the following example. By default, our AppHero component has the class items-center applied to its root element.
If you create a tailwind class using the @apply directive, you can add in !important to make it override the other color classes when used. You will need to use the lang="postcss" attibute to use tailwind directives in a component. <style lang="postcss"> .my-overriding-class { @apply bg-red-600 !important }
If the order changes in a future release of Tailwind, your layout breaks. The second problem is that items-stretch depends on the xl:flex class being applied onto the root element of the component. If The component itself is refactored to use CSS grid instead of Flexbox, again, your layout breaks.
If you create a tailwind class using the @apply directive, you can add in !important to make it override the other color classes when used.
You will need to use the lang="postcss" attibute to use tailwind directives in a component.
<style lang="postcss">
.my-overriding-class{
@apply bg-red-600 !important
}
This is because your component attributes class
on Button
does not tickle down to the html button
. To do this just bind the attributes to the child like so
<button v-bind="$attrs"...>
This will make all the attributes you specify on the Button (which are not props) bind to the html button.
That being said, I personally prefer making a button class using the @apply
directive and reusing it across my project.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With