Programming

Programming

Programming

MJML examples to get you started

Kristina Lauren

September 14, 2023

If you’ve ever coded an HTML email, you know how painful it can be. Unlike building for the web, email requires outdated table-based layouts, endless inline styles, and constant hacks just to make a design render consistently across Gmail, Outlook, and Apple Mail. That’s exactly why MJML (Mailjet Markup Language) was created: to make responsive email coding faster, cleaner, and far less frustrating.

In this post, we’ll give you a straightforward cheat sheet with examples of the most common MJML components you’ll actually use day to day. Whether you’re brand new to coding or already comfortable with HTML, you’ll see how MJML can simplify your workflow and save you hours of troubleshooting.

👉 If you’d like a deeper primer before diving into examples, check out our guide to starting with MJML emails.

What is MJML (and why it exists)

If you’ve ever tried coding an HTML email, you know it’s not like building a web page. Email clients don’t play by modern web standards: most still rely on 1990s-era table layouts, inline styles, and endless hacks to make designs look consistent across Gmail, Outlook, Apple Mail, and others. Even a “simple” button can turn into 20+ lines of clunky HTML.

That’s why MJML (Mailjet Markup Language) was created in 2015 by the team at Mailjet. It’s an open-source framework designed to take the pain out of email coding. Instead of hand-writing all that messy table-based HTML, you write clean, readable tags like <mj-section>, <mj-column>, and <mj-button>. Then MJML compiles it into responsive HTML that just works across email clients.

Why MJML is valuable

  • Saves time: You write a fraction of the code, MJML handles the ugly parts.

  • Responsive by default: Your emails adapt beautifully to mobile and desktop without extra effort.

  • Cross-client consistency: MJML generates bulletproof HTML that plays nicely with even the most stubborn email clients.

  • Component-based: Need a button, image, or social share block? Drop in the MJML tag, not much extra coding required from there.

How to use MJML

One important thing to know: you don’t actually send MJML code to your ESP. ESPs (Customer.io, Iterable, Klaviyo, etc.) only accept HTML. MJML is a source language. You write in MJML, and then a compiler converts it into the responsive HTML that your ESP can send.

The good news: you’ve got plenty of options for doing that conversion, from quick browser tools to more advanced local setups.

Tools for compiling MJML

  • MJML Live Editor – The simplest way to try MJML. Just open your browser, type MJML, and see the compiled HTML instantly.

  • MJML App – A desktop app with live preview that works even offline.

  • Code Editor Plugins

    • Atom – Includes error-spotting and live preview.

    • Visual Studio Code – Full-featured plugin with preview and extras like sending emails via Nodemailer or Mailjet.

    • Sublime Text – Adds MJML syntax highlighting.

  • Node.js / npm – For developers who want MJML available from the command line.

  • Scalero – We have two platforms that supports MJML directly, so you can build, edit, and send without worrying about separate compilers:

How to Start Coding MJML

Below is the foundational layout for your MJML code. As you build out your email, you’ll slowly nest more and more components within these starter tags.

<mjml>
  <mj-head>
      <!-- Just like HTML, css etc go here -->
  </mj-head>
  <mj-body>
    <!-- Just like HTML, body components go here -->
  </mj-body>
</mjml>

Standard MJML head components

MJML components in the head tag may not all be visible within your email, but they’re just as crucial as your body elements. Let’s go over a few of the most important ones.

MJML attributes and all

In MJML, <mj-attributes> enables you to assign default values for all the listed components under the tag. For example, in the code, you can see that we've made all the padding for our text “0”.

You can use <mj-all> to apply an attribute to all components. Notice in the code below that because we assigned “Arial” as the font-family, all text in the email will automatically be Arial font. However, you can later override <mj-all> by adding a different font-family attribute to <mj-text>, such as font-family=“Times”.

<mjml>
  <mj-head>
    <mj-attributes>
      <mj-text padding="0" />
      <mj-class name="blue" color="#2a72d5 !important;" />
      <mj-class name="big" font-size="20px" />
      <mj-all font-family="Arial" />
    </mj-attributes>
  </mj-head>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-text mj-class="blue big">
          This text is in Arial font.
        </mj-text>
        <mj-text mj-class="blue big" font-family="Times">
          This text is in Times font.
        </mj-text>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

You may be wondering what the main difference between <mj-attributes> and <mj-all> is. They’re pretty much the same, except that <mj-all> affects all MJML components using just the one tag instead of a list of tags nested within it.

Styling in MJML

