Making Responsive HTML Email Coding Easy With MJML

Email is one of the best ways to engage with your users, especially during the holiday season. However, if you want to stand out, no matter how beautiful your emails are, you need to make sure they render correctly in your reader’s inbox, regardless of what email client they’re using. Creating responsive email is not an easy task, and there are various reasons for that.

First, there is no standard in the way email clients render HTML. This is true for email clients from different companies, such as Outlook and Apple Mail, but not only. Even different versions of Outlook, such as Outlook 2003, Outlook 2013 and, render HTML differently.

Then, while email clients render HTML, many of them have very limited support of it. Some email clients will just strip the head of your HTML file, including media queries, which is why inline styles are heavily recommended. On a good note, this is moving in the right direction with the Gmail update1.

Now, there are a few techniques out there to help email developers. You might be familiar with some of them, such as the hybrid approach2, the mobile-first approach3 or even the Fab Four technique4 by HTeuMeuLeu5. But because of the reasons stated earlier, and especially the lack of a standard, none of these techniques will enable you to tame all email clients at once.

Abstracting Away The Complexity Of Responsive Email With MJML Link

MJML is an open-source framework that abstracts away the complexity of responsive email. The idea behind it is pretty simple. Just as jQuery normalizes the DOM and abstracts low-level interactions and animations, MJML abstracts the low-level hacks for responsive emails with an easy syntax. MJML is responsive by design. This means you can forget about nested tables and conditional comments and, more generally, about making your email responsive. MJML does it for you.

Leveraging a semantic syntax and high-level components such as the carousel6 (yes, you can display an interactive image gallery within an email!), MJML is really easy to learn for anyone. Responsive emails are no longer only accessible to a handful of experts anymore.

Example of an MJML component: carousel.7

Example of an MJML component: carousel

Being easy to use doesn’t mean that MJML is not powerful. It just enables experts to streamline their development workflow, while still giving them the flexibility they need with lower-level components such as tables8.

For instance, our example email9 was coded in 788 lines of HTML10 and reproduced in fewer than 240 lines of MJML11.

The Approach Link

MJML is built in React12, a JavaScript library developed and maintained by Facebook, and it leverages the power of React’s components. The component names are semantic, starting with mj-, so that they are straightforward as well as easy to recognize and understand: mj-text, mj-image, mj-button, etc.

MJML will transpile to responsive HTML, following a mix of the mobile-first and hybrid coding approaches. Going mobile-first enables you to make sure that the most readable version is displayed by default in email clients that do not change the layout according to the device used.

For example, in, the mobile version will be displayed on both desktop and mobile (which is far more readable than a desktop version being displayed on mobile). The hybrid approach then enables the layout to change according to the device’s size wherever possible, using a mix of fallbacks, conditional comments, nested tables and media queries to target as many clients as possible. The layout degrades nicely, with multi-column layouts on desktop turning into single-column layouts on mobile.

2-column layout - desktop view.13

Two-column layout, desktop view
2-column layout - mobile view.14

Two-column layout, mobile view

Coding In MJML Link

Before we start the tutorial, let’s get ready to code in MJML. We have different ways to use MJML, such as running it locally15 or using the online editor2316. By choosing the online editor, you’ll be able to start immediately, but running it locally enables you to use MJML with your favorite code editor (with plugins for Atom17, Sublime Text18 and Vim19), task runners such as gulp-mjml20 and grunt-mjml21 and a lot more22.

For this tutorial, the online editor2316 is recommended because it doesn’t require any setup.

If you still want to use it locally, open your terminal and run npm install mjml -g (requires to have Node.js and npm24 installed).

Once MJML is installed, create a file named example.mjml (or any name you like) with some MJML and run mjml -r example.mjml in your terminal (make sure to be in the same folder as the file you’re rendering). It will render your MJML file in a file named example.html, with the responsive HTML inside. You can find all available options for the command line in the documentation25.

Creating Your First Newsletter With MJML Link

Now that you’re all set up, we can start creating a responsive newsletter together. To find inspiration, one of the best places around is ReallyGoodEmails26. I found a great example of a newsletter27 by Thrive Market28. Let’s recreate it with MJML!

(Brand names, logos and trademarks used herein remain the property of their respective owners, and their use does not imply any endorsement by or affiliation with Thrive Market.)

Thrive Market newsletter29

Thrive Market newsletter

First, here is what the basic layout30 of an MJML document looks like:





Streamlining The Style Link

While inlining is the norm in HTML to ensure responsiveness, MJML also allows you to create custom MJML classes and MJML styles, which will then automatically be inlined from the head of your MJML file31. In MJML, styles come as component attributes.

	Hello World

To start, we’ll set a default sans-serif font family for text components, because sans-serif is used for most text here. Then, we’ll create classes for elements used repeatedly, so that we don’t have to manually set styles over and over again. We could have created more custom classes and styles, but the most useful styles will be for:

  • buttons,
  • image descriptions,
  • text below the six icons in the footer.

