Overriding Tailwind CSS Classes in a Reusable VueJS Component

Viewed 9236

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.

3 Answers

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 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 
}

As a workaround, you can use props:

<!-- Button.vue -->
<template>
  <button :class="background + ' text-white py-2 px-4 rounded'">
    Click Me
  </button>
</template>

<script>
export default {
  props: {
    background: {
      type: String,
      default: "bg-green-500",
    },
  },
};
</script>
<!-- index.vue -->
<Button background="bg-red-600"></Button>
<Button background="bg-blue-600"></Button>
Related