adoxography / tailwind-scrollbar

Scrollbar plugin for Tailwind CSS
MIT License
972 stars 38 forks source link

Styling Window scrollbars using variants doesn't work on Firefox #62

Open brunoaugusto opened 1 year ago

brunoaugusto commented 1 year ago

For whatever reason, be it to manually trigger the Dark Mode or using Plugins that allow Theme Variants to be created, prevents, as much as I could test, this Plugin from working on Firefox.

In both cases, the general idea is to have the variant keyword as a class in the parent element that'll be styled. In order to target all elements, it's common to add such class in html or, at least, in the body. Since I'm migrating from Bootstrap to Tailwind, I kept the <html>:

html, body {
    @apply theme1:scrollbar-thumb-[#047857] theme1:scrollbar-track-[#003D30]
      theme2:scrollbar-thumb-[#191919] theme2:scrollbar-track-[#6B6B6B]
        scrollbar-thumb-[#6B6B6B] scrollbar-track-[#191919];
  }

  *::-webkit-scrollbar-track {
    @apply theme1:scrollbar-thumb-[#047857]
      theme2:scrollbar-thumb-[#191919]
        scrollbar-thumb-[#6B6B6B];
  }

  *::-webkit-scrollbar-thumb {
    @apply theme1:scrollbar-track-[#003D30]
      theme2:scrollbar-track-[#6B6B6B]
        scrollbar-track-[#191919];
  }

This styles everything correctly but, if I change (or add) the class theme1 in the <html>, I still get the default, unprefixed colours, described in the third lines.

If I remove the html, expression from the first instruction (Firefox) I get the browser's default colours. And inspecting the Element, as expected, there are no scrollbar styles attached to the <html>. Further down, inspecting the <body> I have:

.theme1 body {
    --scrollbar-track: #003d30;
    --scrollbar-thumb: #047857;
}

This is enough to style the scrollbars on Chrome, but not on Firefox, which makes me believe that to style the Window's (Element, not the OS, he-he) scrollbars, the scrollbar-color must be added to the <html>. However, with variants applied, the CSS being generated is .theme1 html instead of html.theme1.

I don't think it's possible to provide a demo on Tailwind Play, but I believe that setting darkMode: ['class'] on tailwind.config.js and then using dark: instead of the theme1 I mentioned, would allow you to test for yourself.

Thank you for your time and may you have a wonderful week :)

adoxography commented 1 year ago

In general, the scrollbar styling needs to be added to whatever element is overflowing, as that's the element that owns the scrollbar. From my own testing, though, it seems like Chrome will allow you to style the window's scrollbar by targeting either the html or body elements, while Firefox insists that the html element has to be targeted.

If the CSS selectors that are being generated look incorrect, though, my suspicion is that that has to do with the code that is generating the selectors, not this plugin. I'd suggest seeing if you can replicate the issue with a native Tailwind class (like bg-black), keeping in mind that since the body overlaps the html, the page might look right even if the selector's not.

brunoaugusto commented 1 year ago

Here you go, an isolated case with purely Tailwind's native manual Dark Mode.

On Chrome, the Window's scrollbar is colored purple/blue while Firefox retains the default styles. In the CSS panel, near the end, you'll see:

/*html,*/
body,
textarea

Removing the comment on html, will colour the scrollbars on Firefox too.

adoxography commented 1 year ago

Sorry, what I meant was see if you can replicate the behaviour with a native tailwind utility in place of scrollbar utilities; like I said, my suspicion is that the behaviour you're seeing isn't part of the purview of this plugin.

The utilities provided by this plugin style whatever element they're attached to. Firefox defaults to the html element being the thing that gets a scrollbar when the page overflows. If you're finding yourself in a situation where you have something generating CSS that can't target the html element, that's the responsibility of whatever's doing that class generation.

brunoaugusto commented 1 year ago

Here you go:

@layer base {

  html,
  body,
  textarea {
    /*@apply scrollbar-thin;*/
    scrollbar-width: thin;
  }

  ::-webkit-scrollbar-track,
  ::-webkit-scrollbar-thumb {
    @apply rounded-md;
  }

  ::-webkit-scrollbar {
    @apply w-1.5;
  }

  /*html,*/
  body,
  textarea {
    /*@apply scrollbar-thumb-[rebeccapurple] scrollbar-track-[cornflowerblue];*/
    scrollbar-color: cornflowerblue rebeccapurple;
  }

  *::-webkit-scrollbar-track {
    /*@apply scrollbar-thumb-[rebeccapurple];*/
    @apply bg-[rebeccapurple];
  }

  *::-webkit-scrollbar-thumb {
    /*@apply scrollbar-track-[cornflowerblue];*/
    @apply bg-[cornflowerblue];
  }

  p {
    @apply mb-4 text-black dark:text-white;
  }
}

And a Diff Check of the compiled styles.

I might've inverted some colours, sorry

Thing is, as much as I know, Tailwind doesn't have native utilities for scrollbars. I could create a scrollbar-thin counterpart in a @layer utilities, but the scrollbar-color would require a custom Plugin because of the colours — reason why I was looking for a scrollbars Plugin, since I don't know how to create them (yet).

With the code above, I had the same results: working on Chrome/Firefox with the html, and Chrome only without it.

All in all, it's really not your Plugin's fault. It's either Chrome accepting something Firefox is strict about; or maybe being too lenient about the correct spec Firefox outlines. Maybe, you could add a new configuration option, say, forceWindow to force an html, to be included along the body if scrollbar-thumb-* / scrollbar-track-* are being added there — which, IMHO, would imply the Plugin users are trying to change the scrollbars of the entire window.