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:
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.
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
Post a Comment