Skip to content

Offset with smooth scroll #231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
0xsven opened this issue Sep 26, 2018 · 5 comments
Open

Offset with smooth scroll #231

0xsven opened this issue Sep 26, 2018 · 5 comments

Comments

@0xsven
Copy link

0xsven commented Sep 26, 2018

I am trying to get a smooth scroll to an element with a sticky navigation bar.

Overriding behavior (to add an offset) also overrides the smooth scroll. Can someone give me some advice on how to make this work?

const scrollIntoViewSmoothly =
  'scrollBehavior' in document.documentElement.style
    ? scrollIntoView
    : smoothScrollIntoView

scrollIntoViewSmoothly(node, {
      block: 'start',
      behavior: (actions) =>
        actions.forEach(({ el, top, left }, i) => {
          el.scrollTop = i === 0 ? top - 90 : top
          el.scrollLeft = left
        }),
    })
@0xsven
Copy link
Author

0xsven commented Sep 27, 2018

So I have worked around it by giving the element the style rule: padding-top: 90px and the element before the style rule: margin-bottom: -90px

@vukadinFE
Copy link

vukadinFE commented Feb 14, 2019

You can use custom transition with popmotion:

import { tween, styler, easing } from "popmotion";

scrollIntoView(node, {
  scrollMode: "if-needed",
  block: "nearest",
  inline: "nearest",
  behavior: instructions => {
    const [{ el, top }] = instructions;
    const elStyler = styler(el);
    tween({
      from: el.scrollTop,
      to: top - 90,
      ease: easing.easeLinear
    })
    .start(top => elStyler.set("scrollTop", top));
  }
});

@arihantverma
Copy link

@stipsan This is a scenario I'm dealing with – I have a sticky navigation menu header. On click of any menu item, it scrolls to the required element. But because the header sticks, it hides the top of that element a little by virtue of Navigation Menu Header's height.

Does it make sense to allow an 'offset' value for top, so that the behaviour coded up smooth-scroll-into-view-if-needed can used directly through this module. Right now the only option I have is to copy paste smooth-scroll-into-view-if-needed's behaviour function and manually add my offset there and use it in my code.

@stipsan
Copy link
Member

stipsan commented Jan 22, 2020

Alright I've had a rethink.
Right now if you give behavior a callback this library will simply forward everything to scroll-into-view-if-needed and no animation happens unless the browser can do it natively, which is confusing and not very helpful since if that's what you need you should just use scroll-into-view-if-needed directly instead of this library.

I'll make a new major release that lets you map over the coordinates when you provide a custom behavior, applying offsets as needed:

// Given this markup:
// <div id="app" style="height: 100vh; overflow: auto;">
//   <header style="position: fixed; left: 0; top: 0; right: 0; height: 50px" />
//   <div id="hero" />
//   <footer id="contact-us" />
// </div>

import scrollIntoView from "smooth-scroll-into-view-if-needed";
const node = document.getElementById("contact-us");

scrollIntoView(node, {
  behavior: actions =>
    actions.map(action => {
      // Ensure the offset is only applied
      // to the element that needs it.
      if (action.el.matches("#app")) {
        // Apply the minimum needed scroll padding
        // to stay underneath the sticky header.
        action.top = Math.max(50, action.top);
      }

      return action;
    })
});

That'll solve these kind of challenges for now. In the long run I want to extend compute-scroll-into-view itself to support either https://css-tricks.com/almanac/properties/s/scroll-padding/ directly, or provide the API needed to build it in packages like scroll-into-view-if-needed. The scroll-margin|padding spec is only used in scroll snapping as far as I know, I'm not aware of any browsers supporting it for scrollIntoView and .focus APIs yet but I'm keeping an eye out for when that happens 😄

@lbineau
Copy link

lbineau commented Nov 17, 2021

Hello,
I'm interested into that feature actually.
Any news about its implementation?
Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants