I am using TailwindCSS in my React + Vite project, and the classes are loaded correctly. The UI looks complete.
The problem is that colors from variables defined in tailwind.config.js are not applied.
I'm using variables like foreground, background, primary, and secondary, but I don't see any colors in the browser.
I verified in DevTools that the classes and variables are loaded.
Why aren't the colors being applied?
Here is my configuration:
tailwind.config.cjs
const plugin = require("tailwindcss/plugin");
module.exports = {
darkMode: ["class"], // use class strategy for dark mode
content: [
"./index.html", // include static HTML
"./pages/**/*.{ts,tsx,js,jsx}",
"./components/**/*.{ts,tsx,js,jsx}",
"./app/**/*.{ts,tsx,js,jsx}",
"./src/**/*.{ts,tsx,js,jsx}",
],
safelist: [
"bg-background",
"text-foreground",
"bg-card",
"text-card-foreground",
"bg-primary",
"text-primary-foreground",
],
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
"icon-bg": "hsl(var(--icon-bg))",
"text-secondary": "hsl(var(--text-secondary))",
"progress-bg": "hsl(var(--progress-bg))",
"progress-active": "hsl(var(--progress-active))",
"chat-bg": "hsl(var(--chat-bg))",
"chat-border": "hsl(var(--chat-border))",
"chat-bot-bubble": "hsl(var(--chat-bot-bubble))",
"chat-user-bubble": "hsl(var(--chat-user-bubble))",
success: "hsl(var(--success))",
"success-bg": "hsl(var(--success-bg))",
sidebar: {
DEFAULT: "hsl(var(--sidebar-background))",
foreground: "hsl(var(--sidebar-foreground))",
primary: "hsl(var(--sidebar-primary))",
"primary-foreground": "hsl(var(--sidebar-primary-foreground))",
accent: "hsl(var(--sidebar-accent))",
"accent-foreground": "hsl(var(--sidebar-accent-foreground))",
border: "hsl(var(--sidebar-border))",
ring: "hsl(var(--sidebar-ring))",
},
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
},
keyframes: {
"accordion-down": {
from: { height: "0" },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: "0" },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
},
},
plugins: [require("tailwindcss-animate")],
};
tailwind.css
@import "./styles/tokens.css";
@import "tailwindcss";
@tailwind base;
@tailwind components;
@tailwind utilities;
tokens.css
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Definition of the design system. All colors, gradients, fonts, etc should be defined here.
All colors MUST be HSL.
*/
@layer base {
:root {
--background: 245 25% 97%;
--foreground: 222 20% 20%;
--card: 210 100% 98%;
--card-foreground: 0 0% 11%;
--popover: 0 0% 100%;
--popover-foreground: 222 20% 20%;
--primary: 249 79% 64%;
--primary-foreground: 0 0% 100%;
--secondary: 220 14% 96%;
--secondary-foreground: 222 20% 20%;
--muted: 220 14% 96%;
--muted-foreground: 215 12% 55%;
--accent: 249 79% 64%;
--accent-foreground: 0 0% 100%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 100%;
--border: 220 13% 91%;
--input: 220 13% 91%;
--ring: 249 79% 64%;
--radius: 0.75rem;
--icon-bg: 249 100% 95%;
--text-secondary: 220 14% 58%;
--progress-bg: 220 14% 96%;
--progress-active: 249 79% 64%;
--chat-bg: 210 100% 98%;
--chat-border: 216 22% 90%;
--chat-bot-bubble: 210 100% 98%;
--chat-user-bubble: 249 100% 95%;
--success: 142 71% 45%;
--success-bg: 142 76% 96%;
--sidebar-background: 0 0% 98%;
--sidebar-foreground: 240 5.3% 26.1%;
--sidebar-primary: 240 5.9% 10%;
--sidebar-primary-foreground: 0 0% 98%;
--sidebar-accent: 240 4.8% 95.9%;
--sidebar-accent-foreground: 240 5.9% 10%;
--sidebar-border: 220 13% 91%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
.dark {
--background: 222 30% 12%;
--foreground: 210 40% 98%;
--card: 222 28% 15%;
--card-foreground: 210 40% 98%;
--popover: 222 28% 15%;
--popover-foreground: 210 40% 98%;
--primary: 249 79% 64%;
--primary-foreground: 0 0% 100%;
--secondary: 217 32% 20%;
--secondary-foreground: 210 40% 98%;
--muted: 217 32% 20%;
--muted-foreground: 215 20% 65%;
--accent: 249 79% 64%;
--accent-foreground: 0 0% 100%;
--destructive: 0 62.8% 50%;
--destructive-foreground: 0 0% 100%;
--border: 217 32% 22%;
--input: 217 32% 22%;
--ring: 249 79% 64%;
--icon-bg: 249 50% 25%;
--text-secondary: 215 20% 65%;
--sidebar-background: 240 5.9% 10%;
--sidebar-foreground: 240 4.8% 95.9%;
--sidebar-primary: 224.3 76.3% 48%;
--sidebar-primary-foreground: 0 0% 100%;
--sidebar-accent: 240 3.7% 15.9%;
--sidebar-accent-foreground: 240 4.8% 95.9%;
--sidebar-border: 240 3.7% 15.9%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
}
vite.config
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [react(),tailwindcss()],
define: {
'global': 'globalThis',
},
css: {
postcss: './postcss.config.js', // optional if you have PostCSS config
},
});
postcss.config.js
export default {
plugins: {
'@tailwindcss/postcss': {},
autoprefixer: {},
},
};
I am using TailwindCSS version 4.1.17.
Example usage in a component:
<div dir="rtl" className="font-sans min-h-screen flex flex-col items-center justify-center p-4 bg-background relative">
