news 2026/11/4 11:15:06

React Email 组件完全参考:从 Tailwind 样式到 19 个核心组件的实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
React Email 组件完全参考:从 Tailwind 样式到 19 个核心组件的实战指南

React Email 组件完全参考:从 Tailwind 样式到 19 个核心组件的实战指南

【免费下载链接】react-email💌 Build and send emails using React项目地址: https://gitcode.com/GitHub_Trending/re/react-email

导读

本指南以 React Email 官方组件参考(COMPONENTS.md)为骨架,逐一定义并解析全部 19 个可用组件(Body、Button、CodeBlock、CodeInline、Column、Container、Font、Head、Heading、Hr、Html、Img、Link、Markdown、Preview、Row、Section、Tailwind、Text),并深入仓库源码(packages/react-email/src/components)印证其底层实现。阅读完本文,你将掌握:如何使用pixelBasedPreset规避rem单位在邮件客户端中的兼容性陷阱、如何组合 Row/Column 构建多栏布局、如何用 CodeBlock/Font 等专用组件呈现代码与字体,以及每个组件 Props 的真实语义与最佳实践。

首要原则:只导入你真正用到的组件。不要在使用组件的代码中遗漏对应 import,也不要引入未使用的组件,这既是包体积优化,也是模板可维护性的基础(见 components/index.ts,所有组件均从react-email单一入口导出)。


一、可用组件总览

所有组件统一从react-email导入。下表对应文档中列出的 19 个组件及其定位:

组件作用
Body包裹邮件正文内容的容器
Button被样式化为按钮的链接,内置 Outlook 内边距兼容处理
CodeBlock基于 Prism.js 的带主题、带正则高亮的代码块
CodeInline在所有邮件客户端都表现一致的行内代码元素
Column纵向分隔内容区域(必须与Row搭配使用)
Container在断点处水平居中内容的布局组件
Font设置邮件字体(支持 web font)
Head承载style、meta等文档级元素
Heading标题文本块(h1–h6)
Hr分隔内容区域的分割线
Html包裹邮件的根 html 组件
Img在邮件中展示图片
Link指向网页、邮箱地址等任意 URL 的超链接
Markdown将 Markdown 转换为合法的 react-email 模板代码
Preview收件箱中显示的预览文本
Row横向分隔内容区域
Section可用行和列进行格式化的区块
Tailwind以 Tailwind CSS 包裹邮件的样式组件
Text以空白分隔的文本块

二、Tailwind:官方推荐的样式方案

2.1 基础用法

官方推荐用 Tailwind 来样式化 React Email 组件:用<Tailwind>包裹邮件内容,直接使用工具类(utility classes)。

import { Tailwind, pixelBasedPreset, Html, Body, Container, Heading, Text, Button } from 'react-email'; export default function Email() { return ( <Html lang="en"> <Tailwind config={{ presets: [pixelBasedPreset], theme: { extend: { colors: { brand: '#007bff', accent: '#28a745' }, }, }, }} > <Body className="bg-gray-100 font-sans"> <Container className="max-w-xl mx-auto p-5"> <Heading className="text-2xl font-bold text-brand mb-4"> Welcome! </Heading> <Text className="text-base text-gray-700 mb-4"> Your content here. </Text> <Button href="https://example.com" className="bg-brand text-white px-6 py-3 rounded-lg block text-center box-border" > Get Started </Button> </Container> </Body> </Tailwind> </Html> ); }

Props:config—— Tailwind 配置对象。

2.2 工作原理(源码级)

从 tailwind.tsx 的实现可以看到完整的处理流水线:

  1. 工具类自动转为内联样式:Tailwind遍历 React 元素树(mapReactTree),收集所有className拆分出的类名,通过setupTailwind生成样式表,再用cloneElementWithInlinedStyles将可内联规则逐元素克隆为style属性;
  2. 媒体查询被提取到<head>的<style>标签:不可内联的规则(如媒体查询)由sanitizeNonInlinableRules清洗后,在遇到<head>元素时注入<style>(见 tailwind.tsx)。若存在需要<head>的类却找不到<head>,组件会直接抛错提示你移动<Head />;
  3. CSS 变量被解析:getCustomProperties提取自定义属性并在内联时解析;
  4. RGB 颜色语法被规范化:downlevelForEmailClients将颜色值降级为邮件客户端兼容的形式。

