← Blurr Motion footer-css-scroll-driven-minimal
Categorie footers Tier 3 Techniek #40 Deps
scroll

Footer onthult zich op scroll. Native CSS scroll-timeline.

1. Mechanisme — kopieer 1-op-1, geen styling-keuzes
// Mechanisme: footer-css-scroll-driven-minimal
// Pure CSS scroll-driven: thin horizontal rule scaleX 0->1, tagline opacity 0->1.
// animation-timeline: view() + animation-range gekoppeld aan entry/cover.
// JS fallback voor non-supporting browsers (scroll-listener + manuele progress).
(() => {
  const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  const supportsTimeline = CSS.supports('animation-timeline: view()');
  const root = document.querySelector('.fcs-mn');
  if (!root) return;
  const rule = root.querySelector('.fcs-mn-rule');
  const tagline = root.querySelector('.fcs-mn-tagline');
  const word = root.querySelector('.fcs-mn-word');
  if (reduce) {
    if (rule) rule.style.transform = 'scaleX(1)';
    if (tagline) tagline.style.opacity = '1';
    if (word) word.style.opacity = '1';
    return;
  }
  if (supportsTimeline) return;
  const sentinel = root.querySelector('.fcs-mn-sentinel');
  if (!sentinel) return;
  const onScroll = () => {
    const r = sentinel.getBoundingClientRect();
    const vh = window.innerHeight;
    const p = Math.max(0, Math.min(1, 1 - (r.top / vh)));
    if (rule) rule.style.transform = 'scaleX(' + p + ')';
    if (word) word.style.opacity = String(Math.max(0, Math.min(1, (p - 0.15) / 0.4)));
    if (tagline) tagline.style.opacity = String(Math.max(0, Math.min(1, (p - 0.4) / 0.4)));
  };
  window.addEventListener('scroll', onScroll, { passive: true });
  onScroll();
})();
2. Skeleton — DOM + class-namen, mag herschikken
<!-- Skeleton: footer-css-scroll-driven-minimal -->
<div class="fcs-mn">
  <div class="fcs-mn-spacer"></div>
  <footer class="fcs-mn-foot">
    <div class="fcs-mn-sentinel"></div>
    <span class="fcs-mn-eyebrow">end</span>
    <h2 class="fcs-mn-word">thanks.</h2>
    <hr class="fcs-mn-rule"/>
    <p class="fcs-mn-tagline">A studio for motion.</p>
    <div class="fcs-mn-meta"><span>blurr</span><span>2026</span></div>
  </footer>
</div>
3. Styling-template — verplicht eigen invulling per merk
/* Styling: footer-css-scroll-driven-minimal */
:root {
  --mn-paper: #F4F1EB;
  --mn-ink: #0A0A0A;
  --mn-rule: rgba(10,10,10,.22);
}
.fcs-mn { background: var(--mn-paper); color: var(--mn-ink); font-family: 'Inter', system-ui, sans-serif; }
.fcs-mn-rule {
  transform-origin: left center; transform: scaleX(0);
  animation: mnRule 0.8s ease-out both;
  animation-timeline: view();
  animation-range: entry 5% cover 65%;
}
.fcs-mn-tagline { opacity: 0; animation: mnFade 0.8s ease-out both; animation-timeline: view(); animation-range: cover 35% cover 75%; }
@keyframes mnRule { to { transform: scaleX(1); } }
@keyframes mnFade { to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .fcs-mn-rule { transform: scaleX(1) !important; animation: none !important; }
  .fcs-mn-tagline { opacity: 1 !important; animation: none !important; }
}