panatgithub_AnkiHeadingSync/docs/settings-sticky-gap-decisions.md
Dusk cdfbf2d12c fixed sticky spacing / 修复粘性间距
added a shared sticky gap variable / 添加了共享的粘性间距变量
card headers dock below the page header with a stable 8px gap before and after scrolling / 卡片标题停靠在页面标题下方,滚动前后均保持稳定的 8px 间距
2026-04-25 22:30:19 +08:00

2.7 KiB
Raw Blame History

设置页 Sticky 标题间距修复决策

本文锁定本轮“页面标题与卡片标题 sticky 间距固定为同一个 8px 来源”的最终实现策略。

1. 共享常量决策

  • 新增常量:
    • SETTINGS_STICKY_CARD_GAP_PX = 8
    • SETTINGS_PAGE_HEADER_FALLBACK_HEIGHT_PX = 64
  • 这两个常量只服务于当前 sticky 标题布局。

原因:

  • 页面标题正常流间距与卡片 sticky 偏移必须来自同一来源,避免滚动前后出现漂移。

2. CSS 变量决策

  • containerEl 初始化时写入:
    • --ahs-settings-page-header-height: 64px
    • --ahs-settings-sticky-card-gap: 8px
  • 页面标题高度变量继续允许运行时测量覆盖。
  • gap 变量固定作为共享布局输入。

原因:

  • 卡片标题 sticky top 需要同时引用“页面标题高度 + 固定 gap”。
  • 变量必须在卡片首次渲染前存在,避免首帧偏移不稳定。

3. 页面标题间距策略

  • 页面标题继续保持:
    • position: sticky
    • top: 0px
    • zIndex: 300
    • 不透明背景
  • 保留现有页面标题遮罩实现。
  • marginBottom 改为:
var(--ahs-settings-sticky-card-gap, 8px)

原因:

  • 页面标题底部间距的语义保留不变,但不再和 sticky 偏移脱节。

4. 卡片标题 sticky top 策略

  • 每个 settingsCardToggle 继续保持 sticky。
  • top 改为:
calc(var(--ahs-settings-page-header-height, 64px) + var(--ahs-settings-sticky-card-gap, 8px))
  • zIndex 继续低于页面标题、高于正文。
  • 背景继续使用不透明主题背景。

原因:

  • 这能保证未滚动时的 8px 间距与吸顶后的 8px 间距由同一个 gap 驱动。
  • 卡片标题不会贴到页面标题底边,也不会在滚动后压缩这段间距。

5. 测量与 fallback 决策

  • 继续复用已有 ResizeObserver 路径更新 --ahs-settings-page-header-height
  • 初始化先写 64px fallback测试环境保持可预测。
  • hide() 继续断开 observer。

原因:

  • 本轮不需要新增滚动监听或其它运行时机制。
  • 现有测量路径已经足以支撑“header-height + gap”的计算。

6. 不变边界

  • 不改 DOM 结构。
  • 不改 toggleCard()
  • 不改 renderCard()
  • 不改 expandedCardIds
  • 不改设置数据结构、Anki 同步逻辑、局部刷新逻辑。
  • 不引入 scroll listener、IntersectionObserverrequestAnimationFrame

7. 本轮与当前实现的最小差异

  • 当前实现已经修好了页面标题遮罩和双层 sticky。
  • 本轮只补“共享 8px 间距变量”这一层。
  • 因此本次不是重新设计 sticky 结构,而是把已有 sticky 结构的间距输入统一化。