fix: keep mail lines a readable length on wide screens

This commit is contained in:
Linus Rath
2026-10-15 03:18:58 +02:00
parent ae1ef5ba5e
commit e94b782f8e
2 changed files with 18 additions and 1 deletions
+10
View File
@@ -8,6 +8,7 @@ import {
hasRemoteContent, hasRemoteContent,
prepareEmailHtml, prepareEmailHtml,
wrapPlainTextEmail, wrapPlainTextEmail,
wrapEmailHtml,
hasNativeDarkMode, hasNativeDarkMode,
sniffImageMime, sniffImageMime,
TRANSPARENT_BLOCKED_PIXEL, TRANSPARENT_BLOCKED_PIXEL,
@@ -253,3 +254,12 @@ describe('sniffImageMime', () => {
expect(sniffImageMime(new Uint8Array([1, 2, 3]), 'application/octet-stream')).toBe('application/octet-stream'); expect(sniffImageMime(new Uint8Array([1, 2, 3]), 'application/octet-stream')).toBe('application/octet-stream');
}); });
}); });
describe('reading width on a wide pane', () => {
it('caps HTML and plain-text bodies only above the tablet breakpoint', () => {
const html = wrapEmailHtml('<p>Hello</p>');
expect(html).toMatch(/@media \(min-width: 840px\) \{\s*body \{ max-width: 720px;/);
const plain = wrapPlainTextEmail('Hello');
expect(plain).toContain('@media (min-width: 840px) { body { max-width: 80ch; } }');
});
});
+8 -1
View File
@@ -449,6 +449,11 @@ body {
word-wrap: break-word; word-wrap: break-word;
overflow-wrap: break-word; overflow-wrap: break-word;
} }
/* A wide reading pane (tablet): keep lines readable instead of running
150+ characters across. Phones never reach the breakpoint. */
@media (min-width: 840px) {
body { max-width: 720px; margin-left: auto; margin-right: auto; }
}
/* Only force the cap on images and tables that set no max-width of their own: /* Only force the cap on images and tables that set no max-width of their own:
an !important 100% also overrides a sender's inline max-width, so an image an !important 100% also overrides a sender's inline max-width, so an image
sized by max-width + max-height + width:100% grows to the pane width while sized by max-width + max-height + width:100% grows to the pane width while
@@ -676,7 +681,7 @@ export function wrapPlainTextEmail(
const { isDark = true, font = 'sans' } = options; const { isDark = true, font = 'sans' } = options;
const cleaned = stripDangerousTags(innerHtml); const cleaned = stripDangerousTags(innerHtml);
const bg = isDark ? '#09090b' : '#ffffff'; const bg = isDark ? '#0a0a0a' : '#ffffff';
const fg = isDark ? '#fafafa' : '#1a1a1a'; const fg = isDark ? '#fafafa' : '#1a1a1a';
const link = isDark ? '#60a5fa' : '#1a73e8'; const link = isDark ? '#60a5fa' : '#1a73e8';
const fontFamily = font === 'mono' const fontFamily = font === 'mono'
@@ -701,6 +706,8 @@ body {
} }
a { color: ${link}; text-decoration: underline; } a { color: ${link}; text-decoration: underline; }
details > summary::-webkit-details-marker { display: none; } details > summary::-webkit-details-marker { display: none; }
/* A wide reading pane (tablet): about 80 characters a line. */
@media (min-width: 840px) { body { max-width: 80ch; } }
`; `;
return `<!doctype html> return `<!doctype html>