Here, we’ll be leveraging head components32 in three ways:

  • Set a default padding of 0 for every component, using . This default padding can be overridden by manually specifying a padding directly on the components we are using.
  • Override the default font family of , using in the head. Each time we use , the default font family will be sans-serif. We can still manually override this new default font by specifying a new one directly on the component.
  • Create classes using and, more specifically, using the following mj-classes:
    • pill
      This is to design a nice button. Attributes worth noting are the background-color set to transparent and the inner-padding, used to size the button as we want.
    • desc
      This is to style the descriptions of the images in the two-column layout.
    • ico
      This is to style the text below the six icons just before the footer.

  	Discover the latest trends

(As you may have noticed, we have omitted the units on some attributes, such as padding. If you do so, MJML will output the attributes with px by default.)

Adding Content Link

Now that the styles are defined in the head (you can see here33 what your code should look like now), let’s start adding content to our email! MJML layouts are based on 34 to create rows and 3835 to create columns inside rows, which is very practical for email design. Note that, except for high-level components such as 36 and 37, content should always be wrapped in a 3835, which itself should go in a 39, even when there is only one column in a section.

Let’s see this with two examples, the preheader and the header of the email.

There’s nothing very fancy here. We’re just creating a text preheader using the 40 component, wrapped in a column, and giving it some MJML styles.

Hack: enables you to use HTML directly inside MJML, granting you full control over the content and allowing you to use the and tags you’re used to, for example.


			The latest tips, trends, recipes, and more

Header of the email41

Header of the email

The header is a bit fancier but very easy to achieve with MJML. All we have to do is create a section that we’ll split into three equal columns (because columns are equal, we don’t even have to manually set the width). We’ll use images as in the original email, leveraging the explicit component 42, which comes with the common attributes you would expect, including src, padding and border.

By default, columns will stack in the mobile version of our email. Here, because we want those three columns to stay side by side even on mobile, we’ll wrap them in an 43 component, which will prevent the columns from stacking.

Hack: As noted in the documentation, due to a bug in iOS, you might have to use a minifier, or else the columns could stack on iPhone even if they’re wrapped in . The MJML command-line interface44 comes with a built-in minifier45 that you can use to run the -m option when rendering MJML.



One-Column Layout for the GIF and CTA Link

We’ll create another section in which we’ll simply add an image, some text and a button. The only new component here is 46, which should be clear enough and which comes with the standard attributes. Please note that you must specify an href, or else the text of the button might not display in some email clients.

			Your daily destination for healthy living
			Read more


Divider Between Body and Header Link

Yes, there’s a component for that, too! It’s a good practice to split different rows into different sections, instead of dumping everything into the same section, because that gives you more control over styling (especially through padding), and it also makes it easier to isolate any problems that occur.



We’ll use the same divider between the body and footer later.

Body Link

Now that we have a beautiful header47, let’s start with what seems to be the complex part of this email.

Two-Column Layout That Stacks on Mobile Link

Two-column layout48

Two-column layout

Here, we’ll create a section for each two-column row. Each column will consist of an image, a piece of text and a button. The good news is that, thanks to MJML’s hybrid approach, we don’t have to do anything to make the images stack on mobile. It’s responsive by default!

Regarding the styling, we don’t have much to do because we’re leveraging the mj-classes pill and desc, which we created earlier. All we need to do is add some padding to match the style of the original email.

Hack: Due to an issue with Outlook 2000, 2002 and 2003 ignoring the set width, it’s a good practice in MJML to set images to the sizes you want them to display at in those clients.

			5 Foods to Boost Your Happiness
			Read more
				Whiten Teeth Instantly with Activated Charcoal
			Read more


