为初始渲染设置滚动目标

CSS 属性 scroll-initial-target 提供了一种声明式、仅限 CSS 的方式,可在滚动容器呈现后立即将特定后代元素引入其滚动容器的可见区域。以前,开发者依赖 JavaScript (Element.scrollIntoView()) 或网址片段标识符 (#item-id),这两者都有局限性,且实现起来比较棘手。

如何实现

如需成功实现此功能,请执行以下操作:

  1. 确保存在滚动容器:目标元素必须位于滚动容器(具有允许滚动的溢出属性的元素,例如 overflow: auto)内。这可以是任何祖先元素,包括根元素 <html>。
  2. 定位到相应项:将 scroll-initial-target: nearest 应用于您要显示在视图中的特定后代元素。

示例代码:垂直媒体 Feed

在此示例中,Feed 在开始时会滚动到特定的“精选”项,而不是列表的最顶部。

/** 
 * TARGET: The item that should be visible on initial load.
 */
.item.target {
  scroll-initial-target: nearest;
}

策略性实施和最佳实践

  • 务必将 scroll-initial-target 用于“从中间开始”的体验,例如从当天开始的日历或从特定图片开始的图库。
  • 请勿将此与无障碍焦点混淆。此属性只会移动视觉视口,而不会移动键盘焦点。如果目标是键盘用户的起点,您必须手动管理 element.focus()。
  • 如果您需要在加载时实现流畅的“滚动”动画,请不要使用此属性;此属性是离散的,会在布局阶段立即设置位置。
  • 请勿在同一可滚动容器内的多个元素上设置 scroll-initial-target。如果多个元素指定了 scroll-initial-target: nearest,浏览器会选择在 DOM 树顺序中首先出现的元素。
  • 务必为媒体提供尺寸。由于滚动位置是在初始布局期间计算的,因此请确保图片或视频具有 aspect-ratio 或固定的 height/width,以防止目标在媒体加载后发生偏移。
  • 务必考虑优先级层次结构:网址片段(例如 example.com/#top)和容器级 scroll-start 属性都优先于 scroll-initial-target。

后备策略

对于尚不支持该 API 的浏览器,请使用 JavaScript 后备。使用 DOMContentLoaded 事件可确保浏览器在 HTML 解析完成后立即将元素滚动到视图中,从而提供比等待所有图片和资源加载更快的体验。或者,也可以将脚本放在 <body> 元素的末尾,这样就无需使用事件监听器。

/**
 * Progressive Enhancement Fallback
 */
document.addEventListener("DOMContentLoaded", () => {
  // Check for native CSS support
  if (!CSS.supports("scroll-initial-target", "nearest")) {
    const feedTarget = document.querySelector(".item.target");
    if (feedTarget) {
      // 'block: center' ensures the featured media is centered in view
      feedTarget.scrollIntoView({ behavior: "instant", block: "center" });
    }
  }
});