scroll-into-view / scroll-into-view-if-needed Goto Github PK
View Code? Open in Web Editor NEWElement.scrollIntoView ponyfills for things like "if-needed" and "smooth"
Home Page: https://scroll-into-view.dev
License: MIT License
Element.scrollIntoView ponyfills for things like "if-needed" and "smooth"
Home Page: https://scroll-into-view.dev
License: MIT License
I can't seem to get this to work on an element within a shadow DOM and I'm beginning to think it's at least temporarily not supported based on scroll-into-view/compute-scroll-into-view#76 -- is that right? Any suggestions on workarounds?
When I set block/inline to end
or nearest
, in a container with scrollbars, part of the target element on the bottom and right remains hidden behind the scrollbars.
This is visible on https://scroll-into-view-if-needed.netlify.com/, the "scroll alignment" example. With block and inline both set to nearest
, scrolling to 9 results in the green box being only partially visible, while scrolling to 1 results in that green box being fully visible. If I set the container to overflow: visible
in devtools, scrolling to 9 results in the green box being fully visible, like for 1.
I get this behaviour on both Firefox 52.5 and Chromium 64.0.
Hi, theres a console.log('test) in the alignNearestInline function.
Documented in this spec: https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin
This is how it'll be possible to set custom offsets without reimplementing the default scrolling behavior or changing the HTML structure to add wrapping elements with padding to accomplish the same thing.
I've noticed that scrolling a horizontal group of elements that are in right-to-left (RTL) writing mode scrolls to the wrong end of the list.
The native API seems to handle this case, so I believe it's a bug.
Reproduction in this pen. Instructions on the page.
Thanks so much!
Version: 2.2.14
.
See the gif:
I don't observe the bug on the react-responsive-ui
demo page but in a real-world app I can see the bug.
Don't know what could cause such behaviour.
I guess there could be many variables affecting that.
I downgraded to various versions and found out that 2.1.0
doesn't have the bug and >= 2.1.1
has the bug, so I guess it was some change from 2.1.0
to 2.1.1
.
I'm staying on version 2.1.0
because of that.
I have a slider of elements and a large view below the slider that is mounted when an element is clicked.
I have used scrollIntoViewIfNeeded when the large view component gets mounted.
It scrolls nicely the first time, but when i close the view and then open it again. It does not scroll.
π hey there,
After some investigation of an issue posted in react-scroll-into-view-if-needed
here. It looks as though there is a bug with the following behavior:
I setup this codesandbox to demonstrate: https://codesandbox.io/s/l4w26w2jz7
(note: it is in React, but I'd be happy to setup an html/css only one soon if it helps)
In this example, with scrollMode set to 'always', scroll to the bottom of the page and click this button at the bottom:
Notice that it scrolls up to the target as expected
Now, switch to 'if-needed' and notice the button does not scroll up to the target.
I'm happy to dig deeper in the near future and submit a PR if I can find the problem, but in the meantime just wanted to document it here for visibility.
Thanks for your work on this package!
Hi, I just upgraded to v2, which looks great, except the duration
option seems to have gone away... is it no longer possible to specify a duration for the smooth scroll animation?
https://msdn.microsoft.com/en-us/library/hh781509(v=vs.85).aspx
This mode may not be possible to combine with the boundary
feature. However the performance benefits for deeply nested elements is worth the time adding this performance optimization.
The scrolling works, but it does not happen smoothly. It just snaps.
I ran into a situation in my code where I wanted to change something so that a full-height element (same height as scroll container) would scroll into view. To my surprise, nothing happened. I thought it must be my code, so I made a Codepen, with the same behavior (nothing happens): https://codepen.io/matthewdean/pen/KxaJga
To verify that it wasn't something wrong with scrolling setup, I made a 99% height tile version, which works: https://codepen.io/matthewdean/pen/qMRgVL
Then I thought, "Well maybe this is just a bug where elements larger than the scrollable area don't scroll into view," at which point I discovered something totally bonkers. A Codepen with tiles that are 101% also work. https://codepen.io/matthewdean/pen/QVdYQp
So this bug appears to be that only tiles the same exact height as the scrollable area cannot scroll into view
I need to do something after the animation is done but don't see a way of doing it with the current options, outside of doing something like setTimeout using the duration time.
I noticed aminate
function accepts a done
option that isn't being used by this package.
Typescript, unlike babel, differentiates between default and "whole" exports, this is.
import * as X from 'X'; = require('X')
import X from 'X'; = require('X').default;
whereas in babel
import X from 'X'; = require('X').default || require('X');
the thing is that the TS typings say that the function is actually on require('X').default, but it is actually in require('X') due to this last line in the generated index.js:
module.exports = exports['default'];
something to do most probably with how rollup does it.
could the typings be fixed? or if not at least then make it actually export the function on default :)
Just tried out this package for this first time, and I'm a big fan! The native browser scrollIntoView
was causing issues for me and this package is working perfectly.
However, I did notice the NPM distribution for this package is somewhat strange. The distributed files, specifically dist/bundle.js
seem to contain all the dependent packages bundled together. This isn't the NPM way - ideally your distributed module should just require
the other modules it wants to use. My friendly suggestion here is to use babel to compile your src/index.js
file and distribute that in your final package as either index.js
or dist/index.js
and appropriately link to it in your package.json
. You can still distribute the full rolled-up dist/bundle.js
if you want, but it shouldn't be the main file.
Also, I noticed that the export in the distributed version is not a default export. So you have to do import * as scrollIntoView from "scroll-into-view-if-needed"
instead of the examples given in the README.
Finally, I'd recommend adding the MIT license or another similar license to this package! Don't want to scare people away from using it π
This is mostly curiosity: why even include the 2nd parameter if the options parameter can do so?
The following cases (I presume) are analogous:
scrollIntoViewIfNeeded(myEl, true);
scrollIntoViewIfNeeded(myEl, null, {centerIfNeeded: true});
If they aren't analogous:
I feel as though the signature could be simplified to just be:
export default function(
node: Element,
options?: ScrollIntoViewIfNeededOptions,
finalElement?: Element
): void;
I understand that parameter 2 is for convenience (at least I assume so), in which case, I recommend removing it from the ScrollIntoViewIfNeededOptions
interface to avoid confusion.
Otherwise good work on a useful module. It's nice to have this around instead of pretending that browsers support the native implementation ;)
I noticed that with IE10 and adding a duration option, the scroll effect is really jerky. Of course this doesn't seem to happen with any other browser. π
Using
scrollIntoViewIfNeeded(node, {duration: 500});
It is getting scrolled to that particular div but but animation is not working.
pls look into this.
Hi,
you left console.log in compute.js -> line 67 -> "console.log('test')"
I fixed scrollable if hidden by frame, but does not work scroll if iframe is outside viewport.
It seems that it is supported in native, so I think it should be supported.
I have modal inside which I have a list of passengers who have scroll into view when clicked on a particular passenger. This works perfectly fine, but the body behind the modal also scrolls when this happens even thous I have frozen scroll using "overflow: hidden" CSS property. How to avoid body scroll.
Moving it out of #155 so this can be done in multiple PRs.
Element.scrollIntoView(ScrollIntoViewOptions)
spec and related draft specs instead of reinventing the wheel.Entirely new API, implementing Element.scrollIntoView(ScrollIntoViewOptions)
and {scrollMode: 'if-needed' | 'always'}
.
{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'}
{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".scrollMode
, block
and inline
.scrollMode
, block
and inline
.scrollMode
, block
and inline
.writing-mode
test, though we might have to skip making it pass in the initial release.boundary
test, should let you set the innermost scrolling box as boundary so unnecessary traversing up the tree can be completely avoided (awesome for performance).boundary
callback test, use to test that scrolling cross an iframe boundary (different realm) can work correctly.ponyfill smooth
test that the promise it returns can be awaited on correctly, and that errors don't end up in unhandled promise rejections.ponyfill smooth
should be cancellable, add the test even if the problem itself won't be solved in time for first release.http://www.performantdesign.com/2009/08/26/scrollintoview-but-only-if-out-of-view/
https://github.com/iamdustan/smoothscroll/blob/master/src/smoothscroll.js
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
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 π
I have some thing floating on the screen like header. I want to set a offset to scroll more and show the content behind the floating header out.
Description of options.centerIfNeeded
says:
Center the target if possible, and if it's not already visible. If it's not centered but still visible it will not scroll
Description of options.forceCenter
would be:
Brute force version of
options.centerIfNeeded
. This will adjust the scroll to center the target even if it's visible already
I discovered an apparent bug, where I have something like this:
scrollIntoView([HTMLElement], {
scrollMode: 'if-needed',
block: 'nearest',
boundary: document
}).then(() => { console.log('done') })
It appears that if the element doesn't need to be scrolled into view (or some other reason?), then the Promise will never resolve. Even if I change .then()
to .finally()
, nothing happens. No console.log is output. Meaning I can't chain scrollIntoView
s.
I didn't have this problem until the element I needed to check if it needed to be scrolled into view was sometimes the same height as the document.
This will be helpful if you have to sync scroll position of some elements.
Changelog haven't been updated since v2, and I'd rather not continue to update it manually.
It should be generated the same way release notes are generated during publish.
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
Using a curated preset maintained by
These branches will be created by Renovate only once you click their checkbox below.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
@sanity/pkg-utils
, @sanity/semantic-release-preset
, EndBug/add-and-commit
, compute-scroll-into-view
, prettier
, prettier-plugin-packagejson
, rimraf
, typescript
).circleci/config.yml
circleci/node 17
circleci/node 17
circleci/node 17-browsers
circleci/node 17
.github/workflows/ci.yml
actions/checkout v4
actions/setup-node v4
actions/checkout v4
actions/setup-node v4
actions/checkout v4
actions/setup-node v4
.github/workflows/prettier.yml
actions/checkout v4
actions/setup-node v4
actions/cache v4
EndBug/add-and-commit v9@61a88be553afe4206585b31aa72387c64295d08b
package.json
compute-scroll-into-view ^3.0.2
@sanity/pkg-utils ^3.2.2
@sanity/semantic-release-preset ^4.0.0
cross-env ^7.0.3
prettier ^3.0.3
prettier-plugin-packagejson ^2.4.3
rimraf ^4.1.2
typescript ^5.0.0
I now get node_modules/scroll-into-view-if-needed/typings has no default export.
I'm not sure if there is something I can do differently on my end. Any thoughts?
Smooth scrolling will return promises in the future: w3c/csswg-drafts#1562
Suggested implementation here is:
If the browser is returning a promise, pass it through and let the browser decide how it's resolved.
If the browser isn't returning a promise, but the behavior is set to "smooth", use Promise.reject
as there is no way of knowing when scrolling is complete anyway so userland code needs to handle both cases.
master
branch failed. π¨I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.
You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. Iβm sure you can resolve this πͺ.
Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.
Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master
branch. You can also manually restart the failed CI job that runs semantic-release.
If you are not sure how to resolve this, here is some links that can help you:
If those donβt help, or if this issue is reporting something you think isnβt right, you can always ask the humans behind semantic-release.
semantic-release cannot push the version tag to the branch master
on remote Git repository with URL http://[secure]@github.com/stipsan/scroll-into-view-if-needed.git
.
Please refer to the authentication configuration documentation to configure the Git credentials on your CI environment and make sure the repositoryUrl is configured with a valid Git URL.
Good luck with your project β¨
Your semantic-release bot π¦π
Hi, is there any way to know whether the scroll into view action has completed (promise resolution? a recommended timer approach?)?
the closest to this issue I found is #387 . Thanks!
The native webkit scrollIntoViewIfNeeded
supports this, and I need this for my app. If it's too hard to implement here, are there any alternatives?
I need to be able to scroll into view with block: 'nearest'
but with an offset. So this means I can have it scroll to the bottom of a div, but provide some buffer space below so the div isn't on the exact bottom of the screen. The center option is too drastic for my use, I just need a buffer of 30 pixels or so but still want it at the bottom of the screen.
I'm hoping there is a way to do this, but if not then this would be a feature request :)
Hi, there.
Because there is a banner above the scroll container, I need to set a target offset. I tried the behavior function implementation, but also wanted to use behavior smooth. How can we combine the two? Do you have any idea?
behavior: actions => {
const [{el, top}] = actions;
el.scrollTop = top - targetOffset
return scrollMotion ? 'smooth' : 'auto'; // works or not?
}
Hi,
I have a div at the top of my page that I need to scroll horizontally without changing the page vertical scroll.
Any ideas of the best approach to take ?
Cheers
If html's height set to 100% it scrolls to top, however scrollMode: 'if-needed'
works correctly, i.e doesn't perform scrolling when the scrolling element is visible.
Hi π Thanks for making this library!
I'm using it to scroll a list that has overflow-y: scroll
. However, when scrolling to an element on the bottom of this list the window is scrolled to the bottom as well. Is there a way to avoid this or is it a bug?
Wish there is an 'onScrollEnd' callback it will be used to set some state / trigger some events after the scrolling finished.
https://recordit.co/z3vQ93V1YP
Scrolling the parent also scrolls another ancestor higher up the DOM tree.
I understand this is the "standard" behavior even for the browser-implemented scrollIntoView
. Is there any way to prevent this? It would be useful if the method did what its name suggest ("ifNeeded").
2.2.8 is the last version that works for me (tried both Chrome and Safari). 2.2.9 and all later versions fail with:
scroll-into-view.min.js:1 Uncaught TypeError: Cannot read property 'clientHeight' of undefined
at n (scroll-into-view.min.js:1)
at r (scroll-into-view.min.js:1)
at scroll-into-view.min.js:1
Here is the failing invocation (elem
is neither undefined
nor null
):
scrollIntoView(elem, {
behavior: 'instant',
scrollMode: 'if-needed',
block: 'nearest',
inline: 'nearest',
});
Hey there, thanks for your job!
I would like to report that default function does not work on Safari macOS Monterey 12.3.1. The native function scrollIntoViewIfNeeded
does work.
Is there any fix we can do?
GSAP's ScrollToPlugin has a very nice option that lets you cancel a scroll when the plugin detects that the scroll position is being changedβi.e. if a user decides to scroll during the tween. Is it possible to support something like this with scroll-into-view-if-needed
?
Edit: See https://github.com/greensock/GreenSock-JS/blob/master/src/uncompressed/plugins/ScrollToPlugin.js#L122-L136 for reference
When importing your lib to an angular project (I tried it with 6.1.9 with a simple empty project created with ng new
) and running ng serve
it works fine.
When I run ng serve --prod
though, calling scrollIntoView
just does nothing. There are no errors on compilation or at runtime, but apparently minification/uglification destroys something essential.
There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.
Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.
Hope this was committed by accident, latest npm published version (1.2.5) is trying to execute yarn build
on npm/yarn install.
I have a React component render list chidrent inside a iframe (fixed height and scrollable). When i click on a child element i want to scroll it to center viewport. I use scroll-into-view-if-needed and it worked. but after update to version 2.2.19 it stop work without any error message. It work again when downgrade to version 2.2.15
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.