2.3 使用注意事项

  • 始终使用pixelBasedPreset:邮件客户端不支持rem单位。该预设(定义于 tailwind.tsx)将fontSize与spacing全部替换为像素值(例如text-base为16px/24px、p-4为16px),确保字号与间距在客户端渲染一致;
  • 自定义 config 是可选的:默认配置已足够好用,仅在需要品牌色等定制时再extend;
  • 避免响应式类(sm:、md:、lg:):这些断点类在主流邮件客户端支持有限且不可靠,请勿依赖。

三、结构型组件

3.1 Html:邮件根包裹

始终作为最外层组件使用。源码(html.tsx)中lang默认"en"、dir默认"ltr"。

import { Html, Tailwind, pixelBasedPreset } from 'react-email'; <Html lang="en" dir="ltr"> <Tailwind config={{ presets: [pixelBasedPreset] }}> {/* email content */} </Tailwind> </Html>

Props:

  • lang—— 语言代码(如"en"、"es"、"fr");
  • dir—— 文本方向("ltr"或"rtl")。

3.2 Head:文档级元素容器

存放style、meta、title等与文档相关的头部元素。注意要放在<Tailwind>内部——因为 Tailwind 需要在此注入媒体查询样式(若缺<head>会抛错)。

import { Head } from 'react-email'; <Head> <title>Email Title</title> </Head>

3.3 Body:正文包裹

import { Body } from 'react-email'; <Body className="bg-gray-100 font-sans"> {/* email content */} </Body>

3.4 Container:水平居中容器

最大宽度约束为37.5em(约 600px),源码在 container.tsx 中体现为style={{ maxWidth: '37.5em', ...tableStyle }},同时自动设置align="center"、width="100%"。实现上还做了一个巧妙的兼容处理:把 padding 相关样式拆到内部<td>上,以改善 Klaviyo 与 Outlook 的兼容性(container.tsx)。

import { Container } from 'react-email'; <Container className="max-w-xl mx-auto p-5"> {/* centered content */} </Container>

3.5 Section:可组合行列的区块

import { Section } from 'react-email'; <Section className="p-5 bg-white"> {/* section content */} </Section>

无障碍说明:<Section>、<Row>、<Container>及<Markdown>生成的表格默认渲染为<table role="presentation">,这样屏幕阅读器不会把它们当作数据表格播报。如果你直接手写裸<table>做布局,请自行加上role="presentation"。

3.6 Row & Column:横纵布局组合

Row横向排布内容区域,Column纵向分隔;Column必须配合Row使用。

import { Section, Row, Column } from 'react-email'; <Section> <Row> <Column className="w-1/2 p-2 align-top"> Left column content </Column> <Column className="w-1/2 p-2 align-top"> Right column content </Column> </Row> </Section>

Column 宽度要点:

  • 使用百分比宽度(如w-1/2、w-1/3);
  • 或使用 Tailwind 宽度工具类;
  • 各列宽度之和应等于 100% 或容器宽度。

四、内容型组件

4.1 Preview:收件箱预览文本

显示在收件人收件箱中的预览文字。

import { Preview } from 'react-email'; <Preview>Welcome to our platform - Get started today!</Preview>

最佳实践:

  • 控制在 140 字符以内;
  • 内容要吸引人、有行动导向;
  • 始终作为<Body>内的第一个元素。

4.2 Heading:标题文本(h1–h6)

import { Heading } from 'react-email'; <Heading as="h1" className="text-2xl font-bold text-gray-800 mb-4"> Welcome to Acme </Heading> <Heading as="h2" className="text-xl font-semibold text-gray-600 mb-3"> Getting Started </Heading>

Props:as—— HTML 标题级别("h1"至"h6")。

4.3 Text:文本块

