Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding Tailwind CSS Classes in a Reusable VueJS Component

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.

like image 935
Moshe Avatar asked Jun 23 '20 07:06

Moshe


People also ask

How do you override a class in Tailwind?

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.

Why you should not use Tailwind CSS?

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.

Can you use Tailwind with Vue?

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!

Can I use tailwind CSS with Vue JS?

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.

Are You violating tailwind CSS’s principle with utility classes?

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.

How to override other color classes when using tailwind directives?

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 }

Why does my tailwind component layout keep breaking?

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.


Video Answer


2 Answers

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 
}
like image 157
Sharkfin Avatar answered Oct 23 '22 18:10

Sharkfin


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.

like image 41
Bhaskar Avatar answered Oct 23 '22 18:10

Bhaskar