Here, we can see that the default HTML style for links is applied. In addition to , you can also inline CSS right into MJML using 49. Let’s do just that by updating the head to overwrite the default style of links once and for all. We’ll also create a CSS class to apply to the tags to give them the right color (we’re creating a class because the links in the email shouldn’t all have the same color).

	    Discover the latest trends
				a {
				.desc {
					color: #45495d;

Follow the same steps with the other two-column sections.

Blue Section With CTA Link

Blue section50

Blue section

To create this section, we’ll use the components that we’re getting familiar with: , and .

First, we’ll add a background-color to our section and some padding so that it looks as expected. Then, we just have to create two columns, one wider than the other, leveraging the width attribute with percentages. As usual, columns will stack on mobile. Because the button is different from the others here, we won’t use the pill class, but rather will manually create a new style.

Hack: Because of poor support for shorthand HEX colors in Internet Explorer, we recommend using six-digit HEX colors. This is a hack that we’ll reintegrate in MJML at some point to make sure that three-digit HEX codes are turned into six-digit codes.

			Get all your healthy groceries at Thrive Market!
			Shop Now


Last Section Of The Body Link

Last section of the body51

Last section of the body

To design the title, we’ll create a three-column layout. The columns will consist of the following, respectively:

  • the dark blue line to the left of the title,
  • the title "Want More Tips, Tricks, and Delicious Recipes?",
  • the dark blue line to the right of the title.

Then, we will wrap the three columns in an so that it doesn’t stack on mobile.

We’ll start creating the lines, leveraging the component, setting its border-width to 2px and adding some padding so that it looks the way we want. By default, the divider will fill the column it’s contained in, so that it looks consistent across devices. Therefore, we don’t need to explicitly set the width of the divider.

Then, we’re just using to add our title, leveraging the desc mj-class (because we want to inherit some of the styles set in this class) and overriding the font-family and align properties that are different from this class. We could have also manually set the style without using the desc mj-class.

Finally, we just have to use our button with the pill mj-class as we did before. We’re overriding the inner-padding because, according to the original design, this button is not as wide as the others.

					Want More Tips, Tricks, and Delicious Recipes?


			Read our Blog


You can see52 what our MJML template should look like so far.

Footer of the email53

Footer of the email

Title Link

We’re wrapping our title in a section and a column, as we’ve seen before, and we’re using the desc style that we created earlier. We need to alter only a few styles by manually setting a different align, font-size and font-style from our mj-class.

			Stay Connected


Six-Icon Section Link

This section is made up of six icons, with accompanying text below. The icons display side by side on desktop and wrap to two lines of three icons on mobile. By now, you probably know that creating such layouts is easy if we leverage the component. To make the icons stack onto two lines, all we have to do is wrap the columns in two groups of three columns in an .

To design the text below the icons, we just have to use the ico mj-class that we created before. We’ll also create a CSS class named ico to apply to the a tags, like we did in the two-column layout section.

			Gluten Free

Social Networks Link

Once again, this section is easy to achieve by leveraging the component, using one column per social network icon and wrapping all of the icons in an so that they don’t stack on mobile. The only trick here is to fine-tune the width of the images and the padding so that the result is consistent with the original design.

Divider and Text Link

Because this part is pretty simple, it’s OK to wrap the divider and the text in the same column and section, even though we could have separated the divider from the text. As we did before when styling the links, we’ll create a footer class so that our links have the proper color.

		Read Our Blog View Email Online

Please don't hit 'reply' to this email--we won't be able to email you back from this address and help you thrive! If you need anything, visit our FAQ or contact Member Services anytime, and we'll be happy to help!

We don't want to see you go, but if you no longer wish to receive promotional emails from us, you can unsubscribe here or change your email preferences anytime.

4509 Glencoe Ave, Marina Del Rey, CA 90292
@2016 Thrive Market All Rights Reserved

Rendering the HTML File and Testing Link

You should now have fewer than 240 lines of MJML (you can check the full code54), whereas the original file was a bit less than 800 lines of HTML. Congrats! You’ve just created your first responsive email using MJML! How easy was that?

Testing how an email renders in different email clients is always a good practice, so let’s do just that using Litmus55 (Email on Acid56 is another great platform for email testing).

Go to Litmus57 (create an account if you don’t have one already), create a new project, and paste the HTML that we generated earlier in the code area. You’ll be able to see the results in various email clients by clicking “Instant Previews” in the right pane. You can see58 the results for major email clients, from Outlook 2003 to Inbox by Gmail.

Going Further Link

Now that you know how to use MJML to easily create a responsive email, why not try to create your own component? My tutorial59 will guide you through this step by step.

What did you think about your first experience with MJML? Feel free to reach out on Twitter60 and join the MJML community now by signing up to the Slack61 channel. You can also subscribe to the newsletter62 to keep up to date on the latest news.

(rb, vf, yk, al, il)

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62

? Back to top

Tweet itShare on Facebook

Powered by WPeMatico


  1. Dhiren SHAH January 24, 2017
  2. Federico Brigante January 24, 2017
  3. Anonymouse January 24, 2017
  4. Ralph January 24, 2017
  5. Nicolas Garnier January 24, 2017
  6. Rey Bango January 24, 2017
  7. Nicolas Garnier January 24, 2017
  8. Alek Davis January 24, 2017
  9. Pedro E. Matos January 24, 2017
  10. Pedro E. Matos January 24, 2017
  11. Jim Olson January 24, 2017
  12. Nicolas Garnier January 24, 2017
  13. Nicolas Garnier January 24, 2017
  14. Alek Davis January 24, 2017
  15. Alek Davis January 24, 2017
  16. Ryan Hettler January 24, 2017
  17. Adam January 24, 2017
  18. rodyone January 25, 2017
  19. Slinky January 25, 2017
  20. Nicolas Garnier January 25, 2017
  21. Nicolas Garnier January 25, 2017
  22. Nicolas Garnier January 25, 2017
  23. Nicolas Garnier January 25, 2017
  24. Adrian January 25, 2017
  25. Nicolas Garnier January 25, 2017
  26. Maksim January 25, 2017
  27. Michel Gotta January 25, 2017
  28. Alek Davis January 25, 2017
  29. Adrian January 25, 2017
  30. Nicolas Garnier January 26, 2017
  31. Jez January 26, 2017
  32. Boots January 27, 2017
  33. Ed Akagawa January 31, 2017
  34. Cosmin January 31, 2017

Leave a Reply