滚动时缩小的标题是一种常见的界面模式,当用户向下滚动时,页面顶部的固定标题元素会平滑过渡到较小的尺寸。这种效果通常用于最大限度地扩大主要内容的屏幕空间,同时让用户能够访问重要的导航或品牌元素。借助 CSS 滚动驱动的动画,您可以通过将动画关联到文档的滚动位置,以声明式且高效的方式实现此效果。
如何实现
以下是创建滚动时缩小的标题的方法:
创建固定页眉:首先创建一个固定在页面顶部且具有预定义高度的页眉元素。
<header>HEADER</header>header { position: fixed; height: 200px; top: 0; left: 0; right: 0; }定义缩小动画:创建一个可更改标题高度的 CSS 动画。
@keyframes shrink { to { height: 50px; } }应用动画和滚动时间轴:将动画附加到标题,并使用
scroll()函数将其与文档的滚动位置相关联。header { animation: shrink auto linear both; animation-timeline: scroll(block root); }设置
animation-range:使用animation-range属性指定动画应发生的滚动距离。例如,如需在滚动前 150 像素时缩小标题,您可以使用animation-range: 0px 150px;。header { animation-range: 0px 150px; }
提示:为防止页眉遮挡其后的内容,请向 body(或主要内容容器)添加一个 padding-top,其值等于页眉的初始高度。
提示:为确保页面内容与缩小的标题同步滚动,请将 animation-range-end 设置为起始大小和结束大小之间的差值。这样可以确保动画在标题达到最终尺寸时精确完成。在此演示中,标题从 200px 缩小到 50px,因此 animation-range-end 设置为 150px。
示例代码
@keyframes shrink {
to {
height: 50px;
}
}
header {
animation: shrink auto linear both;
animation-timeline: scroll(block root);
animation-range: 0px 150px;
}
最佳做法
使用滚动驱动动画时,请务必遵循一些最佳实践,以确保提供流畅且无障碍的体验:
- 务必添加功能检测:并非所有浏览器都支持滚动驱动的动画。使用
@supports ((animation-timeline: scroll()) and (animation-range: 0% 100%))检查是否支持,并为不支持的浏览器提供后备方案。- 此处必须包含
(animation-range: 0% 100%)检查,以滤除仅提供部分支持的浏览器。 - 请勿将
scroll-timeline-polyfill软件包用于回退策略,因为它功能不完整,并且存在许多已知问题。 - 如果动画仅被视为装饰性元素,请选择渐进增强,不要提供后备。
- 此处必须包含
- 务必尊重用户偏好:有些用户更喜欢在网页上看到较少的动画。使用
prefers-reduced-motion媒体查询为这些用户停用或减少动画。 - 务必尝试仅为高性能 CSS 属性添加动画效果:为了获得最流畅的动画效果,请坚持为可由浏览器的合成器线程处理的属性(例如
transform和opacity)添加动画效果。为其他属性(例如width或height)添加动画效果可能会导致性能问题。 - 务必使用正确的声明顺序:使用
animation简写属性时,请在它之后声明animation-timeline和animation-range,以防止简写属性重置时间轴。
使用 scroll() 函数创建滚动驱动的动画时:
- 可选:明确指定滚动条。如果目标不是最近的祖先滚动条,请使用
scroll(root)或scroll(self)明确指定要使用的滚动条。- 如果
root、nearest或self不够用,请使用命名的 scroll-timeline。
- 如果
- 可选:明确指定要跟踪的轴。如果未定位到默认的
block轴(例如在水平滚动条中),请使用scroll(block)或scroll(inline)明确指定要跟踪的轴。
具体到此应用场景:
- 在
animation-range中使用百分比时,您添加动画效果的元素不得是position: static或position: relative。- 这是因为这些元素被视为“流内”元素。在滚动时缩小这些元素会缩短总滚动距离,从而影响滚动到
10%等位置的计算值。
- 这是因为这些元素被视为“流内”元素。在滚动时缩小这些元素会缩短总滚动距离,从而影响滚动到
浏览器支持和后备策略
因此,通常需要采用后备策略。
对于不支持滚动驱动动画的浏览器,您可以使用后备方案来重现视觉效果。后备方案通常使用滚动监听器(用于 ScrollTimeline 效果)或 IntersectionObserver API(用于 ViewTimeline 效果)构建。
在内置支持滚动驱动动画的浏览器中,请始终使用原生 CSS 实现,因为这些实现的性能更高。
请注意,并非所有效果都可以通过后备方法重现。
具体而言,对于此用例,以下脚本会为不支持滚动驱动动画的浏览器应用回退。它使用滚动监听器来跟踪文档在 150px 距离内的滚动位置,并相应地更新标题的高度。
// Fallback for browsers that don't support scroll-driven animations
if (!CSS.supports('(animation-timeline: scroll()) and (animation-range: 0% 100%)')) {
const header = document.querySelector('header');
const initialHeight = 200;
const finalHeight = 50;
const scrollDistance = 150;
window.addEventListener('scroll', () => {
const scrollY = window.scrollY;
const scrollPercent = Math.min(1, scrollY / scrollDistance);
const newHeight = initialHeight - (initialHeight - finalHeight) * scrollPercent;
header.style.height = `${newHeight}px`;
});
}