[csswg-drafts] [css-scrollbars][proposal] Add support for attaching native scrollbars to an element (#3397)

andyearnshaw has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-scrollbars][proposal] Add support for attaching native scrollbars to an element ==
There's currently no way to attach native scrolling capabilities to an element that does not overflow with other HTML content, for example a canvas element or an element that implements custom scrolling behaviour.  There are plenty of custom scrolling solutions out there, but these are generally inferior or inconsistent with native scrollbars. For instance, an element with no natural overflow does not receive scrolling events on mobile devices, "elasticity" and momentum scrolling add a lot of complexity to a component.  Custom scrollbars are also difficult to style like native scrollbars, forcing you to either use a style that is not consistent with native scrollbars on the page, or implementing themes for as many operating system/browser combinations that you care about.

A real world example is Google Sheets, which implements a custom scrollbar as the whole sheet is rendered on a `<canvas>` element for optimisation.  My own use case is similar, I'm working on a grid that can potentially have hundreds of thousands of rows and/or columns, which reuses DOM elements rather than overflowing the container.  We use a custom scrollbar to deal with this, but the issues around it are nontrivial to deal with.

My initial thoughts are to introduce a `Scrollbar` interface, and a new method, `Element.prototype.attachScrollbar(options)`, which returns an instance of the `Scrollbar`

```
enum ScrollbarAxis { "horizontal", "vertical" };

[Exposed=Window]
interface Scrollbar : EventTarget {
  readonly attribute ScrollbarAxis axis;
  attribute unrestricted double scrollValue;
  attribute unrestricted double thumbSize;
  attribute unrestricted double scrollMax;

  void addListener(EventListener? listener);
  void removeListener(EventListener? listener);
           attribute EventHandler onchange;
};

dictionary ScrollbarOptions {
  ScrollbarAxis axis = "vertical";
};

partial interface Element {
  Scrollbar attachScrollbar(optional ScrollbarOptions options)
};
```

Attaching to an element that already has a scrollbar would result in that element's scrollbar being hidden and the declared one to be used in its place.  This would allow you to do things like render a scrollbar that does not represent the element's true overflow -- like having a smaller thumb and a larger track area where "infinite" scrolling is implemented, for example.  The element would then become a scroll target, with the scrollbar dispatching cancellable change events when the element is scrolled by the user.  Ideally, the scrollbar's top/bottom or left/right positions could be defined via new css properties, so that it can be positioned between any fixed content.

I'm happy to do additional legwork here, such as writing the spec, if there is implementor interest.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/3397 using your GitHub account

Received on Wednesday, 5 December 2018 10:01:15 UTC