`<Tailwind>`: Outlook.com ignores every media query after the first, because the generated `<style>` has adjacent `}}`
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 78/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- react, tailwindcss, typescript
- Área
- frontend
Línea de trabajo
Empieza en packages/react-email/src/components/tailwind/tailwind.tsx, en generate(nonInlineStyles), y lee cómo se serializa la hoja de estilos; el issue también señala downlevel-for-email-clients.ts para consultar las adaptaciones existentes para clientes de correo. Comprueba la salida generada de <style> con varios bloques @media y confirma que haya espacios en blanco entre llaves de cierre adyacentes y que se conserven las reglas CSS.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
What versions are you using? (if relevant)
[email protected] (bundled / render), [email protected] (latest of both at time of writing)
Describe the Bug
Outlook.com deletes everything in a <style> element that comes after two adjacent closing braces, }}. This is a long-standing client bug, documented in hteumeuleu/email-bugs#92. The documented workaround is any whitespace between the braces (} }).
<Tailwind> puts every non-inlinable rule in its own @media block and writes the stylesheet minified (generate(nonInlineStyles) in tailwind.tsx). Every block ends in }} and they all share one <style>, so Outlook.com keeps the first @media block and drops the rest.
In practice only one responsive (sm:, md:, …) or dark: rule per email works in Outlook.com. Columns that sit side by side through sm: widths stay stacked at desktop width, and only the first dark-mode colour applies. I've also seen the same thing in Outlook on the web with a Microsoft 365 mailbox and in the new Outlook for Windows.
The CSS is valid, so strictly this is Outlook's bug. But <Tailwind> already adapts its output for email clients (downlevel-for-email-clients.ts), and fixing it there would cover everyone who uses responsive or dark: classes. render(..., { pretty: true }) doesn't help: the <style> contents keep their }}.
Suggested fix: when writing the non-inlinable stylesheet, put whitespace between adjacent closing braces (} }). Merging identical media queries would not be enough on its own: with two different queries (a breakpoint and dark:), the second block still comes after a }}.
What is affected (leave empty if unsure)
Tailwind Component
Link to the code that reproduces this issue
https://github.com/lpolito/react-email-outlook-double-brace
Minimal, self-contained (react-email + tailwindcss only). Core of render.tsx:
import { Body, Head, Html, render, Tailwind } from "react-email";
// Four boxes, each red inline and turned green by its own `sm:` rule.
const Email = () => (
<Tailwind>
<Html>
<Head />
<Body>
<div className="bg-[#cf222e] sm:bg-[#1a7f37]">Box 1</div>
<div className="bg-[#cf222e] sm:bg-[#1f883d]">Box 2</div>
<div className="bg-[#cf222e] sm:bg-[#2da44e]">Box 3</div>
<div className="bg-[#cf222e] sm:bg-[#116329]">Box 4</div>
</Body>
</Html>
</Tailwind>
);
const html = await render(<Email />);
To Reproduce
npm install
npm run render
This writes out/raw.html (react-email's output, unchanged) and out/spaced.html (the same, with one space between each pair of adjacent closing braces inside <style>). The generated <style>:
@media (min-width: 40rem) {
.sm_bg-_1a7f37 {
background-color: rgb(26, 127, 55) !important;
}
}
@media (min-width: 40rem) {
.sm_bg-_1f883d {
background-color: rgb(31, 136, 61) !important;
}
}
@media (min-width: 40rem) {
.sm_bg-_2da44e {
background-color: rgb(45, 164, 78) !important;
}
}
@media (min-width: 40rem) {
.sm_bg-_116329 {
background-color: rgb(17, 99, 41) !important;
}
}
Open both in Outlook.com at desktop width (I used Litmus's Outlook.com client in Chrome).
out/raw.html: box 1 is green, boxes 2–4 stay red.

out/spaced.html: all four are green. (A Microsoft promo pop-up covers part of the top.)

Expected Behavior
Every @media block that <Tailwind> generates survives in Outlook.com, so all four boxes are green at desktop width.
What's your node version? (if relevant)
v24.18.0
- Lenguaje dominante
- TypeScript
- Estrellas
- 19.9k
- Forks
- 1.1k
- Merge medio
- 2 d 15 h
- PR fusionados (30 d)
- 61
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de resend/react-email
-
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
resend/react-email#3878 · 1 comentario · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
Tailwind stacked media variants leave nested CSS in rendered emailsPosiblemente ocupada @lakshya-dhariwal la tomó hace 3 días. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
resend/react-email#3874 ·
Los mantenedores suelen responder en 1 día
-
Inspector Text panel omits Uppercase mark toggle (MARK_NAMES missing "uppercase")Posiblemente ocupada @svargas-dev la tomó hace 9 días. Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 22/100
resend/react-email#3849 ·
Los mantenedores suelen responder en 1 día
-
bug(tailwind): `pixelBasedPreset` only converts spacing and font size; `rounded-*` and `max-w-*` still emit `rem`Posiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 45/100
resend/react-email#3845 ·
Los mantenedores suelen responder en 1 día
-
Dependency DashboardAbiertodependencies
Dificultad 5/5 Más de una semana Aptitud para principiantes 15/100
resend/react-email#746 ·
Los mantenedores suelen responder en 1 día
Todos los issues de resend/react-email
Issues similares
-
Language request: NixAbiertoenhancement language
Dificultad 2/5 1-3 horas Aptitud para principiantes 67/100
pngwn/twinkleplop#178 ·
-
build P3
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
maniator/verticopolis#1945 ·
Los mantenedores suelen responder en 1 día
-
Admin users page number stays stale after filteringPosiblemente ocupada @matthewxkong la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
feature request needs triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 67/100
outline/outline#14529 · 1 comentario ·
Los mantenedores suelen responder en 1 día