blogprojectshajspace
Back to blog

tailwind v4 + chakra ui: five bugs and how to fix them

·3 min read

I just wanted to use bg-blue-500 on one button. Four hours later, I was deep in CSS specificity rabbit holes wondering why my styles kept disappearing.

If you're trying to use Tailwind CSS v4 alongside Chakra UI in a Next.js project, you've probably hit the same problems. Here's what broke and how I fixed it.

why use both

Sounds insane. Two CSS frameworks in one project?

But I had a big Chakra UI app. I wanted Tailwind's utility classes for new pages. A full rewrite wasn't an option.

Real reasons to do this:

  • Slow migration from Chakra to Tailwind
  • Team knows different tools
  • Chakra components + Tailwind quick styling
  • Fast prototyping for new features

bug 1: the config file lie

I had a tailwind.config.js file. Nothing worked.

Spent 30 minutes tweaking the config. Then I checked package.json. The packages weren't installed. The config was completely unused.

bash
npm install -D tailwindcss @tailwindcss/postcss postcss autoprefixer

A config file means nothing without the packages.

bug 2: the postcss plugin switcheroo

Tailwind v4 changed how it integrates with PostCSS. The old way throws this error:

text
It looks like you're trying to use `tailwindcss` directly as a PostCSS plugin

v4 moved its PostCSS plugin to @tailwindcss/postcss:

javascript
// postcss.config.js - v4 way
module.exports = {
  plugins: {
    "@tailwindcss/postcss": {},
    autoprefixer: {},
  },
};

Not this:

javascript
// DON'T DO THIS - v3 way
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
};

bug 3: the invisible padding

Added p-4 to a div. Nothing happened.

DevTools showed the class was there. But a global reset was winning:

css
* {
  padding: 0;
  margin: 0;
}

CSS without a layer beats CSS with a layer. Tailwind uses layers. My reset didn't.

Fix: wrap base CSS in @layer base:

css
@layer base {
  * {
    box-sizing: border-box;
    padding: 0;
    margin: 0;
  }
}

bug 4: the vanishing background

Added bg-primary-500 to a div. Class was there. DevTools showed backgroundColor: transparent.

Chakra UI uses Emotion (CSS-in-JS). Emotion injects styles after page load. Late styles beat early styles.

Fix: add important to your Tailwind import:

css
@import "tailwindcss" important;
@source "../**/*.{js,jsx,ts,tsx}";

That one word adds !important to all Tailwind styles. Now they win against Emotion's late arrivals.

This is the most important fix. Without it, half your Tailwind classes randomly fail near Chakra components.

bug 5: the color palette mystery

Built a color grid to test my theme. Some boxes showed colors. Others were blank.

Pattern: only colors written directly worked. Colors from variables didn't.

Tailwind's JIT compiler scans your code for class names. It can't see names built from variables:

tsx
// BROKEN - JIT can't find this
const bgClass = `bg-${color}-${shade}`;

// WORKS - JIT can find this
const bgClass = "bg-primary-500";

Fix: use a lookup object with all class names spelled out:

tsx
const colorClasses = {
  primary: {
    50: "bg-primary-50",
    100: "bg-primary-100",
    500: "bg-primary-500",
    // ...
  },
} as const;

<div className={colorClasses[color][shade]} />

Verbose, but works every time.

debugging checklist

Problem Check
Nothing works Are packages in package.json?
PostCSS error Using @tailwindcss/postcss for v4?
Styles disappear near Chakra Added important to import?
Resets override Tailwind Base styles in @layer base?
Dynamic classes missing Using lookup object instead of template literals?

Two CSS frameworks can coexist. You just need to know where the conflicts are.

That said, this is probably not a good idea.

Back to blog