@theme, @layer and @utility in the Hyva Theme
Tailwind CSS 4 retires the JavaScript configuration file in favor of a fully CSS-first approach. For Hyva Theme developers on Magento 2 this means design tokens, custom utilities and theme overrides now live directly inside the CSS file, more transparent, easier to maintain and closer to the browser standard.
Table of Contents
- 1. The CSS-first approach in Tailwind CSS 4
- 2. @theme: design tokens as CSS custom properties
- 3. The CSS layer system in Tailwind CSS 4
- 4. @utility: custom utilities without a plugin system
- 5. Hyva Theme structure for Tailwind CSS 4
- 6. Brand tokens for Magento 2 Hyva themes
- 7. @layer components for Hyva component styles
- 8. Migrating from Tailwind v3 to v4 in a Hyva project
- 9. Tailwind CSS 3 vs. 4: configuration compared
- 10. Summary
- 11. FAQ
1. The CSS-first approach in Tailwind CSS 4
With Tailwind CSS 4, the framework has undergone a fundamental paradigm shift: the JavaScript-based tailwind.config.js is no longer a required part of the setup. All theme configuration, color tokens, spacing values and custom utilities can now be defined directly inside the CSS file. This CSS-first approach follows the philosophy that CSS developers think in CSS, not in JavaScript object hierarchies. For Hyva Theme developers on Magento 2 this means a single CSS file (tailwind.css or app.css) now defines the theme's entire design system.
The technical background: Tailwind CSS 4 uses CSS custom properties (CSS variables) internally as its token system. The @theme block defines these variables and simultaneously tells Tailwind to generate utility classes from them. This is not magic, it is a direct mapping from CSS variables to classes. --color-brand: #0369a1; inside the @theme block produces text-brand, bg-brand, border-brand and every other color utility for that color. Anyone who opens the browser DevTools sees the generated CSS custom properties directly on the :root element, full transparency, no build tool black box.
2. @theme: design tokens as CSS custom properties
The @theme block in Tailwind CSS 4 is the centerpiece of the design token system. Every value defined inside it becomes both a CSS custom property on :root and a Tailwind utility class. The naming convention decides which utility family gets generated: --color-* produces color utilities, --spacing-* produces spacing values, --font-size-* produces text sizes. A complete brand color set for a Hyva Theme can be defined in a single @theme block, replacing the whole colors section from the old JavaScript configuration.
The strength of the @theme approach lies in its transparency. In Tailwind CSS 3, brand colors were defined in tailwind.config.js, compiled into CSS classes and then no longer visible as variables in the browser. In Tailwind CSS 4 with @theme, tokens are CSS custom properties that are directly visible, editable and inheritable in the browser DevTools. This also enables genuine dark mode implementations: @theme dark overrides token values for dark mode without duplicating a single utility class, the utilities stay the same, only the token values change.
/* tailwind.css, Hyva Theme main CSS file for Tailwind CSS 4 */
@import "tailwindcss";
/* @theme defines CSS Custom Properties AND generates utility classes */
@theme {
/* Brand color palette, generates text-brand-*, bg-brand-*, border-brand-* */
--color-brand-50: #f0f9ff;
--color-brand-100: #e0f2fe;
--color-brand-200: #bae6fd;
--color-brand-500: #0ea5e9;
--color-brand-600: #0284c7;
--color-brand-700: #0369a1;
--color-brand-900: #0c4a6e;
/* Custom font family, generates font-sans: */
--font-family-sans: 'Inter', system-ui, -apple-system, sans-serif;
/* Custom spacing tokens, generates p-, m-, gap-brand-section etc. */
--spacing-section: 5rem;
--spacing-card-gap: 1.5rem;
/* Custom border radius, generates rounded-card, rounded-badge */
--radius-card: 1rem;
--radius-badge: 0.5rem;
/* Custom shadow tokens */
--shadow-card: 0 1px 3px 0 rgb(0 0 0 / 0.07), 0 1px 2px -1px rgb(0 0 0 / 0.07);
--shadow-card-hover: 0 10px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
}
/* Dark mode, override tokens only, utilities stay the same */
@theme dark {
--color-brand-500: #38bdf8;
--color-brand-600: #0ea5e9;
--color-brand-700: #7dd3fc;
}
3. The CSS layer system in Tailwind CSS 4
The CSS layer system in Tailwind CSS 4 follows the native CSS @layer standard. Tailwind defines three base layers: base for resets and foundational styles, components for component styles and utilities for utility classes. This order determines the CSS specificity cascade: utilities always win over components, components always win over base, regardless of the order in the HTML or in the CSS file. That ends the classic battle with !important that tends to break out in complex Tailwind projects.
The decisive difference compared to Tailwind CSS 3: in v3, @layer was a Tailwind-specific abstraction resolved internally. In Tailwind CSS 4, @layer is the native CSS feature, the browser understands it directly, with no build tool transformation involved. That means custom CSS written outside an @layer block implicitly has higher specificity than every layered style. A plain a { color: red; } outside a layer beats every Tailwind utility class. That is why it matters to always write your own CSS inside the appropriate @layer block rather than defining it outside one.
4. @utility: custom utilities without a plugin system
The @utility directive in Tailwind CSS 4 is the direct replacement for the plugin system from v3, which was used to define custom utilities via addUtilities() in JavaScript. With @utility you define custom utilities directly in CSS: @utility clip-diagonal { clip-path: polygon(0 0, 100% 0, 100% 88%, 0 100%); } produces a class clip-diagonal that is fully integrated into Tailwind's utility layer and compatible with every modifier prefix (hover:, md:, @md:, dark:).
In the Hyva Theme context, custom @utility definitions are especially valuable for project-specific patterns that repeat across many phtml templates but are too specific for Tailwind's standard library. Hero diagonal cuts, standard card hover effects, button shine animations, all of that can be defined as an @utility and then used anywhere in the template with a single class token. Anyone familiar with the Tailwind CSS 4 plugin system from v3 will notice that @utility is simpler, more readable and closer to the CSS standard. The JavaScript knowledge required for plugin development is replaced with CSS knowledge, a clear win for teams with CSS-savvy frontend developers.
/* Custom utilities with @utility, fully integrated into Tailwind's utility layer */
/* All modifiers work: hover:clip-diagonal, md:clip-diagonal, @md:clip-diagonal */
@utility clip-diagonal {
clip-path: polygon(0 0, 100% 0, 100% 88%, 0 100%);
}
@utility clip-diagonal-reverse {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 10%);
}
/* Custom text-balance, browser-native text wrapping */
@utility text-balance {
text-wrap: balance;
}
/* Hyva-specific: visually hidden but accessible to screen readers */
@utility sr-only-focusable {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
&:focus {
position: static;
width: auto;
height: auto;
padding: inherit;
margin: inherit;
overflow: visible;
clip: auto;
white-space: normal;
}
}
/* Custom gradient text, frequently used in Hyva hero sections */
@utility text-gradient-brand {
background-image: linear-gradient(135deg, var(--color-brand-500), var(--color-brand-900));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
5. Hyva Theme structure for Tailwind CSS 4
In a Hyva Theme on Magento 2, the main Tailwind file lives at web/tailwind/tailwind.css. With Tailwind CSS 4, the recommended structure of this file has fundamentally changed: instead of a compact entry file that points to tailwind.config.js, the CSS file itself is now the complete configuration document. A sensible structure for Hyva projects: @import "tailwindcss" at the very top, then @theme with brand tokens, then @import "./tokens/*.css" for modularized token files, then @import "./components/*.css" for component styles, and finally @import "./utilities/*.css" for custom utilities.
Modularization is not mandatory, but it is recommended for Hyva Themes of medium size and up. A single-file approach with everything crammed into tailwind.css becomes hard to navigate as the project grows. The import system in Tailwind CSS 4, which is natively built on CSS @import, allows you to split things up without tooling overhead. Move tokens for colors, spacing and typography into separate files (tokens/colors.css, tokens/typography.css). Move component styles for buttons, cards and navigation into separate components/ files. The build process (bin/npm --prefix app/design/frontend/Mironsoft/default/web/tailwind run build) processes all imports automatically.
6. Brand tokens for Magento 2 Hyva themes
A complete brand token system for Hyva Themes in Tailwind CSS 4 covers at least three categories: colors, typography and spacing. Color tokens define the full color palette across shades from 50 to 950, not just primary and secondary, but also neutral, success, warning and error colors. Typography tokens define font families, the font-size scale and line heights. Spacing tokens define section padding, card gaps and container margins as named values instead of raw pixel numbers.
Especially valuable for Magento 2 e-commerce projects are semantic color tokens that go beyond pure palettes: --color-price: var(--color-brand-700) defines the price color semantically, not just as a hex value. If the brand color changes, the price color changes automatically along with it. --color-badge-sale, --color-badge-new, --color-stock-low are further semantic tokens that are frequently needed in Hyva templates and, without a token system, tend to result in a lot of hardcoded hex values. The Tailwind CSS 4 @theme system makes this semantic token layer practical and maintainable.
/* tokens/colors.css, semantic color tokens for Hyva Magento 2 theme */
@theme {
/* Primary brand colors */
--color-primary: var(--color-brand-600);
--color-primary-hover: var(--color-brand-700);
--color-primary-fg: #ffffff;
/* E-Commerce semantic tokens */
--color-price: var(--color-brand-700);
--color-price-old: var(--color-slate-400);
--color-badge-sale: #dc2626; /* red-600 */
--color-badge-new: #16a34a; /* green-600 */
--color-stock-low: #d97706; /* amber-600 */
--color-stock-out: #9ca3af; /* gray-400 */
/* UI surface tokens */
--color-surface: #ffffff;
--color-surface-alt: var(--color-slate-50);
--color-border: var(--color-slate-200);
--color-text: var(--color-slate-900);
--color-text-muted: var(--color-slate-500);
}
/* tokens/typography.css */
@theme {
/* Font size scale with matching line heights */
--font-size-display: 3.5rem;
--line-height-display: 1.1;
--font-size-heading-lg: 2rem;
--line-height-heading-lg: 1.25;
/* Letter spacing for UI labels */
--tracking-ui-label: 0.05em;
}
7. @layer components for Hyva component styles
The @layer components block in Tailwind CSS 4 is the right place for styles that combine several CSS properties and are used as semantic classes in the template. In Hyva Themes, good candidates for component-layer definitions include button variants (.btn, .btn-primary), card structure (.card, .card-body), form elements (.form-input, .form-label) and project-specific UI patterns such as breadcrumbs, badges and notification bars.
The difference from @utility: components are multi-property blocks with semantics, utilities are single-property blocks without semantics. .btn-primary is a component, it has color, padding, radius, transition and a focus ring. .clip-diagonal is a utility, it has exactly one property. This distinction is not just conceptually important, it also affects CSS specificity. Component styles have lower priority than utility styles in the layer system, which means a bg-red-500 on a .btn-primary element overrides the component's background color without needing !important. That makes the system predictable and friendly to debug.
8. Migrating from Tailwind v3 to v4 in a Hyva project
Migrating an existing Hyva project from Tailwind CSS 3 to Tailwind CSS 4 is structured in three phases. Phase 1: base upgrade. Run bin/npm --prefix app/design/frontend/Mironsoft/default/web/tailwind install tailwindcss@4 @tailwindcss/vite or use the corresponding PostCSS plugin. The tailwind.config.js can initially stay in place, Tailwind CSS 4 can read the v3 configuration through a compatibility layer. Important: the @tailwind base; @tailwind components; @tailwind utilities; directives are replaced with @import "tailwindcss".
Phase 2: token migration. Color and spacing definitions from tailwind.config.js are transferred step by step into @theme blocks in the CSS file. The Tailwind team provides a CLI tool (npx @tailwindcss/upgrade) that automates most of this process. Phase 3: plugin-to-utility migration. Every addUtilities() call in the old configuration becomes an @utility block in the CSS file. Every addComponents() call becomes an @layer components block. After this phase, tailwind.config.js is usually empty except for any safelist entries and can be removed. In the Hyva context, the safelist is especially relevant for dynamically generated classes in PHP templates.
9. Tailwind CSS 3 vs. 4: configuration compared
The structural difference between Tailwind CSS 3 and Tailwind CSS 4 is most visible in how design tokens are configured. What was defined as a JavaScript object in v3 now lives as CSS in v4. This makes the configuration not only more readable for CSS-savvy developers, it also integrates better with existing CSS workflows.
| Feature | Tailwind CSS 3 | Tailwind CSS 4 |
|---|---|---|
| Configuration | tailwind.config.js (JavaScript) | @theme in the CSS file |
| Brand colors | colors: { brand: { 500: '#...' } } | --color-brand-500: #...; |
| Custom utilities | addUtilities() inside a plugin function | @utility in the CSS file |
| CSS layers | Tailwind-internal, non-standard | Native CSS @layer |
| Dark mode tokens | dark: prefix classes, manual definitions | @theme dark, token override |
| Container queries | Separate plugin required | Built in natively, @container class |
The table shows: Tailwind CSS 4 is closer to the browser standard in every dimension. Native @layer, native CSS custom properties via @theme, native @container, everything that used to be a Tailwind-specific abstraction is now built on browser standards. That reduces reliance on the build tool and makes the code understandable even without Tailwind-specific context. For Hyva Theme developers on Magento 2 that means less framework-specific knowledge and more baseline CSS knowledge required, a healthier approach in the long run.
Mironsoft
Tailwind CSS 4 and Hyva Theme development for Magento 2
Need a Tailwind CSS 4 migration for your Hyva project?
We migrate existing Hyva Themes from Tailwind CSS 3 to v4, including a complete design token system, @theme migration, plugin-to-utility conversion and documentation for your team.
v3 to v4 migration
Complete migration from tailwind.config.js to @theme and @utility in CSS, backward compatible and rolled out step by step
Design token system
Semantic color, type and spacing tokens for Hyva Magento 2 with full documentation
Custom utilities
Project-specific @utility definitions for clip-path, animations and Hyva's own UI patterns
10. Summary
Tailwind CSS 4 with its CSS-first approach changes how Hyva Themes on Magento 2 get configured and maintained. The @theme block replaces the JavaScript configuration with CSS custom properties, clearer, closer to the browser and directly visible in the DevTools. The @layer standard (base / components / utilities) delivers predictable specificity without !important hacks. The @utility directive turns custom utilities into first-class citizens of the CSS workflow, with no plugin-system knowledge required.
For Hyva Theme developers already familiar with Tailwind CSS 3, migrating to v4 is worthwhile. Tailwind's upgrade tool automates most of the token migration. The long-term benefits, smaller build outputs thanks to better tree-shaking, direct closeness to the CSS standard, and a more maintainable design token system, justify the migration effort on every production project. The combination of Tailwind CSS 4 @theme, container queries and Alpine.js is the current state of the art for Hyva Theme development on Magento 2.
Tailwind CSS 4 for Hyva, the essentials at a glance
@theme
Defines design tokens as CSS custom properties AND generates utility classes. Fully replaces the colors/spacing section in tailwind.config.js.
@layer
Native CSS layer system. base then components then utilities. Utilities always win, no !important needed anymore for Tailwind overrides.
@utility
Custom utilities directly in CSS, no plugin system required. Compatible with every modifier prefix. Replaces addUtilities() from Tailwind v3 plugins.
Hyva integration
tailwind.css as the complete configuration document. Modularize with @import for token, component and utility files.