My experience with bad scrolling indicator UX
I think everyone found itself using an website or app and did not recognize that there is something to scroll to find the desired action.
One Popular example is the IOS share dialog. I remember some months ago when I switched from Android to IOS I was not able to figure out how to make the most basic things in Safari like adding something's to the bookmarks or performing a page search.
I complained to my Girlfriend that with Android I was able to perform searches on all possible websites and the feature in IOS is just not there. Furthermore, I could not understand that such a simple and basic functionality was missing in that popular OS.
Then she told me that I’m an idiot.
“Everything is in place, you just have to open the share dialog and scroll down”.
I was thinking: “ Why didn't I found that? I just had to scroll.“
Then I figured out that there was nearly nothing that showed me that I could scroll this dialog. There was just a small piece of the next button, but I never saw it.
For a great UX, the user should be always informed whether he can scroll a card or not. By that, your users would not miss amazing content you are writing or beautiful features you have build.
Do you know that you can also perform site search by just scrolling down? I didn’t till I Googled how to search on an iPad. Great example for not so great UX. The next item method does also not work here, since it is covered by the keyboard.
How to indicate a Scrollable Element
In general, there are 4 popular ways to indicate the possibility of scrolling.
Add a small piece of the next item
This is the most popular pattern. It is also the one that is the easiest to implement, but it has a major downside.
As already shown above, there could be cases where the next item is hidden by another Item above or some system specific item. (Like in the Safari share dialog). Or it is just not present enough that the User won't recognize it.
Another problem could be that the next Item disappears on some screen sizes. We had this in our project, where the next item disappeared for smaller screen sizes.
Indicate scrolling with an Arrow
You can place a small Arrow pointing in the direction where the user can scroll.
I Personally think this is a nice solution, since the User definitely will recognize it and will know what to do. The Implementation complexity is a bit higher than the next Item solution, and it will be also possible t implement it following this guide.
Indicate scrolling with Lights and Shadows
This is my favorite solution to this UX issue. You can place beautiful rounded shadows or lights to highlight the borders of a scrollable element in the direction where the User can scroll this element. This will give your application an intuitive UX and a modern Look and feel.
The Complexity will be higher than the next item method, but it will be nearly the same, as with the arrow indicators.
Indicate Scrolling with Shadows in Vue.js
As already mentioned, my favorite method to indicate scrolling is option three, the shadow scrolling. Hence, I will focus on this one in this guide. If you want to, you can easily replace the shadows with arrows or other fancy things. Be creative! The concepts will stay the same, you can simply switch the divs you show and the CSS for them. You will indicate a scrollable element you have previously built with a virtual scroller, for example with the one from vuetify.
Indicate scrolling for virtual scrollers in Vue.js
These components are incredible, the only downside is that directly accessing their plain HTML could be a pain, so implementing the scroll indicators like in this article would be a struggle. At least it was for me, till I found out how to adapt this example to work with virtual scrollers.
So, let's go through this step by step.
Set up the HTML to show Scroll Shadows
To make this work, you need to wrap your v-virtual-scroll or similar with a div.
Inside this div we will place two other divs, these are our shadows. One for top and one for bottom.
If you want to use arrows, lights or other elements to indicate instead, feel free to change the HTML elements as you want. Be Creative!
<div
id="shaddowScrollInd"
class="container off-bottom"
style="background-color: white"
>
<v-virtual-scroll
id="scroller"
bench="10"
:items="yourItems"
>
<template v-slot:default="{ item, index }">
<v-list-item :key="index" class="px-0" color="white">
<some-display-component
:content="item"
@select="$emit('select')"
/>
</v-list-item>
</template>
</v-virtual-scroll>
<div v-if="showTopShaddow" class="shadow shadow-top"/>
<div v-if="showBottomShaddow" class="shadow shadow-bottom"/>
</div>
Add some spice of CSS for the scroll shadows
As we have set up our HTML, we will now add some CSS to build our shadows.
There is not much magic inside. We will just build two rounded Black shadows.
We define the Shape of the specific shadow in the s-top and bottom classes with the box-shadow prop. use 1 to let it point down and -1 to let it point up.
Of course, you can change shapes, colors etc. to your or your client's preferences.
.shadow {
bottom: 0;
left: 0;
pointer-events: none;
position: absolute;
right: 0;
top: 0;
transition: all 0.2s ease-out;
}
.shadow-top {
box-shadow: 0 1em 1em -1em black inset;
}
.shadow-bottom {
box-shadow: 0 -1em 1em -1em black inset;
}
Finally, make the scroll shadows reactive with some JavaScript
At first, I think you already assume 😉 we will set up our two data variables to render the shadows.
data: () => ({
showTopShaddow: false,
showBottomShaddow: true
}),
// Methods
SetUpScrollShaddows() {
this.showTopShaddow = false;
this.showBottomShaddow = true;
const scroller= document.getElementById("scroller");
if (scroller) {
scroller.addEventListener("scroll", e =>
this.setShadows(e)
);
}
// may do some error handling here
},
setShadows(event) {
window.requestAnimationFrame(() => {
if (event.target.scrollTop > 0) {
this.showTopShaddow = true;
} else {
this.showTopShaddow = false;
}
if (event.target.scrollTop < 160) {
this.showBottomShaddow = true;
} else {
this.showBottomShaddow = false;
}
});
}
}
Then inside the methods section, paste the above code.
You should call set up scroll shadows when your scrollable object gets visible. (Otherwise, you can not add your event listener).
So depending on your component you can either call it inside your mounted hook or in some click listener or similar. Since my scrollable component is a Menu, I will call it inside the click listener that opens the menu.
We then will add a Listener to the scroll event of the v-virtual-scroll (or similar).
Where we are going to call setShadows
.
All setShadows
does is evaluating the scroll position inside the scroll element and setting our display variables according to it.
That's it! Now your users will know where they can scroll and where they can’t.
As a further step, I would recommend putting this component as a wrapper component and injecting the display components into it using slots.
So you will have a reliable component to indicate scrolling and improving UX everywhere across your application.
The resulting Scroll Indicators
We were going from something that does not look like it is scrollable.
To Something that is indicating its scrollable content in different directions elegantly.
Conclusion
When scrolling done right, it can Improve the UX of your app a lot! But you have always keep in mind that it is might not as obvious for your users that you can scroll here as it is for the developers. So please give your Users a hint that they can scroll there. This hint should also be in a clear way and should not depend on different screen sizes.
I hope I could give you a clear example on how to communicate the ability to scroll to your Users in a beautiful and understandable way.
Happy Scrolling,
Alex