You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Preview: apply max-device-width media queries at the Mobile preset
#3848
At the Mobile (375px) preset, an email's (max-device-width: …) / (min-device-width: …) rules should apply the way they would on a phone.
Failing that, make it visible in the preview that those rules are not evaluated against the selected width.
Background
Many hand-written and legacy email templates target phones with @media only screen and (max-device-width: 480px) instead of max-width, because some email clients only honored the device variant. The preview server renders raw .html templates too, so this markup shows up there.
The Mobile preset sets the preview iframe to 375×667. Inside an iframe on a desktop browser, device-width is the width of the screen, not of the frame, so those rules never match and the mobile layout never shows. max-width rules work as expected.
Checked in Chrome 156 with a plain 375px srcdoc iframe:
inside the frame
value
innerWidth
375
screen.width
3360
matchMedia('(max-width: 480px)')
true
matchMedia('(max-device-width: 480px)')
false
Reproduction with the preview server (latest stable and canary; the UI source has no handling for device-width):
Add emails/legacy.html:
<!doctype html><html><head><style>p{color: black;}@mediaonly screen and(max-device-width:480px){p{color: red;}}</style></head><body><p>Should be red at the Mobile preset</p></body></html>
Run email dev and open legacy.html.
Switch to Mobile: the text stays black. With max-width: 480px instead, it turns red.
Components and Tailwind output use max-width, so this only affects custom CSS and raw HTML templates. It's in the same family as #3609: how much client or device behavior the preview should emulate.
Proposal
Change only the displayed copy, never the markup that is exported or sent: after the iframe loads, walk contentDocument.styleSheets, and for each same-origin CSSMediaRule whose media.mediaText contains device-width, rewrite it to width (rule.media.mediaText = …). Then the frame's own width stands in for the device width. It's about 30 lines next to the existing applyColorInversion hook in email-frame.tsx, plus a test.
A smaller alternative is a hint in the UI when the email contains device-width queries.
I'm happy to open a PR for either one, if you think it belongs in the preview.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Goals
(max-device-width: …)/(min-device-width: …)rules should apply the way they would on a phone.Background
Many hand-written and legacy email templates target phones with
@media only screen and (max-device-width: 480px)instead ofmax-width, because some email clients only honored the device variant. The preview server renders raw.htmltemplates too, so this markup shows up there.The Mobile preset sets the preview iframe to 375×667. Inside an iframe on a desktop browser,
device-widthis the width of the screen, not of the frame, so those rules never match and the mobile layout never shows.max-widthrules work as expected.Checked in Chrome 156 with a plain 375px
srcdociframe:innerWidthscreen.widthmatchMedia('(max-width: 480px)')truematchMedia('(max-device-width: 480px)')falseReproduction with the preview server (latest stable and
canary; the UI source has no handling fordevice-width):Add
emails/legacy.html:Run
email devand openlegacy.html.Switch to Mobile: the text stays black. With
max-width: 480pxinstead, it turns red.Components and Tailwind output use
max-width, so this only affects custom CSS and raw HTML templates. It's in the same family as #3609: how much client or device behavior the preview should emulate.Proposal
Change only the displayed copy, never the markup that is exported or sent: after the iframe loads, walk
contentDocument.styleSheets, and for each same-originCSSMediaRulewhosemedia.mediaTextcontainsdevice-width, rewrite it towidth(rule.media.mediaText = …). Then the frame's own width stands in for the device width. It's about 30 lines next to the existingapplyColorInversionhook inemail-frame.tsx, plus a test.A smaller alternative is a hint in the UI when the email contains
device-widthqueries.I'm happy to open a PR for either one, if you think it belongs in the preview.
All reactions