您是否见过那些模态窗口从页面顶部飞下的花哨交互? 也许它从侧面滑入,同时淡入到完全不透明? 也许它从上面落下,从模糊到聚焦? 如果适合您网站的氛围,那就太酷了。
它们似乎总是沿着直线移动。 多亏了相当新的 offset-path
,它们不必这样!
CSS 中的 offset-path
属性的存在,使您可以将元素放置在路径上的某个位置。 就像我们从 SVG 中熟悉的 相同路径语法 一样。
这是一个超级简单的路径。 实际上只有两个指令
<path d="M 250,100 S -300,500 -700,-200"></path>
查看 Pen 一个非常简单的路径。 由 Chris Coyier (@chriscoyier) 在 CodePen 上。
我可以将该路径数据直接移到 CSS 并沿路径进行动画
查看 Pen 沿路径进行动画。 由 Chris Coyier (@chriscoyier) 在 CodePen 上。
在这种情况下,它是一个 @keyframe
动画 正在执行移动,这实际上只是更改了 offset-distance
值。
正在进行动画的元素可以是任何东西! 例如,一个模态 ;)
查看 Pen 沿路径移动模态 由 Chris Coyier (@chriscoyier) 在 CodePen 上。
在这种情况下,没有 @keyframes
,只有 transition
和不同的 offset-distance
值。
注意旋转!
我在这里使用 offset-rotation: 0deg;
,因为如果我不这样做,模态将旋转以沿着路径方向。 能够做到这一点非常酷,但在这种情况下却很尴尬。

回退
这种事情很容易成为一项增强功能。 在这里,我们也正在淡出不透明度和比例,因此回退会自动处理。 您也可以将这些内容包装在 @supports
语句中,这样您就可以在 offset-path
不 受支持 的情况下使用其他方式隐藏模态。
/* Fallback hide/show stuff */
.modal {
}
.modal.hide {
}
/* If supported, path-based hiding/showing */
/* Might as well test the rotation feature, as it's also vital */
@supports (offset-rotation: 0deg) {
.modal {
offset-rotation: 0deg;
offset-path: path("M 250,100 S -300,500 -700,-200");
}
.modal.hide {
offset-distance: 100%;
}
}
处理减少的运动
并非每个人都喜欢带有大量移动的 UI,并且 浏览器可以满足这一点。 我们可以这样去除运动
@media (prefers-reduced-motion) {
.modal {
offset-path: none;
}
}

我敢肯定那个媒体查询在一两周前还能工作,但现在我在我尝试过的任何浏览器中都无法让它工作(在 切换操作系统级别的设置 之后)。 不过,最终它会起作用。
与其他回退一样,请确保提供一种让模态隐藏自身的替代方式。 我也不确定这里最佳实践是什么。 也许如果您故意设计“减少运动”体验,您将选择完全不使用运动。 只是一个 display block/none 变化。
很酷的技巧! 但我对这一点感到矛盾 - 对于某些用户来说,这是一个很棒的用户体验,但当我想到这可能会导致的无障碍问题时,我感到很不安。 从无障碍性的角度来看,模态本身已经具有挑战性。
我想知道您具体在想什么。 模态的显示/隐藏方式的美学是否会影响无障碍性,除了我提到的运动问题之外?
是的,模态基本上很糟糕,内联内容和全页面体验要好得多。 我实际上认为添加动画会增强体验,因为我们看到了对象来自哪里,它的存在变得更加明显,感觉更人性化。 也就是说,它需要快得多,而且我觉得动画不透明度会有所帮助
@Chris - 我想的是患有前庭疾病或其他问题的用户,他们的运动和不透明度变化可能会带来问题。 但正如您在文章中提到的,可以通过媒体查询来缓解这种情况(假设浏览器支持它)。
模态动画的时序和缓动让我感到非常不舒服。 不过,想法很棒
@Josh 您是指动画图像的时序和缓动吗? 在 codepen.io 的示例中运行时,一切都正常。 我刚刚开始使用 bs 模态,我之前一直使用自己的方法来创建信息图形 div。 我肯定会玩玩这个。
Graztie 先生,您好
你好,Chris,
演示仅在 Chrome 中有效。
关于(未来)浏览器支持的任何信息?
我想知道,这是否可以用来实现 Medium 样式的光箱? https://terrymun.github.io/Fluidbox/demo/index.html