Scrollbar Width Hack

Have you ever wanted to line something up with the right side of the content of an element with a scrollbar, but were frustrated because scrollbar widths vary by browser (including mobile ones where they might not be visible)? Yeah, me too. I just made a demo page of a hack for that. It creates an invisible element with a scrollbar on it for positioning.  This seems to do what I need right now.  What would be the best, but I don’t have an answer for, is a way to do something like this only taking into account whether the visible element with the scrollbar has a scrollbar or not.  My solution is to make sure it always does.  Doing the same thing when it might not is the next question.  I can think of a couple of ways to do this with JavaScript, but I wanted to do it with CSS.

My Warped Sense of Humor

Image

I get bored of right angles and since this is my blog, and I can do what I want with it, I’ve made some changes to the mobile design.  The base theme is Carrington-mobile-1.2. I added some of my own CSS to it to change the colors and to make it  more, well, me.  I used CSS3 to rotate some stuff.  Perhaps it’s a bit subtle.  I think someone is going to be holding his or her phone and twisting it around trying to make the lines straighten out, then wondering what’s wrong.  That might be really bad design, but it’s also funny.  I hadn’t intended to annoy anyone, just to do something a bit different and have some fun.

Safari Too-Big Border Radius Creates an Interesting Effect

div,article {
width: 540px;
display: block;
border: 1px solid #ccc;
background-color: #fff;
padding: 100px 20px;
margin-bottom: 20px;
-moz-border-radius-bottomright: 800px 100px;
-moz-border-radius-topleft: 800px 100px;
-webkit-border-bottom-right-radius: 800px 100px;
-webkit-border-top-left-radius: 800px 100px;
border-bottom-right-radius: 800px 100px;
border-top-left-radius: 800px 100px;
-moz-box-shadow: 10px 10px 5px #888;
-webkit-box-shadow: 10px 10px 5px #888;
box-shadow: 10px 10px 5px #888;
}

When Firefox has a border radius that’s wider then the container, it changes the curve.

Fixed Table Headers with wide non-breaking content

I just got a bug at work where someone in QA put
“adsfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasfasdfasdfasdfasdfasdf”
into content in a table. This is not “real” content, but it did break the layout. The problem is that it is non-breaking and won’t wrap, and tables can only be as thin as their thickest content in each column. If that had been “adfds adfad adfadsfasdf” etc. with spaces, it would have wrapped and been fine. If it had been a normal table, it would have gotten a horizontal scrollbar and been ok, if not beautiful. What is challenging is that the fixed-header and sorting schemes don’t play well with the horizontal scrollbars. I’m still experimenting with all of this.

http://salzerdesign.com/test/tableOverflow.html

Update: so far all the tables that I’ve tested break with really long non-breaking content. I have not seen a CSS or JavaScript solution that handles it with a fixed header.

Also, the Android mobile OS seems to break with the CSS fixed header, but iOS seems the same as the desktop version.

Conclusion: a fixed header table won’t work with a horizontal scroll bar.  Assuming there are both horizontal and vertical scroll bars, they should show at the same time so the user knows there is content in both directions.  To have both at once, they need to be on the same element.  If they are on different elements, one could be scrolled out of sight.  In order to have the header fixed, the CSS prevents it from scrolling vertically with the body.  Unfortunately, it also doesn’t scroll horizontally with the body.

The JavaScript methods of creating a fixed header have similar problems.

Sorry for the bad news!

Update 2: I added a second set of test tables to show when the CSS has
table {
table-layout: fixed;
word-wrap: break-word;
-moz-hyphens:auto;
-ms-hyphens:auto;
-webkit-hyphens:auto;
hyphens:auto;
}

What seems to happen (I haven’t tested very thoroughly yet) is that the columns become uniform in width and the content wraps even if it has no spaces. There are still problems with the table headers overlapping if they are long. Unfortunately, it seems like the table-layout: fixed is necessary for the td word-wrap to work. If you want the browser to size column widths to according to their content that’s another problem with this extra CSS.

Support for the hyphens is really spotty but they don’t do any harm. See post on http://www.456bereastreet.com/archive/201204/automatic_line_breaks_in_narrow_columns_with_css_3_hyphens_and_word-wrap/

Don’t Mess With Tables – Pure CSS Fixed-Header Left-Aligned Tables

See the Demo Page for examples and view the source for markup and CSS.

Update 9/3/13: I just added Zupa’s suggestion to the demo.

I am working on a project with a requirement for fixed-headers tables (the headers don’t scroll but the body does) which expand to fit the width of the page. We were using a JavaScript plugin which had to be called every time a page was loaded or resized. Last week one of the tables needed to have a second table within it, and I looked into CSS alternatives without JavaScript.

If you’ve ever tried to keep a table header fixed while letting the body scroll, you will find out that many solutions take the “stretch” out of the width of the table.  Tables are special and different from other HTML elements.  Browsers look at the table’s contents and then calculate from the inside out.  After much frustration, I decided not to mess with tables.

My solution is to mess with divs inside of tables. I took the divs inside the th and gave them “position: absolute; top: 0;“.  That pulls the div straight up to the top of the outer container and out of the flow of the table.  The rest of the table is a normal table and continues happily along.  The header divs retain the top left coordinate from the table, and you can even resize the page and see them shift with the columns. Unfortunately, the header divs completely loose the width they got from the th container.

My solution is a table with a scrolling body but fixed header, no JavaScript, and variable width and height.  Should you use this method? It all depends on the style of your table headers.

CONS:

  • All the problems are in the header styles.
  • No right or center aligned headers (unless you do something to set column width and hack the headers).
  • No using the column width in the style.
  • If text in a header is longer then the content in that  column it might look clipped. This is fixed by setting a min-width on the tds or content in that column.
  • The height of the table headers has to be a fixed height.
  • Horizontal scroll bars or really long non-breaking content breaks it (as well as most other methods of making a fixed-header table). (See full post.)

PROS:

  • Other then the table headers, the rest of the table is totally normal and without any hacks.
  • The table has flexible width and height.
  • No JavaScript needed, you can add JavaScript for other stuff if you like.
  • The browser will take care of everything for you on page load and resize.

SUPPORT:

  • It works in IE7+, FF, Safari, and Chrome, and Opera.
  • Some td or content in the tds need a minimum width if the header is wider then the column content.
  • IE6 has some bugs.

The th-inner divs can be styled within themselves, they can be given a fixed width, padding, margin, height, etc.  They just can’t depend on the width of the th, they use the outer container to calculate their width (which isn’t particularly helpful).  There seem to be some bugs in calculation the widths of spans within the divs as well.

I have styled a table using the jQuery plugin Table Sorter written by Christian Bach. (Please see his site for documentation. )  I used my method to keep the headers fixed but styled them to show the sorting.