import { Text } from 'react-email'; <Text className="text-base leading-6 text-gray-800 my-4"> Your paragraph content here. </Text>

4.4 Button:按钮化链接(含 Outlook 兼容)

按钮本质上是一个带样式的<a>链接,源码在 button.tsx 中实现了针对 Outlook 的复杂兼容:

  • 通过msoPaddingAlt: '0px'让 Word 渲染引擎忽略 CSS padding 造成的高度问题;
  • 用mso-text-raise(pxToPt计算)微调文本垂直位置;
  • 用mso-font-width配合零宽字符&#8202;模拟左右内边距——因为 Outlook 的mso-font-width不允许超过 500%,实现会通过computeFontWidthAndSpaceCount自动计算需要重复的空白字符数量(button.tsx)。
import { Button } from 'react-email'; <Button href="https://example.com/verify" target="_blank" className="bg-blue-600 text-white px-5 py-3 rounded block text-center no-underline font-medium box-border" > Verify Email Address </Button>

Props:

  • href(必填)—— 链接目标 URL;
  • target—— 默认"_blank"。

样式技巧:

  • 用block实现通栏按钮;
  • 用text-center居中按钮文本;
  • 加no-underline去除下划线。

4.5 Link:超链接

import { Link } from 'react-email'; <Link href="https://example.com" target="_blank" className="text-blue-600 underline"> Visit our website </Link>

Props:

  • href(必填);
  • target—— 默认"_blank"。

4.6 Img:图片

import { Img } from 'react-email'; <Img src="https://example.com/logo.png" alt="Company Logo" width="150" height="50" className="block mx-auto" />

Props:

  • src(必填)—— 图片 URL(必须是绝对地址);
  • alt—— 无障碍替代文本(默认"";对有意义的图片应填写描述性内容);
  • width—— 像素宽度;
  • height—— 像素高度。

最佳实践:

  • 始终使用托管在 CDN 上的绝对 URL;
  • 有意义的图片:编写能覆盖用途和关键细节的描述性alt(例如alt="Red bicycle leaning against a brick wall",而不是alt="image");
  • 装饰性图片(分隔线、背景花纹等):显式传alt=""让屏幕阅读器干净地跳过,绝不要省略该属性;
  • 链接中的图片永远不是装饰性的:当<Img>位于<Link>或<Button>内时,alt必须描述链接去向(如alt="View order #123")。空alt=""会让链接失去可访问名称;
  • 指定宽高以防止布局抖动;
  • 使用block类避免间距问题。

4.7 Hr:分割线

import { Hr } from 'react-email'; <Hr className="border-solid border-gray-200 my-5" />

五、专用组件

5.1 CodeBlock:Prism 高亮代码块

基于 Prism.js 实现,支持主题与正则高亮。组件在渲染时对代码按行切分、逐行用Prism.tokenize分词,再按 token 类型(含 alias)匹配主题样式(code-block.tsx)。

import { CodeBlock, dracula } from 'react-email'; const Email = () => { const code = `export default async (req, res) => { try { const html = await render( <EmailTemplate firstName="John" /> ); return NextResponse.json({ html }); } catch (error) { return NextResponse.json({ error }); } }`; return ( <div className="overflow-auto"> <CodeBlock fontFamily="monospace" theme={dracula} language="javascript" code={code} /> </div> ); };

Props:

  • code(必填)—— 要渲染的代码,纯字符串并包含正确的缩进;
  • language(必填)—— 必须是PrismLanguage中定义的语言(如"javascript"、"python"、"typescript")。完整的语言清单见 languages-available.ts,涵盖 300+ 种语言/别名;若语言未注册,组件会抛出CodeBlock: There is no language defined on Prism called ...错误(code-block.tsx);
  • theme(必填)—— 代码块主题,从react-email导入(dracula、github、nord等)。仓库内置主题定义见 themes.ts,包括xonokai、vscDarkPlus、duotoneForest、holiTheme、cb、vs、materialDark、dracula、shadesOfPurple等,每个主题都包含base样式与各 Prism token 类型的配色;
  • fontFamily(可选)—— 代码块字体族(如"monospace"),主要用于覆盖<Font>设置的全局字体;
  • lineNumbers(可选)—— 是否自动生成行号(布尔值,默认false)。

