Tailwind CSS 4 Theme Layer and Utility Layer for Hyva Theme
AI generated
</>
tw
Tailwind CSS 4 · @theme · @layer · @utility · Hyva Magento 2
Tailwind CSS 4 Theme Layer:
@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.

16 min read @theme · @layer · @utility · CSS custom properties · Migration Tailwind CSS 4 · Hyva 1.x · Magento 2.4.8

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.

11. FAQ: Tailwind CSS 4 Theme Layer and Utility in the Hyva Theme

1Delete tailwind.config.js in Tailwind CSS 4?
Not right away, the compatibility layer allows a step by step migration. Move tokens into @theme gradually, then remove config.js.
2Safelist in Tailwind CSS 4?
@source for template paths, @source inline for explicit classes. A tailwind.config.js safelist remains usable for complex dynamic classes.
3@theme tokens available as CSS custom properties?
Yes. @theme generates :root { --color-brand-500: #...; }, usable directly in Alpine.js, JavaScript and CSS calc expressions.
4@layer components vs. @utility?
components: multi-property with semantics (.btn, .card). utility: single-property without context (clip-diagonal). Utilities have higher priority in the layer system.
5calc() and var() inside @theme?
Yes. --color-primary: var(--color-brand-600); and calc(var(--spacing-section) * 1.5); both work. Derived token hierarchies are possible without duplicating values.
6Dark mode with @theme dark in Hyva?
@theme dark overrides token values, the utility classes stay identical. Configure @variant dark for class-based dark mode: &:where(.dark, .dark *).
7Parent and child theme with Tailwind v4?
Child imports @import '../parent/tailwind.css', then adds its own @theme overrides. Only changed tokens need to be defined, token inheritance flows through the CSS cascade.
8Build process in Hyva with Tailwind CSS 4?
The bin/npm command stays the same. Internally: the Oxide engine instead of PostCSS, 5 to 10x faster build times. Adjust package.json scripts for @tailwindcss/cli.
9Migrating addBase() to Tailwind CSS 4?
@layer base { ... } in the CSS file. addBase({ 'h1': { fontSize: '2rem' } }) becomes @layer base { h1 { font-size: 2rem; } }, direct, readable CSS.
10Using @theme values in Alpine.js?
getComputedStyle(document.documentElement).getPropertyValue('--color-brand-600'), token values can be read directly in Alpine.js expressions, always in sync with the design system.