ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Remotion Studio 无指针交互规范:hoverable 类、CSS 悬停与键盘焦点的完整实践

Remotion Studio 无指针交互规范:hoverable 类、CSS 悬停与键盘焦点的完整实践 Remotion Studio 无指针交互规范hoverable 类、CSS 悬停与键盘焦点的完整实践【免费下载链接】remotion Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion本文基于 Remotion 仓库中的.agents/skills/no-pointer/SKILL.md技能文档系统讲解 Remotion Studio 内部统一的无指针pointerless交互规范可点击控件一律使用cursor: default悬停效果全部由 CSS:hover驱动而非 React 状态且仅对键盘导航显示焦点装饰。读完本文你将掌握如何在 Studio 代码中正确使用HOVERABLE_CLASS_NAME、hoverableStyle()、FOCUS_VISIBLE_ONLY_CLASS_NAME这套工具理解其背后的 CSS 变量机制、选择器优先级技巧与 iframe 环境下的 hover 可靠性问题并能按照文档给出的标准完成逐项验证。规范速览四条核心约定该技能文档面向新增或修改 Studio 中按钮、链接等可点击控件的场景给出四条硬性约定光标设置cursor: default不要使用cursor: pointer。悬停纯视觉的悬停样式必须通过 hoverable.ts 中的HOVERABLE_CLASS_NAME和hoverableStyle()驱动禁止为颜色或背景变化引入 React hover 状态。背景除非周围组件已经在使用共享的背景悬停约定否则保持背景不变纯文字操作text-only action的idleBackground与hoverBackground都应使用TRANSPARENT。文字颜色空闲态使用LIGHT_TEXT#A6A7A9悬停态使用WHITEwhite图标与嵌套文本必须跟随同一状态。如果 Studio 的 CSS reset 阻断了颜色继承需要检查真正绘制像素的那个元素。为什么禁用cursor: pointer与 React hover 状态规范的第一条看似反直觉——Web 上可点击元素通常都显示手型光标。但 Studio 选择保持default光标是为了让界面视觉更克制、避免处处像链接的噪声。这一点在源码中得到印证通用 Button 组件 的基础样式中直接写死了cursor: default见 Button.tsx#L14-L24侧边栏条目 CompositionSelectorItem 的itemStyle同样是cursor: default见 CompositionSelectorItem.tsx#L63-L82。禁用 React hover 状态的原因则更技术性hoverable.ts 文件顶部的注释明确指出——当 Studio 运行在iframe中如 Browser Studio 场景时浏览器在指针离开 iframe 边界时可能丢失pointerleave事件导致基于状态驱动的悬停背景永久卡住而 CSS:hover由浏览器自身维护具备自我纠正能力见 hoverable.ts#L4-L9。因此视觉归 CSS行为归 JS是这条规范的底层逻辑。hoverable 机制源码解析类名常量与 CSS 变量hoverable.ts 导出四个类名常量HOVERABLE_CLASS_NAME__remotion-hoverable标记一个可悬停元素HOVER_GROUP_CLASS_NAME__remotion-hover-group悬停组的外层HOVER_GROUP_REVEAL_CLASS_NAME__remotion-hover-group-reveal悬停组内悬停才显现的内容FOCUS_VISIBLE_ONLY_CLASS_NAME__remotion-focus-visible-only焦点仅在键盘导航时可见。hoverableStyle()接收idleBackground、hoverBackground、idleColor、hoverColor四个字符串参数返回一个 React 内联样式对象把它们写入四个 CSS 自定义属性见 hoverable.ts#L27-L44CSS 变量来源参数作用--remotion-hoverable-bgidleBackground空闲态背景色--remotion-hoverable-hover-bghoverBackground悬停态背景色--remotion-hoverable-coloridleColor空闲态文字色--remotion-hoverable-hover-colorhoverColor悬停态文字色文件还导出NO_HOVER_BACKGROUND_STYLE仅设置悬停背景变量为TRANSPARENT以及一个实用技巧如需禁用某个控件的悬停效果例如禁用态把空闲值同时传给 hover 参数即可源码注释对此有明确说明见 hoverable.ts#L21-L26。注入的全局 CSS 及其优先级技巧makeHoverableCSS()hoverable.ts#L56-L92生成的规则由 inject-css.ts 在全局样式表末尾统一注入见 inject-css.ts#L168核心规则如下.__remotion-hoverable.__remotion-hoverable { background-color: var(--remotion-hoverable-bg, transparent); } .__remotion-hoverable.__remotion-hoverable, .__remotion-hoverable.__remotion-hoverable * { color: var(--remotion-hoverable-color, inherit); }其中包含三个值得注意的设计双写类名提升特异性选择器写作.x.x是为了压过.css-reset, .css-reset *这类对每个后代都强制设置color和background的 reset 规则——两份样式表的注入顺序并不可控靠特异性而非注入顺序保证生效见 hoverable.ts#L46-L54 的注释。*后代选择器重建继承color变量同时应用到元素本身及其所有后代使嵌套文本与基于currentColor的图标自动跟随悬停状态。这正是 SKILL.md 要求图标和嵌套文本必须跟随同一状态的实现依据。悬停规则限定在media (hover: hover)内只在支持真实悬停的设备鼠标等精确指针上生效避免触屏设备出现粘住的悬停态。此外还有一条防止嵌套悬停串扰的规则外层 hoverable 处于悬停时内部未处于悬停的嵌套 hoverable 仍保持其空闲颜色见 hoverable.ts#L76-L82。悬停组规则则用opacity0/1 切换实现悬停才显现的子元素例如侧边栏 Composition 条目上悬停时才浮现的上下文菜单按钮HOVER_GROUP_CLASS_NAMECompositionContextButton的组合见 CompositionSelectorItem.tsx#L774-L808。键盘焦点样式FOCUS_VISIBLE_ONLYSKILL.md 的 Focus styling 小节要求移除默认 outline 与指针聚焦时的阴影但必须保留键盘焦点指示器。实现方式是在控件上同时添加HOVERABLE_CLASS_NAME与FOCUS_VISIBLE_ONLY_CLASS_NAME共享类实现如下模式.__remotion-focus-visible-only:focus { outline: none; box-shadow: none; } .__remotion-focus-visible-only:focus-visible { box-shadow: ${FOCUS_BOX_SHADOW}; }这条规则已在 Studio 的全局 CSS 中落地inject-css.ts#L73-L88 对.__remotion-focus-visible-only:focus清空outline与box-shadow对:focus-visible应用标准的FOCUS_BOX_SHADOW。FOCUS_BOX_SHADOW 的具体值FOCUS_BOX_SHADOW定义在 colors.ts#L107-L109是一个由四段inset阴影拼成的内描边框效果等价于 1px 的#555边框但不会撑开布局export const FOCUS_BOX_SHADOW inset 1px 1px #555, inset -1px -1px #555, inset 1px -1px #555, inset -1px 1px #555;同一文件还定义了规范引用的两个颜色常量LIGHT_TEXT #A6A7A9colors.ts#L18与WHITE whitecolors.ts#L2。文档同时强调两条禁令永远不要移除:focus-visible指示器键盘可访问性底线以及未可发现的隐藏操作不要进入 Tab 顺序。仓库中 InlineAction 展示了后一条的落地方式它通过useZIndex()状态读取统一的tabIndexInlineAction.tsx#L93由状态层集中决定哪些控件可被 Tab 到达而不是每个组件自行硬编码。真实组件中的完整用法Button规范的标准样例Button.tsx 是这套约定最完整的范例。它把外部传入的style?.backgroundColor/style?.color作为空闲值未提供时使用TRANSPARENT/LIGHT_TEXT悬停背景在未指定时取共享约定getBackgroundFromHoverState({hovered: true, selected: false})即WHITE_ALPHA_06悬停文字色为WHITEdisabled时把 hover 值折叠回 idle 值即前文禁用悬停技巧// 来自 packages/studio/src/components/Button.tsx节选 className{${HOVERABLE_CLASS_NAME} ${FOCUS_VISIBLE_ONLY_CLASS_NAME}} style{{ ...button, ...hoverableStyle({ idleBackground, hoverBackground: disabled || style?.backgroundColor ? idleBackground : getBackgroundFromHoverState({hovered: true, selected: false}), idleColor, hoverColor: disabled || style?.color ? idleColor : WHITE, }), }}注意className中两个类名并排出现这正是 SKILL.md 对焦点小节的要求且cursor: default在基础样式与按钮容器样式中各写了一次见 Button.tsx#L77-L88。InlineAction纯文字操作的透明背景对于纯文字/图标操作InlineAction.tsx#L56-L78 则完全按 SKILL.md 第三条约定idleBackground使用TRANSPARENTidleColor/hoverColor默认为LIGHT_TEXT/WHITE且渲染子内容时统一传入CURRENT_COLORInlineAction.tsx#L97让图标颜色交给 hoverable 的*继承规则处理。CompositionSelectorItem背景保持共享约定侧边栏条目属于周围组件已使用共享背景悬停约定的情形因此 CompositionSelectorItem.tsx#L294-L312 中idleBackground随选中态取值WHITE_ALPHA_06/TRANSPARENThoverBackground使用WHITE_ALPHA_06idleColor在选中时为WHITE、否则LIGHT_TEXThoverColor恒为WHITE——与规范允许的背景例外完全对应。验证清单与本地检查命令SKILL.md 的 Verify 小节要求在运行中的 Studio内检查控件在各状态下的 computed style本文按原文完整继承该清单检查项期望值空闲与悬停时的cursordefault空闲文字颜色rgb(166, 167, 169)即#A6A7A9悬停文字颜色rgb(255, 255, 255)指针聚焦pointer focus无 outline、无 box-shadow键盘Tab聚焦可见标准FOCUS_BOX_SHADOW对涉及 Studio 代码的改动文档要求运行以下两条命令对应仓库的 Turborepo 工作流包名为remotion/studiobunx turbo run make --filterremotion/studio bunx turbo run lint test --filterremotion/studio第一条完成该包的编译产物生成第二条执行 Lint 与测试改动前后可用同一组命令确认没有引入回归。适用边界与小结需要说明适用前提这套规范是Remotion Studiopackages/studio前端交互层的内部约定服务于深色主题rgb(31, 36, 40)背景见 colors.ts#L12下的浏览器 UI以及以 Browser Studio 形式嵌入iframe的运行环境它不适用于用 Remotion 编写的视频内容组件Composition内的画面元素。从 Button.tsx、InlineAction.tsx、CompositionSelectorItem.tsx 等十余个使用HOVERABLE_CLASS_NAME的组件看该约定已在 Studio 的按钮、行内操作、侧边栏条目、时间轴控件等处广泛落地。小结遵循 no-pointer 规范时记住三件事即可——光标永远default颜色与背景的两种状态通过hoverableStyle()写入 CSS 变量、由 hoverable.ts 生成的全局 CSS 消费类名上同时挂HOVERABLE_CLASS_NAME与FOCUS_VISIBLE_ONLY_CLASS_NAME把鼠标点击无装饰、键盘 Tab 有FOCUS_BOX_SHADOW交给:focus/:focus-visible选择器完成。最后按上表的五态清单在运行中的 Studio 里逐项核对 computed style并以两条bunx turbo命令收尾验证。技能入口文件为 .agents/skills/no-pointer/SKILL.md其 Agent 配置含默认提示词位于 .agents/skills/no-pointer/agents/openai.yaml。【免费下载链接】remotion Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表