{"id":28446353,"url":"https://github.com/sleede/html-email-template","last_synced_at":"2026-01-30T03:40:39.896Z","repository":{"id":144742910,"uuid":"319969265","full_name":"sleede/html-email-template","owner":"sleede","description":null,"archived":false,"fork":false,"pushed_at":"2020-12-09T08:44:37.000Z","size":4574,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-02T20:16:57.313Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"v-dj/html-email-template","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sleede.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-12-09T13:44:38.000Z","updated_at":"2022-06-02T21:07:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"9382a526-4005-4405-8c55-39f20464b6d3","html_url":"https://github.com/sleede/html-email-template","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sleede/html-email-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sleede%2Fhtml-email-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sleede%2Fhtml-email-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sleede%2Fhtml-email-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sleede%2Fhtml-email-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sleede","download_url":"https://codeload.github.com/sleede/html-email-template/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sleede%2Fhtml-email-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28899225,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T03:36:35.398Z","status":"ssl_error","status_checked_at":"2026-01-30T03:36:34.949Z","response_time":66,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-06T10:40:31.590Z","updated_at":"2026-01-30T03:40:39.890Z","avatar_url":"https://github.com/sleede.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Créer et tester des emails html\n\n[création](#mjml) | [test](#testi)\n\n## Ressources\n\n\u003cdetails\u003e\n\u003csummary\u003e+/-\u003c/summary\u003e\n\n- [emailclientmarketshare.com](http://emailclientmarketshare.com/) :bar_chart:\n- [campaignmonitor.com/css/](https://www.campaignmonitor.com/css/) :vertical_traffic_light:\n- [caniemail.com](https://www.caniemail.com/) :vertical_traffic_light:\n- [templates.mailchimp.com](https://templates.mailchimp.com/) :bookmark_tabs:\n- [mailjet.com/resources](https://www.mailjet.com/resources/) :bookmark_tabs:\n- [emailonacid.com/blog](https://www.emailonacid.com/blog/category/email-development/) :bookmark_tabs:\n- [litmus.com/resources](https://www.litmus.com/resources/) :bookmark_tabs:\n- [emailonacid.com/resources](https://www.emailonacid.com/resources/) :bookmark_tabs:\n- [reallygoodemails.com](https://reallygoodemails.com/) :art:\n\n\u003c/details\u003e\n\n# MJML\n\nMJML est un langage de balisage *open-source* créer par [Mailjet](https://www.mailjet.com/).  \nGrâce à une syntaxe simple et un ensemble de composants, MJML permet de rapidement créer des emails HTML *responsive* et directement compatibles avec une grande majorité de clients mail.  \nC'est le moteur MJML qui se charge de compiler le template en HTML.  \n\n![code](demo/assets/code.png)\n\n## Documentation\n\n[https://documentation.mjml.io/](https://documentation.mjml.io/)\n\n## Utilisation\n\u003cdetails\u003e\n\u003csummary\u003eMJML dispose de nombreuses options d'utilisations :\u003c/summary\u003e\n\n- [éditeur en ligne](https://mjml.io/try-it-live)\n- [application desktop](https://mjmlio.github.io/mjml-app/)\n- dans **VS Code** grâce à une [extension](https://github.com/mjmlio/vscode-mjml)\n- en [ligne de commande](https://github.com/mjmlio/mjml/blob/master/packages/mjml-cli/README.md)\n- dans [Node.js](https://documentation.mjml.io/#inside-node-js)\n- [API](https://mjml.io/api) gratuite\n- \\+ les outils développés par la [communauté](https://mjml.io/community)...  \n\nExemple d'intégration dans un projet avec la gem [MJML-Rails](https://github.com/sighmon/mjml-rails) qui permet d'injecter des données dynamiques :\n\n```html\n\u003c!-- ./app/views/user_mailer/_info.html.erb --\u003e\n\u003cmj-text\u003eThis is \u003c%= @user.username %\u003e\u003c/mj-text\u003e\n\n\u003c!-- ./app/views/user_mailer/email.html.mjml --\u003e\n\u003cmjml\u003e\n  \u003cmj-head\u003e\n    \u003cmj-preview\u003eHello World\u003c/mj-preview\u003e\n  \u003c/mj-head\u003e\n  \u003cmj-body\u003e\n    \u003cmj-section\u003e\n      \u003cmj-column\u003e\n        \u003cmj-text\u003eHello World\u003c/mj-text\u003e\n        \u003c%= render partial: \"info\" %\u003e\n      \u003c/mj-column\u003e\n    \u003c/mj-section\u003e\n  \u003c/mj-body\u003e\n\u003c/mjml\u003e\n```\n\n\u003c/details\u003e\n\n:warning: Il est préférable de générer une version HTML *minifiée* car elle supprime les attributs `style` vides qui peuvent poser problème sur *Outlook*.\n\n## En pratique\n\n#### Structure :\n\n```html\n\u003c!-- balise principale --\u003e\n\u003cmjml\u003e\n  \u003c!-- métadonnées + styles --\u003e\n  \u003cmj-head\u003e\n    \u003c!-- texte de l'onglet navigateur --\u003e\n    \u003cmj-title\u003e\u003c/mj-title\u003e\n    \u003c!-- texte d'aperçu dans la boite mail --\u003e\n    \u003cmj-preview\u003e\u003c/mj-preview\u003e\n    \u003c!-- attributs par défaut des balises MJML + class --\u003e\n    \u003cmj-attributes\u003e\n      \u003cmj-all padding=\"0\" /\u003e\n      \u003cmj-text font-size=\"18px\" line-height=\"24px\" /\u003e\n      \u003cmj-class name=\"header\" font-size=\"48px\" /\u003e\n    \u003c/mj-attributes\u003e\n    \u003c!-- styles appliqués au HTML généré --\u003e\n    \u003cmj-style\u003e\n      .primary div {\n        color: tomato !important;\n      }\n    \u003c/mj-style\u003e\n  \u003c/mj-head\u003e\n  \n  \u003c!-- corps du mail --\u003e\n  \u003cmj-body\u003e\n    \u003c!-- division verticale --\u003e\n    \u003cmj-section\u003e\n      \u003c!-- division horizontale --\u003e\n      \u003cmj-column\u003e\n        \u003cmj-text mj-class=\"header\"\u003eHello World !\u003c/mj-text\u003e\n        \u003cmj-text css-class=\"primary\"\u003eLorem ipsum dolor sit amet...\u003c/mj-text\u003e\n      \u003c/mj-column\u003e\n    \u003c/mj-section\u003e\n  \u003c/mj-body\u003e\n\u003c/mjml\u003e\n```\n---\n\n#### Style :\n\nMJML va générer une structure de plusieurs éléments HTML en convertissant un composant.  \n:warning: Une `\u003ccss-class\u003e` est toujours appliquée à l'élément parent. Pour appliquer correctement un style il va donc parfois être nécessaire d'inspecter le code généré pour cibler le bon élément enfant.  \n:warning: Comme les styles *inline* sont très utilisés dans les emails HTML il est indispensable de toujours ajouter `!important`.  \n\n![specificity](./demo/assets/specificity.png)  \n[specificity.mjml](./demo/specificity.mjml) : règles de spécificité.\n\n---\n\n#### Unitées :\n\nLa largeur des `\u003cmj-column\u003e` est en **pourcentages** (%) mais pour tout le reste il semble préférable de rester en **pixels** (px).  \nUn exemple : *Outlook* va transformer un *padding* définit en pourcentages... en pouces, et d'une façon *étrange*.  \nL'unité `em` peut également être utilisée sur tout les clients mail [(source)](https://www.caniemail.com/features/css-unit-em/).\n\n---\n\n#### Formats d'images :\n\n- `.gif`(pas d'animation sur Outlook)\n- `.png` (même avec alpha)\n- `.jpeg`\n- Pas de `.svg` :no_entry_sign:  \n[source](https://www.caniemail.com/search/?s=image%20format)  \n\n:warning: Donnez à chaque élément `\u003cmj-image\u003e` décoratif un attribut `alt` vide : `alt=\"\"`\n\n---\n\n#### Responsive :\n\nMJML met à disposition un composant `\u003cmj-column\u003e` au comportement *responsive*.  \nPlacés dans une `\u003cmj-section\u003e`, les `\u003cmj-column\u003e` se partagent sa largeur sur desktop et vont automatiquement s'empiler verticalement sur mobile. La largeur des `\u003cmj-column\u003e` est définie en pourcentage sans que la somme ne dépasse les 100%. Par défaut l'espace est réparti uniformément sur chaque `\u003cmj-column\u003e`.  \nUn composant `\u003cmj-group\u003e` englobant des `\u003cmj-column\u003e` va annuler ce comportement responsive pour les grader côte à côte sur mobile.  \n\n![columns](./demo/assets/columns.gif)  \n[columns.mjml](./demo/columns.mjml) : layout en 2 colonnes.\n\n---\n\n#### CSS Media query\n\nSupport : [plutôt bon](https://www.caniemail.com/features/css-at-media/).  \nIl faut bien les placer dans une balise `\u003cmj-style\u003e` **SANS** l'attribut `\u003cinline\u003e`. Vous pouvez créer plusieurs balises `\u003cmj-style\u003e` dans `\u003cmj-head\u003e`.  \n:warning: Utilisez la règle `!important` sur chaque propriété.\n\n```html\n\u003cmj-head\u003e\n  ...\n  \u003cmj-style inline=\"inline\"\u003e\n    .mobile table {\n      display: none !important;\n      mso-hide: all;\n    }\n  \u003c/mj-style\u003e\n\n  \u003c!-- mj-style SANS l'attribut inline --\u003e\n  \u003cmj-style\u003e\n    @media (max-width: 480px) {\n      .paragraph div {\n        font-size: 16px !important;\n        color: tomato !important;\n      }\n      .desktop table {\n        display: none !important;\n        mso-hide: all;\n      }\n      .mobile table {\n        display: table !important;\n      }\n    }\n  \u003c/mj-style\u003e\n\u003c/mj-head\u003e\n```\n\n![media_query](./demo/assets/media_query.gif)  \n[media_query.mjml](./demo/media_query.mjml) : afficher/masquer des images différentes sur mobile et desktop et appliquer différents styles à un même élément.\n\n---\n\n#### Police distante\n\nSupport : [très mauvais](https://www.caniemail.com/features/css-at-font-face/).  \nUtilisez la balise `\u003cmj-font\u003e` dans `\u003cmj-head\u003e` et pointez l'attribut `href` vers un fichier contenant la déclaration `@font-face` de la police (ex : [Creepster](https://fonts.googleapis.com/css2?family=Creepster)).\n\n```html\n\u003cmj-head\u003e\n  ...\n  \u003cmj-font name=\"Creepster\" href=\"https://fonts.googleapis.com/css2?family=Creepster\" /\u003e\n  ...\n\u003c/mj-head\u003e\n\n\u003cmj-body\u003e\n  ...\n  \u003cmj-section\u003e\n    \u003cmj-column\u003e\n      \u003cmj-text font-family=\"Creepster, sans-serif\"\u003e\n        custom font\n      \u003c/mj-text\u003e\n    \u003c/mj-column\u003e\n  \u003c/mj-section\u003e\n  ...\n\u003c/mj-body\u003e\n```\n\n![custom_font](./demo/assets/custom_font.png)  \n[custom_font.mjml](./demo/custom_font.mjml) : appliquer une police distante.\n\n---\n\n#### Image de fond (fenêtre client)\n\nSupport : bon... sauf sur Outlook (Windows) mais possibilité de faire mieux directement dans le html.  \nUtilisez l'attribut `full-width=\"full-width\"` sur la balise `\u003cmj-wrapper\u003e` et pointez l'attribut `background-url` vers le fichier image.\n\n```html\n  \u003cmj-body\u003e\n    \u003cmj-wrapper background-url=\"./assets/pattern.png\" background-size=\"400px\"\u003e\n      ...\n    \u003c/mj-wrapper\u003e\n  \u003c/mj-body\u003e\n```\n\n![background_image](./demo/assets/background_image.png)  \n[background_image.mjml](./demo/background_image.mjml) : appliquer une image de fond sur toute la fenêtre du client.\n\n---\n\n#### Exemple de *template*\n\n![template](./demo/assets/template.png)  \n[template.mjml](./demo/template.mjml) : template utilisant différents composants MJML.\n\n---\n\n# Testi@ \n\nUne fois le *template* généré il faut **impérativement** le tester et c'est ce que propose le site [testi.at](https://testi.at/) grâce à l'aperçu de plus de 90 clients mail sur desktop, mobile et webmail.  \n\n## Utilisation\n\n#### Éditeur\n\nTesti@ dispose lui aussi d'un éditeur avec sa preview.  \nIl suffit de créer un nouveau test (1), coller le code html dans l'éditeur (2), sélectionner les clients mail (3) dans la liste et de lancer le test (4).  \nL'interface permet aussi de\n![nouveau test](demo/assets/test_new.png)\n![éditeur](demo/assets/test_editor.png)\n![clients](demo/assets/test_clients.png)  \n\n---\n\n#### Réception d'email\n\nVous pouvez aussi recevoir des emails sur votre alias de compte.  \nC'est pratique pour tester une campagne **MailChimp** par exemple.  \nDepuis l'onglet *Settings / Profile*, vous pouvez copier l'adresse et vous connecter pour recevoir le mail qui va lancer le test automatiquement.  \n![settings](demo/assets/test_settings.png)  \n\n---\n\n#### Aperçus\n\nEnfin, l'interface de présentation des captures d'écrans permet de visualiser le rendu du mail sur les différents clients.  \nVous pouvez déplier/replier toutes les fenêtres d'aperçus (1), parfois visualiser le code source (2) et relancer un client (3).  \n![preview](demo/assets/test_preview.png)  ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleede%2Fhtml-email-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsleede%2Fhtml-email-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleede%2Fhtml-email-template/lists"}