At the computer on my desk, there were three browsers in which to view the implementation. We viewed the implementation in the first browser.
“This browser is not keeping our checkboxes aligned between the header and the list!”, we said.
So, we viewed the implementation in the second browser.
“This browser also is not keeping our checkboxes aligned!”, we exlaimed.
So, we viewed the implementation in the last browser.
“Ahhh, this browser looks just right”, we said happily.
Okay, enough with the Goldilocks adapation. What the heck is going on and why?
Browsers and Scrollbars
The scrollbar seems to be a forgotten piece of browser-specific implementation that needs to be exposed through CSS.
There’s no way to reference browser scrollbar size through CSS. As you can see in the above screenshots, each browser does something a little different.
We could naively try to always turn scrollbars on, but then the problem becomes that the width of the scrollbar is different across platforms and browsers. And we’d still have discrepancies.
OSX has 0 width (or if you have an input device plugged in, a slim width). Firefox tries to implement its own thing using native styles (which makes it slim on OSX and wider on Windows) and IE9 goes even a little wider. This makes it very annoying when implementing a design like the above.
Do we need to resort to implementing browser-specific hacks or implement our own custom scrollbars across browsers?
Well, sort of. We do need to implement a cross-browser work around. Before we look at the fix, here’s the source markup that produces the above behavior.
A little bit of markup and a dash of styles. You can see this live in this jsfiddle: http://jsfiddle.net/zdennis/QsCDm/
Let’s dive right in and resolve the issue in a cross-browser manner.
First, we decided that we always have the list container show vertical scrollbars (but never horizontal scrollbars as we didn’t need them):
Next, we needed to find a way to add vertical scrollbars in the header. If we could achieve that, then those scrollbars could push the header checkbox in from the right enough to align them with the list.
In order to do that we introduced two containers in the header element:
The .scroll_holder will be used to house a scrollbar and the .actions_holder will be used to contain our original header checkbox. Both of these containers need to be floated right:
Now, the first container .scroll_holder needs to contain a scrollbar. It’s this scrollbar that will push the header checkbox in from the right enough to achieve alignment with the list checkboxes. However, we don’t want the scrollbar to be visible to the user. Let’s introduce a container to house the scroller inside of .scroll_holder:
Adding styles for .scroller will give us a scrollbar and then we can update the styles for .scroll_holder to hide it from the user:
We used visibility hidden because that will let our scroller take up space in the layout without being visible to the user. We also introduced a height on our .scroller so IE9 will indeed render scrollbars. Otherwise, it won’t because there’s no content.
If you refresh at this point it still won’t look right. There’s a style that’s in there from the original source that needs to get removed. It’s the style that made the header checkbox absolute positioned:
We’re getting close. The last style to add is to make sure the list’s li elements are positioned relative. This will fix the last bit of positioning:
The header checkbox is now aligned with the checkboxes in the list below:
And the final updated source:
You can see this live in this jsfiddle: http://jsfiddle.net/zdennis/pBGzq/
At the time I wrote this, the solution worked in Chrome, Safari, Firefox, IE, and Opera. It may work in others, but I didn’t test beyond the ones listed.
No bears or golden haired gals were harmed during the making of this post. Porridge may have been consumed, however.