From ddee5d4baf0f5a711ce5080727eb6ef5e026c247 Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Wed, 29 Apr 2026 11:21:08 -0400 Subject: [PATCH] fix post email width --- emails/post.tsx | 28 ++++++++++++++-------------- emails/shared.tsx | 35 ++++++----------------------------- 2 files changed, 20 insertions(+), 43 deletions(-) diff --git a/emails/post.tsx b/emails/post.tsx index 79d0de5b..51bec99f 100644 --- a/emails/post.tsx +++ b/emails/post.tsx @@ -233,13 +233,6 @@ export const PostEmail = (props: Partial = {}) => { @media only screen and (max-width: 480px) { .email-page-pad { padding: 12px 8px !important; } .email-card-pad { padding: 16px !important; } - /* The card table carries an HTML width attribute (e.g. 624) so - Gmail anchors on it; on mobile that pins it wider than the - viewport. Force it to fit. */ - .email-card-table { - width: 100% !important; - max-width: 100% !important; - } } `} @@ -279,20 +272,27 @@ export const PostEmail = (props: Partial = {}) => { padding: "24px 16px", }} > - {/* Both the HTML `width` attribute and CSS `width` are set: - Gmail strips/ignores `max-width` in some contexts but - always honors the HTML attribute, so it pins the box at - the publication's web page width on desktop. The - media-query rule above forces 100% on small screens. */} + {/* Responsive width: `width="100%"` lets the card fill its + container, and `max-width: pageWidth` caps it on wider + viewports. This keeps it readable at the publication's + page width on desktop while shrinking gracefully when + the email is viewed in a narrow window (e.g. Apple Mail + desktop resized below the page width). Outlook desktop + ignores `max-width` and will render full-width — that's + a known tradeoff for the simpler markup. */} diff --git a/emails/shared.tsx b/emails/shared.tsx index f795551f..1d4e78cd 100644 --- a/emails/shared.tsx +++ b/emails/shared.tsx @@ -1,9 +1,4 @@ -import { - Head, - Img, - Link, - pixelBasedPreset, -} from "@react-email/components"; +import { Head, Img, Link, pixelBasedPreset } from "@react-email/components"; import React from "react"; export type EmailTheme = { @@ -34,15 +29,9 @@ export const defaultEmailTheme: EmailTheme = { // Parse rgb()/rgba()/#hex into [r, g, b]. Returns black on parse failure — // theme colors come from a typed config so this is just defensive. const parseColor = (input: string): [number, number, number] => { - const rgbMatch = input.match( - /rgba?\(\s*(\d+)[\s,]+(\d+)[\s,]+(\d+)/i, - ); + const rgbMatch = input.match(/rgba?\(\s*(\d+)[\s,]+(\d+)[\s,]+(\d+)/i); if (rgbMatch) - return [ - Number(rgbMatch[1]), - Number(rgbMatch[2]), - Number(rgbMatch[3]), - ]; + return [Number(rgbMatch[1]), Number(rgbMatch[2]), Number(rgbMatch[3])]; const hexMatch = input.match(/^#([0-9a-f]{6})$/i); if (hexMatch) { const h = hexMatch[1]; @@ -69,11 +58,7 @@ const parseColor = (input: string): [number, number, number] => { // leaving borders invisible and tinted text falling back to defaults. // Linear mixing isn't perceptually identical to the oklab original, but // for the near-grayscale tints we use it's visually indistinguishable. -export const mixRgb = ( - a: string, - b: string, - bPercent: number, -): string => { +export const mixRgb = (a: string, b: string, bPercent: number): string => { const [ar, ag, ab] = parseColor(a); const [br, bg, bb] = parseColor(b); const t = bPercent / 100; @@ -179,16 +164,9 @@ export const confirmEmailTailwindConfig = { // makes every element render visually small). Templates can pass extra // children — usually a `