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
@tailwind
directives in with a single@import
statement:
- @tailwind base;
- @tailwind components;
- @tailwind utilities;
+ @import 'tailwindcss';
- We've deleted the
postcss.config.js
file, 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.@theme
block
1. Move semantic token definition to the 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 allcolor
variables in the theme.initial
clears those variables.
Effectively the equivalent of doing
theme.colors = {}
in the Tailiwnd config.dark
and theme
CSS variables to mirror the @theme
CSS variables
2. Rename 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.H
S
L
channels
3. Use the full color syntax, not 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.