重要提醒:

  • 除非明确要求,否则默认不要使用lineNumbers;
  • 始终用带overflow-auto类的div包裹CodeBlock,避免内边距溢出。

5.2 CodeInline:行内代码

在所有邮件客户端表现一致的行内代码元素。

import { Text, CodeInline } from 'react-email'; <Text className="text-base text-gray-800"> Run <CodeInline className="bg-gray-100 px-1 rounded">npm install</CodeInline> to get started. </Text>

5.3 Markdown:Markdown 转邮件模板

将 Markdown 字符串转换为合法的 react-email 模板代码。支持两种传参方式:子元素children,或直接传childrenprop。

import { Html, Markdown } from 'react-email'; const Email = () => { return ( <Html lang="en" dir="ltr"> <Markdown markdownCustomStyles={{ h1: { color: "red" }, h2: { color: "blue" }, codeInline: { background: "grey" }, }} markdownContainerStyles={{ padding: "12px", border: "solid 1px black", }} >{`# Hello, World!`}</Markdown> {/* OR */} <Markdown children={`# This is a ~~strikethrough~~`} /> </Html> ); };

Props:

  • children(必填)—— Markdown 字符串;
  • markdownCustomStyles—— 针对 HTML 元素(h1、h2、p、a、codeInline等)的样式覆盖;
  • markdownContainerStyles—— 容器 div 的样式。

5.4 Font:邮件字体(支持 Web Font)

生成@font-face与全局字体声明的组件,必须放在<head>内。源码(font.tsx)会同时生成mso-font-alt供 Outlook 识别替代字体,默认fontStyle: 'normal'、fontWeight: 400。

import { Head, Font } from 'react-email'; <Head> <Font fontFamily="Roboto" fallbackFontFamily="Arial, sans-serif" webFont={{ url: "https://fonts.gstatic.com/s/roboto/v27/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2", format: "woff2" }} /> </Head>

Props:

  • fontFamily(必填)—— 字体族名称(注意:不要在这里放多个字体,多字体请用fallbackFontFamily);
  • fallbackFontFamily—— 回退字体,支持字符串或数组,数组顺序即优先级(合法值见 font.tsx 中的FallbackFont类型,如Arial、Helvetica、Verdana、Georgia等);
  • webFont—— 包含url和format的对象;
  • fontStyle—— 默认'normal';
  • fontWeight—— 默认400。

支持的字体格式(FontFormat类型,font.tsx):

  • woff2(推荐)
  • woff
  • truetype
  • opentype
  • 另有embedded-opentype、svg

注意:并非所有邮件客户端都支持 web font,使用前请核对目标客户端的@font-face支持情况。


六、实战组合:一个完整的可复用模板骨架

将上述组件组合起来,即可得到一份结构完整、兼容性良好的邮件模板:

import { Html, Head, Body, Container, Section, Row, Column, Preview, Heading, Text, Button, Link, Img, Hr, Tailwind, pixelBasedPreset, } from 'react-email'; export default function WelcomeEmail() { return ( <Html lang="en" dir="ltr"> <Head> <title>Welcome to Acme</title> </Head> <Tailwind config={{ presets: [pixelBasedPreset] }}> <Body className="bg-gray-100 font-sans"> <Preview>Welcome to Acme - Get started today!</Preview> <Container className="max-w-xl mx-auto p-5"> <Section className="bg-white p-5 rounded-lg"> <Img src="https://cdn.example.com/logo.png" alt="Acme logo" width="150" height="50" className="block mx-auto" /> <Heading as="h1" className="text-2xl font-bold text-gray-800 mb-4 text-center"> Welcome aboard! </Heading> <Row> <Column className="w-1/2 p-2 align-top"> <Text className="text-base text-gray-700"> Feature one highlights. </Text> <Link href="https://example.com/features" className="text-blue-600 underline"> Learn more </Link> </Column> <Column className="w-1/2 p-2 align-top"> <Text className="text-base text-gray-700"> Feature two highlights. </Text> <Link href="https://example.com/pricing" className="text-blue-600 underline"> See pricing </Link> </Column> </Row> <Hr className="border-solid border-gray-200 my-5" /> <Button href="https://example.com/get-started" className="bg-blue-600 text-white px-6 py-3 rounded block text-center no-underline font-medium box-border" > Get Started </Button> </Section> </Container> </Body> </Tailwind> </Html> ); }

