Tailwind CSS

Maizzle uses the Tailwind CSS framework, so you can rapidly prototype email templates with utility classes instead of having to write inline styles.

For most of the time, you won't be writing CSS anymore 😎

Structure

CSS files are stored in src/assets/css, and are imported into main.css.

main.css

The src/assets/css/main.css file imports Tailwind's utilities and components, and our custom, email-specific resets, components, and utilities.

This is the file Maizzle looks for when compiling Tailwind CSS, and you can configure where it lives and how it's named:

// config.js
module.exports = {
  build: {
    tailwind: {
      css: 'src/assets/css/main.css',
      // ...
    }
    // ...
  }
  // ...
}

Custom CSS Files

Add custom CSS files anywhere under src/assets/css.

Maizzle adds the following ones in src/assets/css/custom :

  • reset.css

    This contains browser and email client CSS resets.

  • utilities.css

    Add here any custom utility classes that Tailwind CSS doesn't provide.

Plugins

To use a Tailwind CSS plugin, simply npm install it and follow its instructions to add it to your tailwind.config.js. Maizzle currently includes the tailwindcss-gradients plugin, for CSS background-image gradients.

CSS purging

When running maizzle build [env], if [env] is specified and is not set to local, Maizzle will use postcss-purgecss to remove any unused classes from the CSS that is being injected into the template currently being rendered.

This is needed so that the CSS inliner and email-comb (which run after the purging step) receive as little CSS as possible to parse.

It greatly improves build speed.

To make sure the Tailwind CSS classes that you use in your emails are not purged, pass layouts and any partials or components directory paths to the purgeCSS.content config key, as an array of file globs:

// config.js
module.exports = {
  cleanup: {
    purgeCSS: {
      content: [
        'src/layouts/**/*.*',
        'src/partials/**/*.*',
        'src/components/**/*.*',
      ],
      // ...
    },
    // ...
  }
  // ...
}

Shorthand CSS

Maizzle uses postcss-merge-longhand to rewrite your CSS padding, margin, and border properties in shorthand-form, when possible.

Because utility classes map one-to-one with CSS properties, this normally doesn't have any effect with Tailwind CSS. However, it's useful when you extract utilities to components, with Tailwind's @apply.

Consider this template:

---
title: Confirm your email
preheader: Please verify your email address with us
---

<div class="col">test</div>

Let's use @apply to compose a col class by extracting two padding utilities:

/* src/assets/css/custom/components.css */

.col {
  @apply py-8 px-4;
}

When building for production, normally that would yield:

<div style="padding-top: 8px; padding-bottom: 8px; padding-left: 4px; padding-right: 4px;">test</div>

However, Maizzle will merge those with postcss-merge-longhand, so we get this:

<div style="padding: 8px 4px;">test</div>

This results in smaller HTML size, reducing the risk of Gmail clipping your email.

As mentioned, this works for padding, margin, and border. Using shorthand CSS for these is well supported in email clients and will make your HTML lighter, but the shorthand border is particularly useful because it's the only way Outlook will render it properly.

Shorthand borders

To get shorthand-form CSS borders, you need to specify all these:

  • border-width
  • border-style
  • border-color

With Tailwind's @apply, that means you can do something like this:

.my-border {
  @apply border border-solid border-blue-500;
}

... which will turn this:

<div class="my-border">Border example</div>

... into this:

<div style="border: 1px solid #3490dc;">Border example</div>

Use in Template

You can use Tailwind CSS, including directives like @apply, right inside a template.

Use {% block head %} to push a <style tailwind> tag to the template's <head>:

---
title: Using Tailwind CSS directives inside a template
---

{% block head %}
<style tailwind>
  a {
    @apply text-red;
  }
  @screen sm {
    table { 
      @apply w-full;
    }
  }
</style>
{% endblock %}

posthtml-content is used to parse the contents of any <style> tag that has a tailwind attribute - the contents are compiled with Tailwind CSS.

Prevent inlining

Add a data-embed attribute to that <style> tag, to prevent it from being inlined:

---
title: Preventing in-template embedded CSS from being inlined
---

{% block head %}
<style tailwind data-embed>
  /* This CSS will not be inlined */
  img {
    border: 0;
    @apply leading-full align-middle;
  }
</style>
{% endblock %}