题干与适用场景
一个帮助面板或折叠卡片默认只显示标题,展开后高度由内容决定。产品希望从固定高度平滑过渡到 auto、max-content 或 fit-content,同时保持键盘、屏幕阅读器和旧浏览器体验。请说明你会如何使用 interpolate-size 或 calc-size(),以及如何验证收益和风险。
这道题适合前端、设计系统和性能岗位。MDN 将 interpolate-size 标为非 Baseline 的有限支持特性;它需要显式启用 intrinsic size 插值,不能把它当成所有浏览器都默认支持的动画捷径。
面试官考察点
- 是否理解长度值与 intrinsic size 关键字之间的插值边界。
- 是否知道
interpolate-size会继承,以及全局启用可能影响后代。 - 是否区分
interpolate-size与calc-size()的职责。 - 是否保留无支持浏览器的静态可用状态和减少动效偏好。
- 是否验证内容变化、布局抖动、焦点顺序与性能,而不是只看演示视频。
回答前需要澄清的问题
先确认:
- 目标浏览器和最低版本是什么,是否允许有限支持的渐进增强?
- 展开内容是可折叠语义,还是必须始终存在于文档和辅助技术树中?
- 动画对象是高度、宽度还是两者,内容是否会在动画期间异步变化?
- 需要支持
prefers-reduced-motion、键盘操作、焦点回收和中途反向播放吗?
若没有补充,可以假设目标是现代 Chromium、Firefox 和 Safari 的差异化支持,旧浏览器必须保持可用但可以没有平滑 intrinsic size 动画。
30 秒回答框架
我会先把折叠状态做成语义正确的按钮和内容区域,再把动画视为渐进增强。支持的浏览器在局部容器启用 interpolate-size: allow-keywords,从一个明确的长度过渡到 max-content 或 auto;需要参与尺寸计算时再评估 calc-size()。不支持时使用静态展开、预设最大高度或无动画切换,不能依赖动画完成业务状态。最后用键盘、屏幕阅读器、减少动效、内容变长、中途反向和真实性能测试验证。
分步骤深入解答
1. 先建立语义状态
按钮使用 aria-expanded 指向内容区域,内容的隐藏策略与产品语义一致。动画只改变视觉和布局过渡,不负责决定是否可操作。焦点不能因为折叠突然丢失;关闭后若焦点仍在隐藏区域,应移动到触发按钮或明确的下一个可见控件。
2. 选择插值方式
interpolate-size: allow-keywords 允许长度百分比值与 intrinsic size 值之间插值,但不能直接让两个 intrinsic size 关键字互相动画。calc-size() 适合需要对 intrinsic size 做计算的场景;普通 calc() 不能计算 auto、max-content 等值。先用局部容器启用,避免根元素继承到不相关组件。
3. 处理内容与布局边界
动画容器应有清晰的 overflow、最大尺寸和定位边界。异步加载内容会改变目标尺寸,需决定是等待内容稳定、重新计算,还是在动画完成后更新。嵌套网格、绝对定位和滚动容器可能让 intrinsic size 与预期不同,必须在真实组件组合中测量。
4. 兼容性与回退
检测支持后才启用增强规则;旧浏览器继续使用静态高度、max-height 近似或直接切换。回退必须保留内容可读、按钮可用、链接可聚焦和关闭状态可理解。不要用 JavaScript 强行测量每一帧来掩盖基础 CSS 不支持,因为这会引入同步布局和更多状态分支。
5. 动效偏好与交互
在 prefers-reduced-motion: reduce 下缩短或移除过渡,但保留状态变化和焦点逻辑。键盘 Enter、Space、Tab 和 Escape 的行为要与组件规范一致。用户在动画中再次点击时,浏览器应自然反向或跳到新目标,不应留下两个并发动画和错误的 aria-expanded。
6. 验证指标
用真实内容覆盖短文本、长文本、异步错误和多语言换行。记录布局偏移、动画帧丢失、主线程样式与布局时间、交互延迟、焦点可见性和辅助技术结果。对支持与不支持路径做对照,并测试属性被忽略时页面仍然可用。CSS 特性收益必须来自实测,不能把浏览器支持表当成产品性能承诺。
高质量示范回答
我会把面板实现成语义按钮加内容区域,aria-expanded 是状态来源,CSS 动画只是增强。支持的浏览器在面板容器上局部设置 interpolate-size: allow-keywords,从一个明确的折叠长度过渡到 max-content 或 auto;如果需要对 intrinsic size 做额外计算,再使用 calc-size()。我不会在根元素盲目打开,因为该属性会继承。
不支持时,面板仍能直接展开或使用有上限的 max-height,内容和焦点不依赖动画完成。减少动效时移除过渡但保留状态。动画中内容异步变更时,我会选择等待稳定、重新计算或跳到最终状态,并保证按钮状态只更新一次。
验证包括长短内容、多语言、键盘、屏幕阅读器、焦点回收、中途反向、旧浏览器和 prefers-reduced-motion。性能上比较样式、布局、帧率、布局偏移和交互延迟;若支持路径带来抖动或兼容性问题,就缩小选择器范围或关闭增强,而不让 CSS 实验影响基础可用性。
常见错误
- 把 intrinsic size 关键字当成可以互相插值的普通数字。
- 在根元素设置
interpolate-size,让无关组件继承意外行为。 - 把
calc-size()当成普通calc()的替代品,却没有说明适用边界。 - 只在支持浏览器测试,忽略属性被丢弃时的内容与焦点。
- 用
max-height的巨大常数掩盖真实高度,导致动画速度和布局结果失真。 - 让 JavaScript 每帧读取布局并写回,制造强制同步布局。
- 忽略减少动效、键盘反向操作和动画中异步内容变化。
- 只展示视觉流畅度,不测 CLS、交互延迟和屏幕阅读器状态。
追问及应对
为什么不能直接从零过渡到 auto?
传统插值需要可计算的数值端点;auto、max-content 等 intrinsic size 不是普通长度。interpolate-size 允许特定长度到 intrinsic size 的插值,但仍受支持范围限制。
什么时候用 calc-size?
当目标尺寸需要在 intrinsic size 基础上继续计算时使用,例如加入固定间距或上限。若只需启用长度与 intrinsic size 的过渡,局部 interpolate-size 更直接。
内容在动画期间变长怎么办?
先定义产品策略:等待数据稳定、重新计算目标,或立即跳到最终状态。无论选择哪种,都要保持可滚动、焦点和 aria-expanded 一致,并测试快速连续操作。
不支持该属性的浏览器怎么办?
保留无动画展开或有界的静态回退,确保内容、链接和键盘路径完整。渐进增强失败只减少视觉效果,不能改变业务可用性。
如何验收可访问性?
用键盘完成展开、关闭、再次打开和焦点移动,检查辅助技术读到的状态与内容。再验证减少动效设置下状态仍及时更新,隐藏内容不会留下不可达焦点。