この記事で扱うこと
ホームページのヒーロー横の ライブノートデモ とダークな パイプラインスクロール演出 を、アニメーションライブラリなしで CSS だけで合わせた一日だ。並行してフォント CLS の整理と活性表示・アクセシビリティの整理もした。
散漫にならないよう、一作業ごと に 前提知識 → どんな状況 → 中心の作業 → 教訓 の順でまとめて整理する。
一日のまとめ
| 作業 | 何をしたかったか | やったこと | 結果 |
|---|---|---|---|
| 1. スクロール連動ホーム演出 | JS ライブラリなしで「記録 → 昇格」ストーリーのスクロール演出 | sticky 舞台 + 進行度 phase、clip-path 反復 loop、view() 登場 | ライブラリ 0kb でホームのナラティブを実装 |
| 2. タイポ CLS 整理 | 遅いネットワークでも文字のずれ(CLS)0 | タグ·バッジ·本文フォント swap → optional | 遅いネットワークで CLS 0(回帰テスト) |
| 3. UI 一貫性 & アクセシビリティ | 活性表示の統一 + 対比違反の解消 | 活性レールの単一化·aria-current、対比 AA トークン化、VR baseline | ページ間の表示統一、a11y 違反の解消 |
1. スクロール連動ホームナラティブ
前提知識(概念)
- scrolly / sticky scrolly: 一つの要素を
position: stickyで貼り付けたままスクロール量を進行度に変え、スクロールするぶん段階(phase)が進む演出。 - scroll-timeline / view-timeline (
animation-timeline): JS なしで スクロール位置そのものをアニメーションの時間軸 に使う CSS 機能。view()は「要素がビューポートに入ってくる度合い」を時間軸にする。 - CSS keyframes:
@keyframesで定義して時間に沿って回るアニメーション。スクロールと無関係に自分で反復(loop)する。
どんな状況だったか
- 最近のランディングページの流れは JS アニメーションライブラリの代わりに CSS keyframes + ネイティブ scroll-timeline を使うほうが主流だ。
- 問題は 時間 loop(自分で反復)/ スクロール phase(進行度で段階遷移)/ スクロール登場(view reveal) の三軸が混ざると互いに壊れることだ。
- sticky scrolly と view-timeline は 親に
overflow: hidden一行あるだけで同時に静かに死ぬ。
中心の作業
- パイプラインセクションは sticky 舞台 + ラッパー高さベースの進行度 で phase を派生した — 一画面に一段階、レールとグリッドは固定。
- ヒーローのライブデモは clip-path steps ワイプ +
animation-delayだけで反復 loop を作った。hydration(サーバ HTML に JS を付けて生かす過程)コスト 0、テキストは鮮明、min-heightで場所を予約 して loop がレイアウトを揺らさないようにした。 - 一覧·カードの登場は
animation-timeline: view()+animation-range: entryで進入しながら fade — loop とは クラス·時間軸を分離 した。 prefers-reduced-motionでは sticky を解除し 最終昇格状態に固定 → アニメだけ切って情報はそのまま degrade。
教訓
- ランディングモーションは JS 0kb でも可能 だ — scroll-timeline·sticky·keyframes の組み合わせが最近の流れと合う。
- 三つの時間軸(時間 loop / スクロール phase / スクロール登場)はクラス·タイムラインで 分離しないと互いに壊れる。
- sticky scrolly は祖先要素の
overflow: hidden一行で静かに死ぬ — 壊れたら親チェーンから疑う。 - 装飾用デモは
aria-hidden+min-height予約 で layout を揺らさないようにする。
→ Scroll-driven narrative layout · CSS view-timeline entry animation · 2026 startup landing page trends
2. タイポ CLS 整理
前提知識(概念)
- CLS (Cumulative Layout Shift): ページがロードされながら要素が急にずれ出る度合い。低いほどよい。
font-display: swapvsoptional:swapはウェブフォントが遅く到着すると代替フォントをウェブフォントに替える。optionalはごく短い待ちのうちにフォントが来なければ 代替フォントをそのまま維持 する。
どんな状況だったか
- タグ pill·バッジ·本文が
font-display: swapだったため、ウェブフォントが遅く到着すると文字サイズ(glyph metrics)が変わってレイアウトがずれた(CLS 跳ね)。
中心の作業
- タグ pill·バッジ·本文フォントを
swap→optionalに替えた。 - 遅いネットワーク +
optionalの組み合わせで CLS 0 を守る回帰テストを追加した。
教訓
font-display: optionalはブランドフォントの完璧な再現より 計測可能な CLS が優先の文書 UI に合う。
→ font-display optional and CLS
3. UI 一貫性 & アクセシビリティ
前提知識(概念)
aria-current: 現在の活性項目(現在のページ·フィルタ)を支援技術に知らせる属性。- 対比 AA: WCAG の明暗比基準。テキスト/背景の対比がこの基準を超えてこそ低視力ユーザーも読める。
- VR(Visual Regression) baseline: 画面のスクリーンショットを基準線として保存しておき、以降の変更が画面を意図せず変えたかをピクセル比較で捕まえること。
どんな状況だったか
- 活性状態の表示(レール·下線·pill)がページごとに違い 目で追うコスト が大きかった。
- 強調色のテキスト対比が基準に届かない箇所があった。
中心の作業
- 活性表示を レール一つに単一化 し、フィルタに
aria-currentを付け、本文幅を制限した。 - 強調色を対比 AA 通過値 に調整して
--signal-textトークン に抜き出した(再発防止)。 - 主要な breakpoint について VR baseline を取った。タイプチェック + 単位(vitest)+ E2E すべて green。
教訓
- 活性表示は 単一ソースで統一 してこそページごとにずれない。
- 対比値は トークン化 しておけば次に同じ違反が再発しない。