Theme Configuration in CSS
Loading "Theme Configuration in CSS"
Run locally for transcripts
Our project is already setup with Tailwind CSS v4.
If you're using vscode, you might want to upgrade the Tailwind CSS
Intellisense extension to the "pre-release" version to work with Tailwind v4.
Tailwind CSS v4 upgrade
- We've upgraded our Tailwind version and installed the new Tailwind CSS Vite plugin:
"@tailwindcss/vite": "^4.0.0-alpha.17",
"tailwindcss": "^4.0.0-alpha.17",
- We've registered the Vite plugin in :
import tailwindVite from '@tailwindcss/vite'
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), tailwindVite()],
server: {
port: Number(process.env.PORT) || 3000,
},
})
- We've replaced the three
@tailwinddirectives in with a single@importstatement:
- @tailwind base;
- @tailwind components;
- @tailwind utilities;
+ @import 'tailwindcss';
- We've deleted the
postcss.config.jsfile, which is no longer needed.
We could also delete the
tailwind.config.ts file, but we're keeping it
around for reference of the work we've done.Porting the theme configuration to CSS
Instead of defining the
backgroundColor, borderColor, and textColor objects in the tailwind.config.ts file, you're going to register those in CSS directly.The GREAT news is that Tailwind CSS v4 uses CSS Variables as the primary theme configuration mechanism βΒ so a lot of our gymnastics between CSS and JS configuration is going to be greatly simplified.
The equivalent of Tailwind config's
theme.extend in v4 is an @theme block in CSS.The various theme core plugins can be extended (or overriden) by defining CSS variables with a specific naming convention.
Here is a complete list of the CSS variable
names
for the
@theme definition.The Tailwind Intellisense extension should give you autocomplete suggestions
as you start typing
-- inside the @theme block.1. Move semantic token definition to the @theme block
Keep the raw color tokens in the
@layer base for now (we'll address this later).Take the semantic tokens CSS variables in your CSS file, and move theme outside of the
@layer base, and into a new @theme block:@layer base {
:root {
/* raw color tokens (`--color-grey-0`, etc ) */
}
}
@theme {
--background-color-neutral: var(--color-grey-0);
/* ... */
}
--color-bg-neutral to --background-color-neutral! This is to accomodate for the @theme naming convention.Here's a list of the tokens you need to move:
/* Semantic tokens */
--color-bg-highlight: var(--color-teal);
--color-bg-accent: var(--color-purple);
--color-bg-neutral: var(--color-grey-0);
--color-bg-neutral-inverted: var(--color-grey-100);
--color-bg-subtle: var(--color-grey-5);
--color-bg-bold: var(--color-grey-80);
--color-border-bold: var(--color-grey-60);
--color-border-subtle: var(--color-grey-40);
--color-border-muted: var(--color-grey-20);
--color-text-copy: var(--color-grey-100);
--color-text-subtle: var(--color-grey-60);
--color-text-muted: var(--color-grey-40);
--color-text-inverted: var(--color-grey-5);
Make sure all the semantic color tokens are moved to the
@theme and re-named accordingly.Warning: Doing this will not _replace the default Tailwind colors, but
rather extend them.
Remember: we want to override the default theme
colors. Here's the way to do this in the @theme:@theme {
--color-*: initial;
}
color-*targets allcolorvariables in the theme.initialclears those variables.
Effectively the equivalent of doing
theme.colors = {} in the Tailiwnd config.2. Rename dark and theme CSS variables to mirror the @theme CSS variables
The
@theme variables become the new :root scope CSS variables for our project. Anywhere you redefine those variables (dark, data-theme-"citrus") needs to be updated to reflect the new naming convention.3. Use the full color syntax, not H S L channels
All the complexity of composing a color with Tailwind's internal
<alpha-value> goes away. You can just pass the full color (HSL` in our case) to the CSS variable.Update all CSS variables that use
H S L channels to use the full HSL color syntax:@layer base {
:root {
- --color-teal: 173 100% 50%;
+ --color-teal: hsl(173 100% 50%);
}
}
If you've done everything right βΒ the UI should once again have the correct colors for both themes, in both light and dark modes.