MJML gives you two different ways to handle styling:

  1. Using mj-style (traditional CSS)

    • Lets you write raw CSS inside <mj-head>, just like you would in a <style> tag on a webpage.

    • Great for developers who are already comfortable with CSS or want precise control.

      <mj-head>
        <mj-style>
          a { color: red; text-decoration: none; }
        </mj-style>
      </mj-head>


  2. Using mj-class (MJML shorthand)

    • Lets you define a reusable set of MJML attributes and apply them to multiple components.

    • Instead of writing full CSS selectors, you assign an mj-class name and reuse it across components.

      <mjml>
        <mj-head>
          <mj-attributes>
            <mj-text mj-class="blue-text" color="blue" font-size="18px" />
          </mj-attributes>
        </mj-head>
        <mj-body>
          <mj-section>
            <mj-column>
              <mj-text mj-class="blue-text">I'm blue and 18px</mj-text>
            </mj-column>
          </mj-section>
        </mj-body>
      </mjml>


👉 Think of it this way:

  • mj-style = pure CSS, traditional and flexible.

  • mj-class = MJML’s own shortcut for grouping attributes so you don’t repeat yourself.

Breakpoints

Use <mj-breakpoint> to control when your email switches from desktop to mobile layout. By default, MJML uses 480px, but you can customize it:

<mjml>
  <mj-head>
    <mj-breakpoint width="320px" />
  </mj-head>
</mjml>

Preview (Preheader) text

The <mj-preview> tag sets the preview text (the snippet shown under the subject line in most inboxes). Place it in the <mj-head>:

<mjml>
  <mj-head>
    <mj-preview>Hello, Friend</mj-preview>
  </mj-head>
</mjml>

Fonts

<mj-font> allows you to import fonts in MJML, which is helpful if you want to use a custom font in your emails. You can use a source like https://fonts.google.com/ to access hundreds of fonts and just include the URL in the code. The only caveat is that custom fonts don’t always work with major email clients, including Gmail, surprisingly. Check out one of our previous blog posts to learn more about how to pick the best email-safe fonts.

<mjml>
  <mj-head>
    <mj-font name="Montserrat" href="https://fonts.googleapis.com/css2?family=Montserrat" />
  </mj-head>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-text font-family="Montserrat, sans-serif">
          Welcome to Scalero!
        </mj-text>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Standard MJML body components

Now we move into MJML body components, which will be responsible for creating the visible content in your emails. Let’s start by understanding how to give your design some basic organization.

Sections and columns

MJML sections behave like rows in an email and are used to give structure to your layout. Columns, on the other hand, allow you to organize your layout horizontally. It’s important to nest the <mj-column> tag within the <mj-section> tag in order for it to work, but columns can’t be nested within columns and neither can sections.

<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-text>1st column</mj-text>
      </mj-column>
      <mj-column>
        <mj-text>2nd column</mj-text>
      </mj-column>
      <mj-column>
        <mj-text>3rd column</mj-text>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Groups

<mj-group> comes in handy when you want to keep MJML columns from stacking in mobile. When you use this component, your columns will stay side-by-side on both desktop and mobile. Also be aware that if you need to set a width for your columns on desktop, you should use percentages instead of pixels so that the columns adapt to the viewport of the browser in use.

<mjml>
  <mj-body>
    <mj-section>
      <mj-group>
        <mj-column>
          <mj-image width="137px" height="185px" padding="0" src="https://framerusercontent.com/images/yp3dx8JLyUw1l2OQWlNK8F5u6HY.png?scale-down-to=1024" />
          <mj-text align="center">
            <h2>Email Marketing</h2>
            <p>At Scalero, you get email strategists, designers, and developers all in one place.</p>
          </mj-text>
        </mj-column>
        <mj-column>
          <mj-image width="166px" height="185px" padding="0" src="https://framerusercontent.com/images/yp3dx8JLyUw1l2OQWlNK8F5u6HY.png?scale-down-to=1024" />
          <mj-text align="center">
            <h2>Email Design</h2>
            <p>Email design isn’t easy, especially with so many code limitations from mail clients--so let us do the heavy-lifting.</p>
          </mj-text>
        </mj-column>
      </mj-group>
    </mj-section>
  </mj-body>
</mjml>

Dividers

<mj-divider> allows you to create a horizontal line as a divider. It can also be customized, similarly to a divider in HTML. For example, you can control the thickness of the border using the attribute “border-width”; you can control whether the divider is solid, dotted, or dashed with “border-style”; and you can change the color using “border-color”.

<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-divider border-width="5px" border-style="dotted" border-color="green" />
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Text

Much like with HTML, inserting text in MJML is simple. Just use <mj-text>. If you want to control the size, use the attribute font-size; to change the color, use the color attribute; to capitalize, uppercase, or lowercase the text, use text-transform.

<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-text font-size="20px" text-transform="uppercase" text-decoration="underline">
          <h1>
            Hey, friend!
          </h1>
        </mj-text>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Buttons

<mj-button> lets you create and customize buttons in MJML, with the aid of style attributes. For example, you can control the font of your button text, the color of the text, and the color of the button itself.

