Generating Email Styles with Tailwind CSS
Tailwind 4 and Email styles
There is currently no good solution for generating email-compatible styles with Tailwind 4. The CSS output it produces is too modern for email clients and requires a parser to convert it back to older, widely-supported styles.
For now, the recommended approach is to use Tailwind v3 alongside v4 in your theme for emails, or to add a post-build step that downgrades the CSS to older standards — for example, using a PostCSS plugin.
A community solution exists that resolves most of the CSS compatibility issues in Tailwind 4, though it does not address the CSS variables limitation. You can find it at maizzle/tailwindcss.
We at Hyvä are also exploring options, and will update this page when we find one.
Magento email templates use LESS for styling, but you can use Tailwind CSS utility classes as the source for generating LESS-compatible email stylesheets. This approach lets you write email styles using familiar Tailwind classes and the @apply directive, then compile them to plain CSS that Magento's email system can process.
This technique uses PostCSS to compile Tailwind classes into standard CSS properties, which are then output as a LESS file that Magento's email rendering system can consume.
Community Contribution
This approach was developed and shared by Lucas van Staden from ProxiBlue.
Prerequisites
Before starting, complete the email styling preparation steps in the Styling Emails documentation.
All file paths below are relative to your theme folder (app/design/frontend/Vendor/ThemeName).
Configuration Steps
Tailwind v3
These instructions are for Hyvä 1.3.x using Tailwind v3.
For Hyvä 1.4 and newer builds the PostCSS and tailwind configuration instructions will need to be adjusted.
Step 1: Create the Emails Directory
Create a dedicated directory for email-related Tailwind configuration:
Step 2: Create the PostCSS Configuration
Create web/tailwind/emails/postcss.config.js with the following content. This configuration uses a separate Tailwind config file specifically for email compilation:
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss/nesting'),
require('tailwindcss')({ config: './emails/tailwind.email.config.js' }),
]
}
Step 3: Create the Email-Specific Tailwind Configuration
Create web/tailwind/emails/tailwind.email.config.js to extend your theme's Tailwind configuration while disabling RGBA color functions. Magento's LESS processor cannot parse RGBA syntax, so colors must be output as HEX values:
const defaultConfig = require('../tailwind.config.js');
module.exports = {
...defaultConfig,
corePlugins: {
backdropOpacity: false,
backgroundOpacity: false,
borderOpacity: false,
divideOpacity: false,
ringOpacity: false,
textOpacity: false
}
};
Step 4: Install PostCSS CLI
Install the PostCSS command-line interface as a development dependency:
Step 5: Add the Build Script
Add the email build script to your theme's web/tailwind/package.json:
This script reads source CSS from theme/email.css and outputs compiled LESS to web/css/source/_theme.less, overwriting the base file you copied during email styling preparation.
Exclude Generated File from Version Control
Add web/css/source/_theme.less to your .gitignore since this file is regenerated each time npm run build-email executes.
Usage Example
Create the source file web/tailwind/theme/email.css with Tailwind utility classes using @apply:
Run the build command to generate the LESS output:
The generated web/css/source/_theme.less file contains compiled CSS with HEX color values:
.footer {
border-top-width: 2px;
border-color: #DEDEDE;
}
.footer .span {
background-color: #001F43;
}
To verify email styling, use the Yireo Email Tester 2 extension to preview transactional emails.
Known Limitations and Workarounds
Custom Background Images with LESS Variables
When using LESS variables in background image URLs, wrap the URL path in single quotes to ensure proper LESS processing:
Border Utility Classes
Some Tailwind border utilities like border-b and border-t may not compile correctly for email use. As a workaround, combine Tailwind utilities with explicit border declarations: