Remotion 视频布局排版指南:安全区、字号基线与"视频优先"构图法则
【免费下载链接】remotion🎥 Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion
导读
在 Remotion 中用 React 写视频时,最容易犯的错误是把一帧画面当作网页来排版。本指南围绕 remotion-create 技能中的 video-layout.md 布局规则展开,它是创建新视频组合(Composition)时"设计而非写页面"的第一手规范。读完本文,你将掌握视频构图的核心决策顺序、1080px 基准画布下的安全区与最小字号数值、随画布宽度等比缩放的换算方法,以及如何用 Remotion 的<AbsoluteFill>、useVideoConfig与文本测量工具把这些规则落地成像素精确的代码。
一、这份规范在 Remotion 技能体系中的位置
video-layout.md 并非独立文档,而是 remotion-create 技能(SKILL.md)"Designing a video"环节明确要求遵循的两份规范之一:
Follow Remotion React Markup Best Practices and Video Layout Rules for video-first layout and text sizing guidance.
也就是说,新建视频项目的推荐流程是:先按 SKILL.md 脚手架创建工程,再按照 remotion-markup 技能 编写 React 标记,最后用 video-layout.md 的规则做"视频优先"的版式与字号校正。对应的完整操作链包括:
npx create-video@latest --yes --blank --no-tailwind my-video cd my-video npm i开发中可在 Remotion Studio 中即时预览构图:
npx remotion studio --no-open渲染成品则使用:
npx remotion render布局规则正是在"预览→渲染"之前对每一帧画面的质量把关,属于创作流程中的设计审查层。
二、视频不是网页:围绕"第一眼焦点"构图
video-layout.md 开门见山第一条原则是You are designing a video, not a webpage.这句话背后是两种媒介的本质差异:
- 网页用户会在页面上停留、滚动、扫描多个模块,排版可以容纳并列的多条信息;
- 视频中的每一帧通常只在观众眼前停留零点几秒,画面一旦推进或切换,阅读时间就结束。
因此规范给出两条可操作的决策:
- 决定每一场景中观众首先注意到什么(
Decide what the viewer should notice first in each scene); - 让画面围绕这一个事物构建(
Build the frame around that one thing),并且Do not add redundant elements(不添加冗余元素)。
在实践中,"画面围绕一个焦点"意味着:同一屏内不宜同时出现大标题、副标题、说明文字、Logo、统计数据和装饰图形;多余元素会把观众的注意力从唯一的焦点上稀释掉。实现上,Remotion 的典型做法是用层级化组件组织画面——焦点内容放在最高层,其他元素依据其与焦点的关系决定是否保留或弱化。
从源码可以印证 Remotion 为这种层级化叠加提供的原语:<AbsoluteFill>是"绝对定位、占满画布、flex 布局"的容器组件(packages/core/src/AbsoluteFillElement.tsx),其内部AbsoluteFillInner会把自身包进一个layout="none"的<Sequence>中(packages/core/src/AbsoluteFill.tsx),从而同时具备时间轴控制能力。多个<AbsoluteFill>天然支持背景层、焦点层、前景层叠加,构图时应该主动删掉那些不服务于单一焦点的层。
三、安全区设计:1080px 画布的明确数值
规范为安全区给出了可执行的硬性基准(针对 1080px 宽的画面):
- 关键文字距画面左右两侧至少 80px;
- 关键文字距画面顶部与底部至少 100px。
Keep important content inside a generous safe area. For 1080px-wide videos, keep key text at least 80px from the sides and 100px from the top and bottom.安全区之所以"慷慨"(generous),是因为视频成品几乎总会经历二次裁切或遮挡:平台播放器的时间轴与控件悬浮在画面边缘、竖屏信息流会圆角裁切、不同设备存在 overscan/安全区裁剪,而这些都属于渲染引擎无法控制的展示环节。因此设计时必须把关键内容收缩在安全区内,宁可留白,不可压线。
换算到一块 1080×1080 的方形画布上,安全区即中央920px × 880px的矩形区域;无论下方左右留多少装饰,标题与正文的包围盒都应落在这个矩形内。
用 AbsoluteFill 落实安全区
最直接的实现方式是把安全区内边距做成常量并应用到根布局:
// 1080px 基准画布 export const SAFE_AREA = { horizontal: 80, // 左右至少 80px vertical: 100, // 上下至少 100px }; import {AbsoluteFill} from 'remotion'; export const TitleCard: React.FC = () => { return ( <AbsoluteFill style={{ padding: `${SAFE_AREA.vertical}px ${SAFE_AREA.horizontal}px`, justifyContent: 'center', }} > <h1>主标题保持在安全区内</h1> </AbsoluteFill> ); };<AbsoluteFill>默认样式为position: absolute、四周0、宽高100%、flex-direction: column(见 packages/core/src/AbsoluteFillElement.tsx),因此直接在它上面设置padding,就等价于给整个画面加了一圈"安全区护栏"。
四、字号基线:主标题与说明文字的最小值
规范针对 1080px 宽画布给出的是"粗略最小值"(rough minimums),原文表述很克制,值得逐字理解:
- 主标题(Main headline):84px 起
- 重要辅助文字(Important supporting text):44px 起
For 1080px-wide compositions, use these rough minimums: - Main headline: 84px - Important supporting text: 44px之所以强调"rough minimums",是因为字号必须结合文本长度与内容总量再微调:短标题可以更大以增强冲击力,长说明则要在"不小于 44px"与"不越出安全区"之间做平衡。这两个数值的设定逻辑是:1080px 宽的画面在常规播放尺寸下,84px 的字号大约占画面宽度 7.8%,能保证标题跨屏可读;44px 的辅助文字约为画面宽度 4.1%,是远距离观看仍能辨认的下限。低于这两个值的文字,在手机竖屏、横屏投屏等实际观看距离下都容易变得难以辨认。
标题层级建议参照如下比例关系组织(单位为 px,基于 1080 宽):
| 文本角色 | 建议字号 | 相对主标题 |
|---|---|---|
| 主标题 | 84 | 1× |
| 重要辅助文字 | 44 | ≈ 0.52× |
| 次要标注(时间、脚注、字幕辅助) | 不超过辅助文字 | < 0.52× |
需要留意:Remotion 的字体渲染以实际像素为准,px字号会直接映射到合成帧的真实像素,因此上述数值就是最终渲染帧中的物理尺寸,不存在网页中的 rem/视口缩放折损。
五、随画布宽度等比缩放:换算公式与速查表
规范最后一条是关键通则:Scale those values with the composition width.安全区与字号全部以 1080px 宽为基准,画布一旦改变宽度,所有数值都应等比缩放,从而保证文本在画面中所占比例恒定。
缩放公式非常简单:
目标值 = 基准值 × (画布宽度 / 1080)例如主标题:84 × (width / 1080);辅助文字:44 × (width / 1080);左右安全区:80 × (width / 1080);上下安全区:100 × (width / 1080)。
常见画布速查表
| 画布宽度 | 左右安全区 | 上下安全区 | 主标题最小 | 辅助文字最小 |
|---|---|---|---|---|
| 720 | 53 | 67 | 56 | 29 |
| 1080 | 80 | 100 | 84 | 44 |
| 1280 | 95 | 119 | 100 | 52 |
| 1920 | 142 | 178 | 149 | 78 |
表中的 1920×1080 是典型的横屏成品(如packages/skills中地图渲染用例常见的 1920×1080 构图),此时主标题约为 149px;而 1080×1920 竖屏视频仍以 1080 为宽度基准,直接套用 1080 一行的数值即可。
用 useVideoConfig 自动缩放
Remotion 在 packages/core/src/index.ts 中导出了useVideoConfig,它能读取当前组合的width/height等配置。把基准值定义为常量、用宽度实时换算,是最稳妥的实现:
import {AbsoluteFill, useVideoConfig} from 'remotion'; // 1080px 基准下的布局规范 const TYPE_SCALE = { headline: 84, supporting: 44, safeX: 80, safeY: 100, } as const; const scale = (base: number, width: number) => Math.round((base * width) / 1080); export const Layout: React.FC = () => { const {width} = useVideoConfig(); const headline = scale(TYPE_SCALE.headline, width); const supporting = scale(TYPE_SCALE.supporting, width); const padX = scale(TYPE_SCALE.safeX, width); const padY = scale(TYPE_SCALE.safeY, width); return ( <AbsoluteFill style={{ padding: `${padY}px ${padX}px`, justifyContent: 'center', alignItems: 'flex-start', }} > <h1 style={{fontSize: headline, margin: 0}}>主标题</h1> <p style={{fontSize: supporting, marginTop: supporting / 2}}> 重要说明文字,同样落在安全区内。 </p> </AbsoluteFill> ); };这样同一套代码注册为不同尺寸的<Composition>(宽度不同),排版会自动保持相同视觉比例,避免"换了画布字号就失控"的问题。组合的画布尺寸由<Composition>的width/height/fps/durationInFrames定义,参数写法可参考 compositions.md:
import {Composition} from 'remotion'; import {Layout} from './Layout'; export const RemotionRoot: React.FC = () => ( <> <Composition id="SquarePromo" component={Layout} durationInFrames={150} fps={30} width={1080} height={1080} /> <Composition id="WidePromo" component={Layout} durationInFrames={150} fps={30} width={1920} height={1080} /> </> );六、把字号规范做到像素级:文本测量与兜底
字号给出的是"最小值",而真正严格的布局还需要验证"文本最终没有溢出安全区"。Remotion 生态为此提供了文本测量工具集 packages/layout-utils,它在渲染前就能算出字符串在给定字族、字重、字号下的实际宽度:
measureText:测量单行文本渲染宽度;fitText:根据容器宽度反向计算出刚好放得下的fontSize,其核心思路是用 100px 采样字号测量文本宽度,再按比例反推目标字号(fit-text.ts);fitTextOnNLines:把文本限制在 N 行内并计算合适字号。
例如某段长标题既要满足"不小于 84px",又必须在安全区宽度内显示,就可以先用安全区宽度约束测量,必要时让文案换行或使用fitText收紧字号,实现"下限与溢出"两个约束同时满足。典型用法形如:
import {fitText} from '@remotion/layout-utils'; import {useVideoConfig} from 'remotion'; // 仅示意:withinWidth 应取安全区可用宽度 const {fontSize} = fitText({ text: 'Your headline', withinWidth: safeWidth, fontFamily: 'Inter', });文本测量类库在仓库中有配套测试(如packages/layout-utils/src/test/下的用例),用于验证fitText/fitTextOnNLines在超长不可断单词等边界情况下的行为,可作为"布局规则需要被程序化验证"的参照。
七、与 TailwindCSS 的联动注意点
视频项目常引入 TailwindCSS 做原子化样式。此时有两个约束需要与字号/安全区规范配合:
- 字体与间距类可用,但动画类禁用。同仓库 tailwind.md 明确规定:不要使用
transition-*或animate-*类——Remotion 的所有动画都应由useCurrentFrame()钩子按帧驱动,这样渲染器才能在每一帧拿到确定值并逐帧导出,而不是依赖浏览器 CSS 过渡的运行时行为。 - Tailwind 的任意值语法天然适合本规范。例如
text-[84px]、px-[80px]、pt-[100px]可以直接映射 1080 基准的数值,与安全区常量一一对应,便于在设计稿与代码间对齐。
仓库中 Tailwind 的接入与模板(如packages/tailwind、packages/tailwind-v4)可供参考;若项目明确要求 Tailwind,应保证其已正确启用后再使用上述任意值类。
八、规范速查清单
video-layout.md 的全部规则可收敛为五条可自查清单,建议在提交渲染前逐条过一遍:
- 媒介意识:我在设计视频,不是网页——画面不承载"慢慢浏览"的任务;
- 单一焦点:每个场景先确定观众第一眼看到什么,画面围绕它构建;
- 安全区:1080px 宽画布下,关键文字距左右 ≥ 80px、距上下 ≥ 100px;
- 零冗余:删除一切不服务于焦点的重复或装饰元素;
- 字号下限:1080px 宽画布下主标题 ≥ 84px、重要辅助文字 ≥ 44px;画布宽度变化时,上述全部数值按
宽度/1080比例等比缩放。
结语
video-layout.md 虽然只有寥寥数行,却浓缩了 Remotion 项目"用代码排版视频"的设计内核:以单一视觉焦点组织画面、以慷慨的安全区保护关键信息、以明确的字号下限保障远距可读性、以画布宽度为唯一缩放基准。配合仓库中的<AbsoluteFill>层级原语、useVideoConfig运行时画布信息、layout-utils 的文本测量工具以及 remotion-markup 技能 的配套规范,这些看似简单的数值就能转化为稳定、可复现、逐帧精确的渲染结果。把这份清单当作每次新建组合时的默认自检,是让 Remotion 视频从"像网页"走向"像成片"的第一步。
【免费下载链接】remotion🎥 Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考