要点回顾:

  1. Preview紧跟<Body>之后,控制收件箱预览文案;
  2. Container负责整体水平居中,Section+Row+Column负责内部多栏布局;
  3. Button内置 Outlook 兼容逻辑,无需额外 hack;
  4. 所有图片提供描述性alt,链接内图片的alt说明链接去向;
  5. 全部样式类均基于pixelBasedPreset的像素体系,避免rem兼容问题。

七、延伸阅读

  • 完整组件参考原文:skills/react-email/references/COMPONENTS.md
  • 组件实现源码目录:packages/react-email/src/components(每个子目录对应一个组件的index.ts与实现文件)
  • 组件导出入口:packages/react-email/src/components/index.ts
  • Tailwind 处理流水线核心实现:tailwind.tsx
  • CodeBlock 内置主题:themes.ts;支持语言清单:languages-available.ts
  • 仓库内置的大量真实邮件示例(覆盖激活、密码重置、订单确认、订阅更新等场景)可作参考:apps/demo/emails

【免费下载链接】react-email💌 Build and send emails using React项目地址: https://gitcode.com/GitHub_Trending/re/react-email

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/30 2:42:24

WeKan 设计演进史:与 Trello、Jira 的功能借鉴对比与技术溯源

WeKan 设计演进史&#xff1a;与 Trello、Jira 的功能借鉴对比与技术溯源 【免费下载链接】wekan The Open Source kanban, built with Meteor. GitHub issues/PRs are only for FLOSS Developers, not for support, support is at https://wekan.fi/commercial-support/ . PR …

作者头像 李华
网站建设 2026/10/30 2:42:26

Vue 3豆瓣仿制项目:工程化实战与移动端适配全解析

简介&#xff1a;这是一份面向前端初学者与Vue.js入门学习者的豆瓣仿制网站实训项目源码&#xff0c;聚焦单页应用开发全流程实践&#xff0c;帮助开发者系统掌握Vue核心生态与工程化能力。资源共51个文件&#xff0c;包含11个功能完备的Vue组件&#xff08;如HomeView、Detail…

作者头像 李华
网站建设 2026/10/30 2:42:28

一条命令禁用 Windows 11 的 AI 功能:Copilot 和 Recall 彻底移除

一条命令禁用 Windows 11 的 AI 功能&#xff1a;Copilot 和 Recall 彻底移除 【免费下载链接】RemoveWindowsAI Force Remove Copilot, Recall and More in Windows 11 项目地址: https://gitcode.com/GitHub_Trending/re/RemoveWindowsAI RemoveWindowsAI 是一个在 Wi…

作者头像 李华
网站建设 2026/10/30 2:42:28

Java求职招聘系统实战:从Maven构建到Spring Boot全栈实现

简介&#xff1a;这份压缩包是一套基于Java实现的求职招聘系统毕业设计源码&#xff0c;随包附带SQL数据库文件&#xff0c;主要面向计算机相关专业学生&#xff0c;用于毕业设计选题参考、课程设计或者求职前的项目复盘。资源共54个文件&#xff0c;其中41个Java源文件承载系统…

作者头像 李华
网站建设 2026/10/30 2:42:28

大模型时代的GEO优化:变革流量入口与提升品牌曝光

1. 大模型时代流量入口的变革与GEO优化机遇过去十年间&#xff0c;我们经历了从PC搜索到移动搜索的流量入口迁移&#xff0c;而现在&#xff0c;大模型正在引发新一轮的流量入口革命。根据最新行业数据显示&#xff0c;超过60%的用户开始习惯通过对话式AI获取信息&#xff0c;而…

作者头像 李华