<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-button font-family="Arial" background-color="#f48847" color="white">
          Call Now!
        </mj-button>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Images

Display images in MJML and control their size by using the <mj-image> tag.

<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-image width="300px" src="https://framerusercontent.com/images/yp3dx8JLyUw1l2OQWlNK8F5u6HY.png?scale-down-to=1024" />
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Spacers

<mj-spacer> lets you control the amount of space between two components, such as text. However, if you want to start another line of text (a line break), you can just use the <br> tag as you would in HTML.

<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-text>Hello</mj-text>
        <mj-spacer height="100px" />
        <mj-text>Goodbye</mj-text>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Tables

Creating tables in MJML works much like in HTML. Start with the <mj-table> tag and use <tr>, <th>, and <td> to build your rows and columns. You can also add inline styles or attributes to customize the table’s appearance.

<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-table>
          <tr style="border-bottom:2px solid green;text-align:center;padding:15px">
            <th style="padding: 0 15px 0 0;">First Name</th>
            <th style="padding: 0 15px;">Last Name</th>
            <th style="padding: 0 0 0 15px;">Email</th>
          </tr>
          <tr style="text-align:center">
            <td style="padding: 0 15px 0 0;">John</td>
            <td style="padding: 0 15px;">Smith</td>
            <td style="padding: 0 0 0 15px;">jsmith@scalero.io</td>
          </tr>
          <tr style="text-align:center">
            <td style="padding: 0 15px 0 0;">Mary</td>
            <td style="padding: 0 15px;">Parker</td>
            <td style="padding: 0 0 0 15px;">mparker@scalero.io</td>
          </tr>
        </mj-table>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Navigation bar

Use the <mj-navbar> tag to add a navigation bar to your emails. If your links share the same domain, you can set a base-url attribute on <mj-navbar> (for example, scalero.io). Then, when adding links with <mj-navbar-link>, you only need to include the URL slugs (the part that comes after the domain).

<mjml>
  <mj-body>
    <mj-section background-color="#172725">
      <mj-column>
        <mj-navbar base-url="https://scalero.io" hamburger="hamburger" ico-color="#ffffff">
          <mj-navbar-link href="/company/contact-us" color="#ffffff">Contact Us</mj-navbar-link>
          <mj-navbar-link href="/services" color="#ffffff">Our Services</mj-navbar-link>
          <mj-navbar-link href="/blog" color="#ffffff">Our Blog</mj-navbar-link>
          <mj-navbar-link href="/company/about-us" color="#ffffff">About Us</mj-navbar-link>
        </mj-navbar>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Social media icons

Adding social media icons is simple with the <mj-social> tag. You don’t need to source or host the icons yourself—MJML provides them. Just use <mj-social-element> (e.g., "linkedin") and include the link to your profile.

<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-social font-size="15px" icon-size="30px" mode="horizontal">
          <mj-social-element name="linkedin" href="https://www.linkedin.com/company/scalero">
          </mj-social-element>
          <mj-social-element name="facebook" href="https://www.facebook.com/scalero.io/">
          </mj-social-element>
          <mj-social-element name="twitter" href="https://twitter.com/scalero_io?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor">
          </mj-social-element>
        </mj-social>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Wrappers

The <mj-wrapper> tag lets you group multiple sections together. It’s especially useful for creating nested layouts that share the same background color, background image, or borders across several sections.

<mjml>
  <mj-body>
    <mj-wrapper border="1px solid #aaaaaa" padding="50px 30px">
      <mj-section border-top="1px solid #aaaaaa" border-left="1px solid #aaaaaa" border-right="1px solid #aaaaaa" padding="20px">
        <mj-column>
          <mj-image padding="0" src="https://framerusercontent.com/images/yp3dx8JLyUw1l2OQWlNK8F5u6HY.png?scale-down-to=1024" />
        </mj-column>
      </mj-section>
      <mj-section border-left="1px solid #aaaaaa" border-right="1px solid #aaaaaa" padding="20px" border-bottom="1px solid #aaaaaa">
        <mj-column border="1px solid #dddddd">
          <mj-text padding="20px" font-size="30px"> 5 Tips to grow your business </mj-text>
          <mj-divider border-width="1px" border-color="lightgrey" padding="0 20px" />
          <mj-text padding="20px"> It all starts with an idea...</mj-text>
        </mj-column>
      </mj-section>
    </mj-wrapper>
  </mj-body>
</mjml>

Putting together some of these components

To wrap things up, here’s a full MJML example that combines many of the concepts from this post, like breakpoints, preview text, reusable classes, a navbar, wrappers, tables, and social icons, all into one working template. You can use it as a reference or a starting point for building your own production-ready emails.

