magic-akari / seamless-scroll-polyfill

Scroll Behavior polyfill
https://www.npmjs.com/package/seamless-scroll-polyfill
MIT License
159 stars 12 forks source link

Element scrollIntoView on a single axis only? #107

Closed alandickinson closed 3 years ago

alandickinson commented 3 years ago

Hi! First off, thanks so much for maintaining this.

I am using this to get a cross-browser smooth scroll on a horizontal tab bar. At small viewports it becomes scrollable, and I've set it up so when a tab is selected, it gets scrolled to the horizontal center of the screen. I've been building out the rest of the page and am now seeing that selecting a tab causes vertical scroll at the page level. Is there a way to specify scrollIntoView to only act on the horizontal axis? Or am I using the wrong method for this?

Here's my current approach:


// polyfill for smooth scrolling of feature tabs in safari
elementScrollIntoViewPolyfill();

function FeatureTab({ index, ...props }) {
    const { selectedIndex, focusedIndex } = useTabsContext();
    const ref = React.useRef();
    // scroll selected tabs to center of screen for better UX on mobile
    React.useEffect(() => {
        if (index === selectedIndex && ref.current) {
          ref.current.scrollIntoView({
              behavior: "smooth",
              inline: "center",
              // set a custom duration used by the polyfill
              duration: 150
          });
        }
    }, [index, selectedIndex]);
    return (
        <StyledFeatureTab
            selectedindex={selectedIndex}
            focusedindex={focusedIndex}
            index={index}
            ref={ref}
            {...props}
        />
    )
}
magic-akari commented 3 years ago

There is no way to only act on the horizontal/vertical axis. But what you need is probably nearest.

Try this:

ref.current.scrollIntoView({
  behavior: "smooth",
  inline: "center",
  block: "nearest",
});
alandickinson commented 3 years ago

Thanks for your help, this mostly solves it for me! My page scrolls to the first set of tabs when the page loads, but that is probably because React is running the code on initial render which would be unrelated to this polyfill.

alandickinson commented 3 years ago

Closing this since this resolved my issue, thanks again. I ended up moving the scrollIntoView method into an onChange handler which only runs after user interaction.