feature(html/mjml): updates/reduction to underlying html#3059
Open
dazgreer wants to merge 7 commits intofix/replace-html-minifierfrom
Open
feature(html/mjml): updates/reduction to underlying html#3059dazgreer wants to merge 7 commits intofix/replace-html-minifierfrom
dazgreer wants to merge 7 commits intofix/replace-html-minifierfrom
Conversation
- mj-title throws an error if missing or empty - optional Outlook and dark mode support - add space to preview text - comprehensive tidy of HTML to reduce code bloat - updated tests and docs
guigui64
approved these changes
Mar 11, 2026
Collaborator
guigui64
left a comment
There was a problem hiding this comment.
Code looks good to me.
Just one remark on this:
removed all tags [potential small breaking change for any user added CSS that relies on it in a selector]
I think it is a breaking change (not a small one) and you should list it in the release notes.
mjml-core - Updated Prettier to use single quotes inside of CSS - Broken out the accordion CSS into its own style block as it was breaking other CSS and causing non functional components, e.g. carousel in Gmail and updated test mjml-section - fixed issues caused by removing background-size and background-repeat as default attributes whereby the default values were used to determine VML settings. Created automated test - removed multiple declarations of the background color and concatenated two divs that were split because of this - updated table to use role=“none”
guigui64
approved these changes
Mar 16, 2026
totocap
approved these changes
Mar 17, 2026
…d-tidy - Merged cssnano-preset-lite improvements and normalizeMinifyCssOption helper from fix/replace-html-minifier - Adopted Mocha-based *.test.js pattern for mjml-core tests (replacing old *-test.js runner) - Preserved accordion-style and dark-mode skeleton tests from feature branch in skeleton.test.js
cheerio is a webpack external for the browser bundle, so calling load() inside mergeHeadStyleBlocks() crashed the smoke test with 'Cannot read properties of undefined (reading load)'. Replace the cheerio DOM walk with a plain character scanner that tokenises <head> content into plain-style / whitespace / other segments and merges consecutive eligible <style> blocks inline. The merged output is identical; the import of load from cheerio is retained for the mj-html-attributes feature at the call-site that is already correctly guarded by an isEmpty() check. Also fixes no-continue lint errors by using an 'advanced' flag instead of continue statements in the tokenizer loop.
3842f49 to
3184a11
Compare
…t tests - extracted mergeHeadStyleBlocks into its own helper module and imported - added test file covering 29 unit tests.
totocap
approved these changes
Mar 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Highlights
mj-titlethrows an error if missing or emptyDetails
Features
mj-titlethrows an error if missing or empty (added test, updated doc)support-outlook-classicoption tomjmltag to remove support for Outlook (removes ghost tables and other Outlook specific code. Set to `true by default) (updated doc)mj-previewto add blank space after preview text (updated doc) [Fixes Create automatically white space after <mj-preview> text #1829]HTML changes
General
printWidthof Prettier to prevent long lines wrapping attributes and increasing filesizeclass=“”orstyle=“”| IEfrom all conditional commentshtml
xmlnsattribute as no longer neededxmlns:oattribute whensupport-outlook-classic=“true"xmlns:vifbackground-urlis present onmj-heroormj-sectionmeta
charsettagX-UA-Compatibletag as no longer usefuluser-scalable=yessupport-dark-modeoption (on<mjml>tag) to allow dark mode supporthead (skeleton)
.mj-outlook-group-fixCSS as only applies to older unsupported Outlook versions (2003 and less)-msprefixed reset styles whensupport-outlook-classic="false"-webkit-text-size-adjusttotext-size-adjustmarginfrom13pxto1em<link>font import, now uses just@importCSS:rootCSS behindsupport-dark-modeoption (on<mjml>tag) to allow dark mode supportstyle (skeleton)
type=“text/css”as no longer required<style>blocks where possiblemj-column-per-100as it’s declared by default in the tagtable
role=“presentation”torole=“none”<tbody>tags [breaking change for any user added CSS that relies on it in a selector]font-family declarations
HelveticaandArialas fallbacks [small breaking change as fonts will change to system default sans-serif font]mj-body
xml:lang=“”(populated from globalData language, declared onmjmltag)background-colourandword-spacingas declared on the childdivmj-accordion
border-bottomdeclaration to0and now only outputs when border is not already set to0ornonevertical-alignas it’s default to the tag<style>block as it broke other things in Gmailmj-accordion-element
paddingattribute as it’s default to the tagmj-button
text-transform,font-weightattributes as default to the tagtargetattribute as not necessary in emaildisplaytoblockand removedmso-padding-altdeclaration to solve issue where the full button is not clickable when thewidthis setmultilineoption to allow users to negate issues with the above in Outlook classic when button text wrapscursor: autoset on<td>andmargin: 0set on<a>mj-carousel
prettier-ignorecomment to fallback image as Prettier was breaking itmso-hide-allattributes as the carousel is not displayed in Outlookborder-radiusfrom Outlook fallback image as Outlook does not display ittargeton links andheighton image as not needed.[owa]class as no longer usedmj-carousel-image
targetattributecheckedfor first input rather thanchecked="checked"mj-column
directionattribute as default to the tagvertical-aligndeclaration fromtableas set in childrenmj-outlook-group-fixclass as only applies to older unsupported Outlook versions (2003 and less)mj-divider
tableorp(based onsupport-outlook-classic) and only outputs onepxunits for html tablewidthas they don’t workmax-widthto bothtableandpto better handle widthmj-group
directionattribute as default to the tag'text-align': 'left'from div as defaultmj-outlook-group-fixclass as only applies to older unsupported Outlook versions (2003 and less)mj-hero
background-urlandpaddingdefaultsbackground-repeatdeclaration inbackgroundshorthand valuebackground-positiondeclaration to singlecenter</td>tags for fluid height hero as self-closing tag is not validvertical-aligndeclaration from<tr>tagmj-image
fluid-on-mobileCSS when not settdand changed CSS selector to accommodatetext-decoration,outlineandfont-sizeas attributes as default to the tagtargetattribute as not necessary in emailmj-navbar
font-family/font-size/line-heightwhen declaring inmj-attributes>mj-all. Previously it was using its ownico-text-decorationattribute as default to the tag'mso-hide': 'all'and'-moz-user-select': 'none'as not requiredmj-navbar-link
font-weightas attribute as default to the tagtargetattribute as not necessary in emailmj-section
direction,background-repeatandbackground-sizeas attributes as default to the tagbackground-coloror color reference inbackgroundas unnecessarily declared multiple timestext-alignoption tocolumn-alignas it was poorly named. Aliased the deprecated option for backwards compatibility [updated docs]mj-social
targetattribute as not necessary in emailwidthdeclarations [Fixes MJ-SOCIAL - Outlook app android/iOS interpret wrong the icon-padding. #3043]mj-social-element
text-alignandvertical-alignas attributes as default to the tagmj-table
widthdeclaration when user sets toautoas default to tagtable-layoutattribute as default to the tag. If the user adds, it will also not be be written outmj-wrapper
text-alignfrom docs as it doesn't do anything