Open 0xsven opened 6 years ago
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
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));
}
});
@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.
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 😄
Hello, I'm interested into that feature actually. Any news about its implementation? Thank you.
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?