scroll-into-view / scroll-into-view-if-needed

Element.scrollIntoView ponyfills for things like "if-needed" and "smooth"

Home Page:https://scroll-into-view.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Todo for v2

stipsan opened this issue · comments

Moving it out of #155 so this can be done in multiple PRs.

Guiding principles behind the rebuild

  • Ponyfill principles, never alter globals that one day could break the web (cough cough mootools cough cough)..
  • Minimal in design and API surface.
  • Follow the Element.scrollIntoView(ScrollIntoViewOptions) spec and related draft specs instead of reinventing the wheel.
  • Comprehensive testing suite to ensure the spec is implemented correctly, and that common use cases are accounted for.
  • Modular design, favor composition over configuration.
  • Adapts to your priorities. If speed and bundlesize is more important than every visitor seeing a nice smooth scroll then the default version is enough. If a consistent user experience for all your users is more important, opt in to the smooth-behavior ponyfill.
  • Sensible defaults, zero-config (as long it doesn't break spec compliance).
  • Lifecycle hooks instead of a million options.

Entirely new API, implementing Element.scrollIntoView(ScrollIntoViewOptions) and {scrollMode: 'if-needed' | 'always'}.

  • new docs page.
  • upgrade cypress to be all TS.
  • upgrade next.js to follow TS best practice.
  • upgrade next.js to export test pages when cypress is running it.
  • update readme.
  • rewrite old tests to new changes.
  • migration guide with a list over breaking changes.
  • new rollup build that generates react-router like suite of bundles so this package is easier to consume for most people.
  • {scrollMode: 'if-needed'}, this feature is what spawned the creation of this package, but it needs to be rewritten to simply check if something isn't visible before it should optimistically attempt scrolling it into view (reference implementations: 1)
  • {scrollMode: 'always'}, and suddenly this package became a lot more useful.
  • {block: 'start'}
  • {block: 'center'}
  • {block: 'end'}
  • {block: 'nearest'}
  • {inline: 'start'}
  • {inline: 'center'}
  • {inline: 'end'}
  • {inline: 'nearest'}
  • scroll it yourself {behavior: (scrollInstructions: [Element, scrollTop, scrollLeft])}. Maybe you want to be creative, or a different transition, easing, do it in a sequence or throttle it. Whatever floats your boat.
  • {behavior: 'smooth'} (ensure ponyfilled animation matches what firefox and chrome is doing, it must not feel slow or odd).
  • {boundary: Element}, limit propagation of scrolling as it traverses innermost to outermost scrolling boxes by passing in an element reference.
  • {boundary: (el: Element) => boolean}, provide a way to do custom checks. This solves the problem with cross-realm elements (scrolling up iframes and frames) where referencial checks won't work. It also provides an escape hatch for userland business logic like "skip all elements that are overflow: hidden".

Testing strategy

Helpful reference material

https://github.com/chromium/chromium/blob/f18e79d901f56154f80eea1e2218544285e62623/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js#L392-L433

https://github.com/chromium/chromium/blob/7bacbbc6c0e5e337f642811374d9023f52795bd3/chrome/browser/resources/chromeos/chromevox/common/selection_util.js#L226-L249

http://www.performantdesign.com/2009/08/26/scrollintoview-but-only-if-out-of-view/

https://github.com/chromium/chromium/blob/f18e79d901f56154f80eea1e2218544285e62623/third_party/WebKit/LayoutTests/fast/scroll-behavior/bordered-container-child-scroll.html

https://github.com/iamdustan/smoothscroll/blob/master/src/smoothscroll.js

https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/dom/element.cc?sq=package:chromium&dr=CSs&l=500

Using FireFox' implementation as reference

The way FireFox handles smooth scrolling, and the scrollIntoView features in general is the best one today. So I am using their C++ implementation to guide me on the JS implementation: https://github.com/mozilla/gecko/blob/03abe3240ab1ad8c2e7f78ebb16a6bd3c17febb1/layout/base/PresShell.cpp#L3626-L3743

Rationale from dropping Element.scrollIntoViewIfNeeded

The fine folks over at chromium are already discussing removing this non-standard api: https://bugs.chromium.org/p/chromium/issues/detail?id=699843&q=scrollintoView&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified

It's time to move on 😃