Skip to content

Rules · smooth/*

Smoothness rules

How the page feels after it loads: dropped frames during a scripted scroll, long animation frames, INP of real clicks, shifts after input, animated layout properties, idle rAF loops and reduced-motion handling.

$ void smooth13 rules1 error · 11 warn · 1 infoupdated 16 Sept 2026
  1. smooth/scroll-jankwarnFrames are dropped while scrollingWhen the main thread cannot produce a frame every 16.7 ms, scrolling stutters. Users read this as a cheap, broken site even when load metrics are good.
  2. smooth/long-frames-during-scrollwarnLong animation frames block scrollingLong Animation Frames (LoAF) during scroll show script that delays rendering; the attributed script is the culprit.
  3. smooth/scroll-listener-nonpassivewarnNon-passive wheel/touch listenerA non-passive wheel or touchmove listener forces the browser to wait for JavaScript before it can scroll, so every scroll gesture starts late.
  4. smooth/inp-slowwarnInteractions are slow to respond (INP)Interaction to Next Paint measures the delay from tap/click to the next frame. Above 200 ms the UI feels laggy; above 500 ms it feels broken.
  5. smooth/layout-shift-after-inputwarnLayout shifts long after an interactionShifts that happen more than 500 ms after a tap are not excused by user input and feel like the page is jumping on its own.
  6. smooth/layout-shift-on-scrollwarnLayout shifts while scrollingLazy content that pops in without reserved space shoves the text the reader is looking at.
  7. smooth/animate-layout-propertywarnAnimation of a layout-triggering propertyAnimating width, height, top/left, margin or padding re-runs layout and paint on every frame; box-shadow on large elements repaints large areas. These animations drop frames on phones.
  8. smooth/transition-allwarntransition: alltransition: all animates every property that changes, including layout properties you did not intend, and makes transitions harder to reason about.
  9. smooth/will-change-overuseinfowill-change is applied too broadlyEvery will-change layer costs GPU memory; applying it statically to many elements (or html/body) can make scrolling worse, not better.
  10. smooth/reduced-motion-ignoredwarnAnimations keep running with prefers-reduced-motionPeople with vestibular disorders set reduce motion to avoid nausea and dizziness; infinite or large animations must stop for them (WCAG 2.3.3).
  11. smooth/raf-loop-idlewarnrequestAnimationFrame loop runs while idleA perpetual rAF loop (canvas, WebGL, JS-driven marquee) burns CPU and battery on every frame even when nothing is visible, and competes with scrolling.
  12. smooth/scroll-timeline-no-fallbackerrorContent is invisible without scroll-driven-animation support`animation-timeline: view()/scroll()`, `view-timeline` and `animation-range` have no fallback path: a browser that doesn't implement them (Firefox, at every version through 151) evaluates the enclosing `@supports (animation-timeline: …)` block as false and drops every rule inside it — including the keyframes that would ever make the element visible. If the element's base rule (outside that block) sets `opacity: 0`, `visibility: hidden`, a collapsed scale/mask or an off-screen translate, the content isn't degraded, it's gone — permanently, not just until scrolled into view.
  13. smooth/multiple-webgl-contextswarnMultiple WebGL contextsEach WebGL context has its own GPU state and memory; browsers cap them (≈16) and mobile GPUs struggle with more than one.