Is it possible to customize the scrollbar

I would like to change the width and color for the scrollbar and have tried it with the settings as I did with the CEP panels. But unfortunately this does not work. Is there another possibility

::-webkit-scrollbar {
  width: 8px;
}

::-webkit-scrollbar-track {
-webkit-box-shadow: none;
    background-color: #262626;
}

::-webkit-scrollbar-thumb {
    border-radius: 0;
    background-color: #363636;
    border: 1px solid #262626;
    margin: 1px;
    -webkit-box-shadow: none;
}

Does anyone have an idea

No, unfortunately it’s not possible to style scrollbars in UXP.

Maybe you could try to make entirely your own. But it will take some effort.

If you do make your own and are in a sharing mood, I think the community would love to see what you come up with!

But as @simonhenke notes, there’s no CSS support for modifying the native scroll bars. (These are drawn entirely by the host [Ps or XD]).

I personally don’t think that building an own solution would be a great idea (in UXP), because…

  1. You can’t hide scrollbars. This means, you can’t make use of the native scrolling behavior. That’s how most of the custom scrollbar libraries for the web work, they just hide the original scrollbars and draw their own ones. Not possible in this case due to the z-index/always visible bug.

  2. onScroll or onMouseWheel events don’t work. This means even if you’d build your own wrapper component that hides excess content via overflow:hidden and write functions to move its content’s position, you couldn’t bind it to the scroll event. And nobody wants to scroll by dragging a scrollbar, that’s just bad UX :sweat_smile:

Actually, Textarea on windows does not have any scrollbar at all. So it would be an improvement. Now you can scroll only using keyboards and page up/down or selecting and dragging the text.

Can’t you just make it large and put it in a smaller container which is then scrollable?
Still not a great solution though, as you’d have to give it a fixed height.

I don’t know. Can I? It bothers me the most in the Alchemist plugin.

Maybe, but the results might be weird.

I’ve set up a small test component (react) to experiment with a custom scrollbar, it can definitely be built…

If anyone wants to use the code, i’ll attach it here, but I won’t keep on working on it. There’s a lot of things that need to be handled (horizontal scrollbar, hide scrollbars when content fits, clicking on the track, …) and the code probably has some flaws (had to use setTimeout to get the actual height of the children elements).
The better choice would probably be to use an existing library and adjust it to fit to UXP if necessary.

Scroller.zip (1.3 KB)

Could you use onLoad event instead of timeout?

Not sure about that in a React Context.
Usually, reading the height in componentDidMount or componentDidUpdate should be fine as it happens after the render, but it didn’t in this case. Maybe the props.children takes longer to draw, I don’t know.

It’s worth noting that this is one of those big differences between UXP and browsers – UXP’s DOM is not really synchronous. It looks like that most of the time, but layout is one of those places where it doesn’t.

UXP doesn’t calculate element sizes until a layout pass occurs, and those passes occur only when frames are generated. So if you add an element to the DOM, it could be upwards of 16ms before you see size information.

UXP tries to be helpful here: it will send a resize event your way when it’s safe to look at an element’s size, but of course you can use setTimeout or even requestAnimationFrame, but resize is the guaranteed method that works.

Of course, libraries made for the browser don’t do this, but they would have to be tweaked using timeouts or resize to work properly in UXP.

Ah that’s interesting and it does make more sense now why some solutions from Github or StackOverflow weren’t working, where they just added setTimeout(...) or setTimeout(...,1) to wait for the actual size. In my case I needed to wait about ~80ms.

That resize event you mentioned sounds perfect, will it be fired on the document or where else? (document.addEventListener('resize', () => ...) for eample?)

resize does not bubble, so you’d want to register the event listener wherever it makes the most sense; for a scroller like this, I’d put it on the scroll container.

even better, thanks!