Thanks! I'd to write a proper "How It's Made" article about it in the future, but this is basically how it's done:
There is a blank DOM node "scrollArea" in front of all others that catches the native JS scroll event.
It then converts these scroll offsets (scrollTop and scrollLeft) to cell/viewport coordinates, by default 40px actual pixels per row/column.
So if the scrollArea has a scrollLeft of 40px and a scrollTop of 200px , an underlying DOM node that renders the cell values and column lines, will render at viewport position {x: 1, y: 5}.
The other important part that makes it snappy, is that a viewport of let's say 20 rows by 10 columns does not actually consist of 200 DOM nodes. Only columns are DOM nodes. The values inside a column are made to look like rows by CSS white-space property. So it only updates 10 DOM nodes when scrolling.
There is a bug that is caused directly by this whitespace hack. If you copy two lines of text and paste it to one cell, it displays as two cells and shifts the column content below the affected cell (if the affected cell is in the viewport)
Yes, it is possible to paste cells in excel and shift cells below in Excel. But here the cells are shifted if the corrupted cell is visible and shift back if it's not. Definitely a bug.
Ah I think I know what you mean now. I think you mean when you paste multi-line text inside the cell value editor! You're right, thanks for spotting it!
This does not happen when you paste when the editor is not open, am I correct?
Hi janci, just letting you know that the bug has been fixed. Thank you for spotting it!
The current solution that I came up with: replace \n with Return HTML-entity. Not sure if that is the best solution for you (or anybody else) but at least it prevents the unwanted shift of column contents.
CSS Scroll Snapping doesn’t make scroll in steps like the steps() timing functions, it just controls the points that the eventual scroll position will snap to.
CSS Scroll Snapping may have a place for image gallery sorts of widgets, but for broader layout matters I strongly recommend against it: it can work tolerably on mobile (though it’s not without problems), but on desktop it seriously messes with scrolling so that on many devices it’s almost entirely problems.
Using a real scrolling area and observing what effect scrolling has upon it is the only correct way of rendering things. Then you could draw the contents in various ways—canvas (handle interactivity yourself), another DOM element behind the scrolling area (ditto), or a fancily-done `position: sticky` element that fills the visible part of the scrollable area.
Just remember that there are serious accessibility concerns about any of these sorts of things. Approach any sort of clever lazy loading of content with extreme caution.
Css native's scroll-snap was not useful in my case, but in the end DGXL's custom scroll snap was one of the easiest parts of the product to build. It was one of the things I really wanted to get right.
Using a <table> tag would always be best for accessibility reasons, but it's not an option if you want to create a performant data table with thousands of rows. I am still using HTML, not Canvas, so it is accessible, but it needs improvements.
A great relief is that this is an input-component first of all, to be used in admin-areas. So there's no need for SEO-compatible HTML.
If a user is trying to scroll horizontally, we can get the delta and get the scroll direction. Find the column width of the next/prev column and update the scroll property. An implementation can look like:
True, scroll snap does have some performance benefits: fewer moments to update the DOM.
You're probably browsing the site on your phone, am I correct? I created scroll snap to replicate desktop version of Excel & G. Sheets behavior. I agree that it is not the best option for smaller viewports/touch. It's on my todo-list to introduce smooth-scrolling as well.
That’s an interesting case because it’s certainly a cool effect, but it’s kind of a cumbersome UX on mobile. It makes it hard to keep track of the columns as you scroll up and down. At a glance it seems like both the Google Sheets and Numbers iOS apps have smooth scrolling instead of snapping.
I initially created scroll snap to replicate desktop version of Excel & G. Sheets behavior. I agree that it is not the best option for smaller viewports/touch. It's on my todo-list to introduce smooth-scrolling as well, so that scrolling DGXL on touch will work closer to native apps.
CSS Scroll Snap?
Nicely done.