常见的自动布局陷阱

虽然布局 API 可以自动处理大多数动画场景,但某些极端情况可能会产生意料之外的结果。以下是需要注意的事项。

某些元素意外淡出

当使用 children 选择器时,作为匹配子元素的后代(但其本身并非目标)的元素,其状态只会在过渡进度达到 50% 时更新。为了避免两种状态之间出现生硬的切换,在以下条件下,这些元素会淡出至透明度 0,然后再恢复至 1:

  • 该元素未被 children 选择器明确选中
  • 该元素的大小发生了变化
  • 其父元素是目标元素,且父元素的大小也发生了变化

解决方法

将需要保持可见的元素添加到 children 选择器数组中。
或者将 swapAt 参数更改为 opacity: 1

const layout = createLayout('#root', {
  children: '.card', // Only .card elements are targets
  swapAt: { opacity: 1 } // This will make sure all descendants of .card are always visible during the transition.
});

根元素位置在过渡期间“跳动”

根元素的位置不会被动画化,因为这可能会导致其他问题,例如由于根元素的兄弟节点不是布局的一部分,导致它们在过渡期间发生跳动。
根元素的尺寸可以被动画化,因为改变宽度和高度(在大多数情况下)会影响其他元素的位置。

解决方法

如果你遇到需要对布局根元素的位置进行动画处理的情况,则必须将当前根元素的父元素用作新的根元素。

// From this
const layout = createLayout('#container .grid'); // .grid position can't be animated.
// To this
const layout = createLayout('#container'); // Now .grid position can be animated

我的文本在布局过渡期间发生跳动

fontSize 的同时对 widthheight 进行动画处理可能会导致文本在动画过程中重排,特别是在 Firefox 中。即使开始和结束状态具有相同的换行符,中间帧的宽度/字体大小比例也可能触发自动换行。

解决方法

如果不需要文本换行,请在元素上使用 white-space: nowrap

文本内嵌的一些元素没有移动

为了防止在过渡期间破坏文本流,与文本节点相邻的元素会被排除在位置动画之外。

<p>Some text <span class="highlight">inline element</span> more text</p>

解决方法

将文本元素包裹在 span 标签中,以允许文本节点与内嵌元素一起进行动画处理。

<p><span>Some text</span> <span class="highlight">inline element</span> <span>more text</span></p>

变换(Transform)简写属性不起作用

enterFromleaveToswapAt 参数不支持 CSS 变换简写属性,如 scalerotatexy 等。

// Won't work
createLayout('#root', {
  enterFrom: { scale: 0 }
});

解决方法

请使用包含完整变换字符串的 transform 属性。

// Use transform string
createLayout('#root', {
  enterFrom: { transform: 'scale(0)' }
});

SVG 元素未进行动画处理

SVG 元素及其后代会被排除在布局动画之外。只有 HTML 元素会被追踪并进行动画处理。