<mjml>
  <mj-head>
    <mj-title>Scalero Newsletter</mj-title>
    <mj-preview>New features, tips, and a quick how-to</mj-preview>
    <mj-breakpoint width="380px" />
    <mj-font name="Inter" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700" />
    <mj-attributes>
      <mj-all font-family="Inter, Arial, sans-serif" />
      <mj-text font-size="16px" line-height="1.5" />
      <mj-button background-color="#111827" color="#ffffff" border-radius="8px" padding="16px" />
      <mj-class name="eyebrow" color="#6B7280" font-size="12px" text-transform="uppercase" letter-spacing="0.08em" />
      <mj-class name="card" padding="24px" background-color="#ffffff" border-radius="16px" />
    </mj-attributes>
    <mj-style>
      a { text-decoration: none; }
      .muted div { color:#6B7280 !important; }
      .h1 div { font-size:24px !important; font-weight:700 !important; line-height:1.25 !important; }
      .h2 div { font-size:18px !important; font-weight:600 !important; }
      .table th, .table td { padding:8px 12px; border:1px solid #E5E7EB; }
    </mj-style>
  </mj-head>

  <mj-body>
    <!-- Top nav with base-url -->
    <mj-section background-color="#111827" padding="0">
      <mj-column>
        <mj-navbar base-url="https://www.scalero.io" hamburger="true" ico-color="#ffffff" ico-font-size="24px" ico-align="right" padding="16px">
          <mj-navbar-link color="#ffffff" font-size="14px" href="/">Home</mj-navbar-link>
          <mj-navbar-link color="#ffffff" font-size="14px" href="/company/blog">Blog</mj-navbar-link>
          <mj-navbar-link color="#ffffff" font-size="14px" href="/contact">Contact</mj-navbar-link>
        </mj-navbar>
      </mj-column>
    </mj-section>
    <!-- Grouped content with shared background via wrapper -->
    <mj-wrapper padding="24px" background-color="#F3F4F6">
      <!-- Hero -->
      <mj-section>
        <mj-column>
          <mj-text mj-class="eyebrow">Update</mj-text>
          <mj-text css-class="h1">Introducing Smart Blocks</mj-text>
          <mj-image src="https://framerusercontent.com/images/yp3dx8JLyUw1l2OQWlNK8F5u6HY.png?scale-down-to=1024" alt="Feature image" padding="12px 0 0" border-radius="12px" />
          <mj-text>Build responsive emails faster with reusable MJML classes and global styles.</mj-text>
          <mj-button href="https://www.scalero.io">Learn more</mj-button>
        </mj-column>
      </mj-section>
      <!-- Two cards -->
      <mj-section>
        <mj-column mj-class="card">
          <mj-text mj-class="eyebrow">Quick Tip</mj-text>
          <mj-text css-class="h2">Use <code>&lt;mj-class&gt;</code> for reuse</mj-text>
          <mj-text css-class="muted">Define once in <code>&lt;mj-attributes&gt;</code>, apply everywhere.</mj-text>
          <!-- Table demo -->
          <mj-table css-class="table">
            <tr>
              <th align="left">Component</th>
              <th align="left">Class</th>
              <th align="left">What it does</th>
            </tr>
            <tr>
              <td><code>mj-text</code></td>
              <td><code>eyebrow</code></td>
              <td>Small, muted label</td>
            </tr>
            <tr>
              <td><code>mj-column</code></td>
              <td><code>card</code></td>
              <td>Padded white box</td>
            </tr>
          </mj-table>
          <mj-spacer height="8px" />
          <!-- Social icons -->
          <mj-social align="left" font-size="14px" icon-size="24px" mode="vertical">
            <mj-social-element name="linkedin" href="https://www.linkedin.com/company/scalero">LinkedIn</mj-social-element>
            <mj-social-element name="twitter" href="https://x.com/">Twitter</mj-social-element>
          </mj-social>
        </mj-column>
        <mj-column mj-class="card">
          <mj-text mj-class="eyebrow">Resources</mj-text>
          <mj-text css-class="h2">Starter Links</mj-text>
          <mj-text>Try MJML in your browser or install the CLI to compile to HTML.</mj-text>
          <mj-button href="https://mjml.io/try-it-live">Open Live Editor</mj-button>
          <mj-button href="https://github.com/mjmlio/mjml" background-color="#2563EB">Install via npm</mj-button>
        </mj-column>
      </mj-section>
    </mj-wrapper>
    <!-- Footer -->
    <mj-section padding="0 24px 24px">
      <mj-column>
        <mj-text css-class="muted">You’re receiving this because you subscribed at scalero.io.</mj-text>
        <mj-text css-class="muted">© 2025 Scalero, Inc.</mj-text>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Conclusion

MJML takes the pain out of email development, making it faster and easier to build responsive, reliable designs. With just a few tags, you can create layouts that would normally require dozens of lines of old-school HTML.

If you’d like some extra guidance, or need help coding production-ready emails, feel free to contact us. We’re happy to help.