Feed Icon RSS 1.0 XML Feed available

Workaround for Firefox 2 Scroll Bar Bug on Mac

Date: 6-Nov-2007/4:30

Tags: , , ,

Characters: (none)

Firefox 2 on the Mac has an unfortunate bug #187435, which makes the scroll bars on lower regions "bleed through" and overwrite the areas above them. On traditional web pages that aren't doing much tricky stuff, it will be only a minor visual nuisance. But it seriously impacts sites that are pushing the envelope of what HTML layout can do--like Mocha or the Extjs Web Desktop Demonstration:
Firefox 2 Scrollbar Bug on Mac
Apparently on the server side, it's possible to adapt one's code using the overflow:auto attribute, though it can be tricky to implement:
Working with overflow:auto on elements can be a pain, since your height and width need to be precise, and different browsers need different amounts of margins to prevent triggering the scrollbars. The scrollbar problem was a good chunk of the UI dev work on jjot.com.
So sometimes this method won't be right for you, and a client-side fix for Firefox 2.0 would help. I have a workaround that patches the Firefox browser using a theme. All you have to do is download this file and drag it into the themes list you get when you go to the Tools->Add Ons menu:
download aqua-scrollfix-together-1.0-fx.jar
When installation is complete, go back to the menu and and click "Use Theme".
Note
If you have your Appearance palette set with scroll buttons to be "Top and Bottom" style instead of "Together", then you'll want to download this instead:
download aqua-scrollfix-topbottom-1.0-fx.jar
A smattering of other themes you can find on the web will also incidentally work around the problem, but these two are intended for those Mac users who don't actually want to change the appearance of the browser. They're exactly the code for default Firefox in every aspect but scrollbars. The only caveats are:
  • The workaround is using a theme, and Firefox doesn't let themes draw inactive scroll bars differently from active ones.
  • It's not a perfect pixel match for the Aqua scrollbars--bear in mind, we're simulating them with quirky CSS. But it's close enough that most people won't notice. If there's enough interest to warrant trying harder to match more exactly, I'll cross that bridge at that time.

How does it work?

Firefox has the default behavior of delegating the drawing of scroll bars to the operating system. The bug in question arises from a miscommunication about rendering priority. So if you provide enough information in the skin that it can draw scroll bars on its own and not call the OS, the problem just goes away.
Implementing skinned scroll bars requires you to provide bitmaps that serve as the pieces of the scroll bar control. To give you an idea what these pieces look like, let's examine some of the ones from the MacFox II Aqua theme by Kelly Cunningham, which uses graphics made by Alex W. If you bothered to rename the .jar file to a .zip and unzip it, here's some of what you'd find in the global / scrollbar / directory:
MacFox scrollbar parts
One must take special care because on Mac OS/X, the description of how these parts integrate is in the theme file global / nativescrollbars.css. For all other platforms it is in global / xulscrollbars.css. If you aren't going to have different behavior on different platforms, then you can set the contents of both those files into a 1-line shortcut that references a central global / scrollbar.css file:
@import url("chrome://global/skin/scrollbars.css");
MacFox II doesn't do this, because it delegates to the OS if you're on a Mac. This means it still has the bug. So I changed it to always draw the scroll bars, which quickly exposed another problem: the position of the buttons was being assumed to be "Together" on the same side of the thumb, while the graphics were drawn for being on the "Top and Bottom". (This is something you can set in the Appearance palette of the System Preferences.)
To unmangle the scroll buttons, I used a tip from an article about scrollbar tweaks to position them the way the MacFox theme had expected. Yet I now realized I would need to make two variations--one for each possible user preference. Since I couldn't find an existing theme with graphics and logic for the modern OS/X curved buttons "Together", that meant making my own.
I was unfamiliar with CSS, so the files were hard to edit at first. Especially since almost all the themes I looked at contained patterns like this one (from MacFox's global / scrollbars.css):
scrollbarbutton[type="increment"] {
    position: absolute;
    margin: 0px 0px 0px -9px;
    min-width: 24px;
    min-height: 15px;
    background: url("chrome://global/skin/scrollbar/right_cut.png");
}
/* line 99 */
scrollbar[orient="vertical"] > scrollbarbutton[type="increment"] {
    position: absolute;
    margin: -9px 0px 0px 0px;
    min-width: 15px;
    min-height: 24px;
    background: url("chrome://global/skin/scrollbar/down_cut.png") no-repeat bottom left;
}
What this is saying is roughly:
  • Rule #1: All scrollbarbuttons you might find in the universe that increment the property to which they are attached--regardless of context--should be painted with the icon right_cut.png using the following attributes.
  • Rule #2: Oh...wait...!! There's one context where that's not the case. Override it if it's a scrollbarbutton that increments and happens to be enclosed in the context of a vertical scrollbar, and use down_cut.png with these other attributes.
This is--in my view--an abuse of the inheritance mechanism. If you don't remember to override all the characteristics you added to scrollbarbutton that gave it universal "horizontalness", those attributes will get inherited by the vertical case, causing unexpected defaults to appear as you modify lines of code. It's much better to have two narrow rules that apply explicitly to horizontal and vertical scrollbar contexts. (This is especially true because there are other places in Firefox that scrollbarbutton might appear and need to be handled differently.)
After fixing general problems of that type, I was able to more clearly determine what each line did. Eventually I discovered the position: absolute characteristic was not affecting position, but was indicating that those parts should be drawn in a higher Z-order than the relative pieces. The usages of negative margin values was to make sure they overlapped a little bit, to allow for what I call the "nestling" of the thumb into the buttons.
I had to be a little tricky with the graphics to implement the curved gutter at the edge of the scroll bar region. This involved putting a bit of empty space at the end of the thumb so that it would hit the edge prematurely, leaving the gutter showing. I mixed in some bitmaps from screen captures in a way that didn't look too horrible--but my goal was only to do approximately as good a job as MacFox had done with the buttons "Top and Bottom". If a better pixel artist wants to take this on and improve it, that would be great.
So there is the story. Beyond just addressing the problem I started out with, I think the source is reworked enough to be a nice place to start for anyone who is going to try theming scroll bars on their own. To assist with that, you can download the source to the scrollbar CSS files here:
  • aqua-scrollfix-together-1.0-fx.jar / global / scrollbars.css : view CSS
  • aqua-scrollfix-topbottom-1.0-fx.jar / global / scrollbars.css : view CSS
Feel free to ask questions if you have them!
Business Card from SXSW
Copyright (c) 2007-2015 hostilefork.com

Project names and graphic designs are All Rights Reserved, unless otherwise noted. Software codebases are governed by licenses included in their distributions. Posts on blog.hostilefork.com are licensed under the Creative Commons BY-NC-SA 4.0 license, and may be excerpted or adapted under the terms of that license for noncommercial purposes.