名前付きタイムライン

scroll-timeline-name / view-timeline-name / timeline-scope。 離れた要素のスクロール / ビューに紐づける機能。

なぜ必要か

scroll(nearest) は最寄り、view() は自分自身。 「親 A のスクロールを子 B のアニメに使う」のような離れた紐付けには名前を介する必要がある。

scroll-timeline-name

スクロールコンテナに名前を付ける:

.scroller {
  overflow: auto;
  scroll-timeline-name: --my-scroll;
  scroll-timeline-axis: block;     /* y / x / inline / block */
}

.elsewhere {
  animation: bar linear;
  animation-timeline: --my-scroll;
}

scroll-timeline 短縮形

.scroller {
  scroll-timeline: --my-scroll block;
}

view-timeline-name

.target {
  view-timeline-name: --target-view;
  view-timeline-axis: block;
  view-timeline-inset: 100px 0;
}

.linked {
  animation: react linear both;
  animation-timeline: --target-view;
  animation-range: entry 0% entry 100%;
}

timeline-scope

名前の探索範囲を制御。子孫だけでなく祖先からも名前を見えるようにできる:

body {
  /* 子孫のどこかにある --my-timeline を body 配下全体で参照可能に */
  timeline-scope: --my-timeline;
}

.scroller {
  scroll-timeline-name: --my-timeline;
}

.fixed-bar {
  /* fixed なので scroller の子孫ではないが参照できる */
  animation: bar linear both;
  animation-timeline: --my-timeline;
}

典型例 1: 別ペインの進捗バー

<header>
  <div class="reading-bar"></div>
</header>
<main class="article">
  ...長文...
</main>
body { timeline-scope: --article; }

.article {
  scroll-timeline: --article block;
  /* この main 内にスクロールがある場合 */
}

.reading-bar {
  animation: grow linear both;
  animation-timeline: --article;
  transform-origin: left;
  transform: scaleX(0);
}
@keyframes grow { to { transform: scaleX(1); } }

ページ全体スクロールなら scroll(root) で済むが、 記事だけのスクロールに追従するならこれ。

典型例 2: スクロールと連動するナビ

main { scroll-timeline: --main block; }

.section1 {
  view-timeline-name: --sec1;
}

.tab1 {
  animation: highlight linear both;
  animation-timeline: --sec1;
  animation-range: contain 0% contain 100%;
}
@keyframes highlight {
  to { background: #fff3; }
}

各セクションを view-timeline-name で名付け、対応するナビアイテムがそのセクション中だけハイライトされる。

名前と CSS 変数

関連プロパティ一覧

プロパティ用途
scroll-timeline-nameスクロールタイムラインに名前
scroll-timeline-axis軸(block / inline / x / y)
scroll-timelinename + axis の短縮形
view-timeline-nameview タイムラインに名前
view-timeline-axis
view-timeline-inset境界の内側オフセット
view-timeline短縮形
timeline-scope名前の探索範囲

view-timeline-inset

ビューポート境界を内側に縮める:

.target {
  view-timeline-name: --t;
  view-timeline-inset: 100px 100px;  /* 上下 100px ずつ縮める */
}

例: ヘッダーが固定で 80px 占めている場合、view-timeline-inset: 80px 0 にすると「ヘッダーで隠れる部分は無視」して進入扱いに。

scroll() vs view() vs 名前付き

用途選択
シンプル / 自要素scroll() / view()
離れた要素同士の連動scroll-timeline-name / view-timeline-name
祖先で参照timeline-scope

動的に名前を切替

CSS 変数のように動的に切替えはできない(同じ要素が複数の名前を持つことは可)。 切替えたければ JS から CSS を書き換える。

失敗パターン

症状対処
名前が見つからないtimeline-scope で見える範囲を広げる
動かない名前付け要素が実際にスクロール / view 対象になっているか
2 つ以上のスクロールに対応したい複数の scroll-timeline-name を持つ親を分ける

典型レシピ

「サイドの目次が現在地をハイライト」

<aside class="toc">
  <a href="#s1">セクション 1</a>
  <a href="#s2">セクション 2</a>
  <a href="#s3">セクション 3</a>
</aside>
<main>
  <section id="s1">...</section>
  <section id="s2">...</section>
  <section id="s3">...</section>
</main>
body { timeline-scope: --s1, --s2, --s3; }
#s1 { view-timeline-name: --s1; }
#s2 { view-timeline-name: --s2; }
#s3 { view-timeline-name: --s3; }

.toc a:nth-child(1) { animation: hi linear both; animation-timeline: --s1; animation-range: contain 0% contain 100%; }
.toc a:nth-child(2) { animation: hi linear both; animation-timeline: --s2; animation-range: contain 0% contain 100%; }
.toc a:nth-child(3) { animation: hi linear both; animation-timeline: --s3; animation-range: contain 0% contain 100%; }

@keyframes hi { to { color: orange; font-weight: 700; } }
timeline-scope の使い所

名前付きタイムラインを使うなら、共通の親(body や app ルート)timeline-scope を入れて 全体で見えるようにすると組み立てが楽。