Custom scrollbar for variable height flex items

We recently moved our single page app layout to a fully flex based grid. As part of this we locked the app into 100vh, and in a number of places we use flex to create panels 100% high with a fixed header and footer and a flexible height scrollable panel in the centre.

See https://plnkr.co/edit/TX1iIKpVktnDjw6k8Bvc for a basic example of this. When targeting modern browsers the amount of css needed to achieve this sort of layout is refreshingly trivial - once you get your head around flex.

Once we had this layout in place we wanted to get rid of the ugly browser scrollbars, particularly on windows, and apply a custom scrollbar. We wanted preferably to do this in a way that made use of the native OS scrolling. John Kurlak at Microsoft discovered an easy way of hiding the native scrollbars across browsers a couple of years ago, and this still works well. However, in order to use this approach, and overlay a custom scrollbar,  the scrollable section needs to have a fixed height and width .... but in our fancy new flex panels the scrollable section has a variable height .... what to do, what to do ....?

Thanks to some help from simple-scrollbar for the initial scroll and drag handling setup I was able to set up an angular directive that detects the current size of the variable height flex panel and wraps it in a fixed size container and applies the custom scrollbar. The directive also sets up a window resize watcher and mutation observer to detect changes in the size of the scrollable section. If a change is detected the fixed size is recalculated.

I also added drop shadows to the top and bottom of the scrollable section to indicate to the user that there is scrollable content above or below.

A basic working example can be seen at https://plnkr.co/edit/p1ps6Nx0vyldiXVv4xlf - if viewed on Firefox on Mac you may notice some native scrollbar still - there is a fix for this, but for some reason plunkr seems to identify Chrome on a mac as mozilla so had to comment this fix out.

Todo:

The initial proof of concept custom scroller is working, but there is still some tweaking to do:
  • Tidy up the methods and move bulk of functionality into vanilla ES6 module and make the angular directive a wrapper only
  • Add horizontal scroll support
  • Remove dependency on ng-lodash
  • Add tests
The proof of concept directive can be found at https://github.com/glendaviesnz/variable-flex-scroll.

If there is another custom scroll module out there that uses native OS scrolling and works perfectly with variable height flex items let me know. I had a good look around at the options but couldn't find anything that met both these criteria.




Comments