Welcome to CrankyGoblin.Com Sign in | Join | Help

Public Class GeoffAppleby

Inherits Microsoft.VisualBasic.MVP : Implements IBrainFart
CSS expressions in IE (or, How to make a TBODY scroll)

Update:

A couple of months ago, I blogged about a cool way to make a HTML table body scroll in IE using CSS expressions.

That post is by far the most hit page I've written - it seems that many people are trying to figure this out. Since it's been so popular, I wanted a chance to redo what I posted before - I've learned a bit more since then, and I'd also like to address all the comments that have been left on the first post up to now. I've also discovered a new way to do the scrolling that doesn't require the CSS expression at all.

So I've written an article that (hopefully) explains it all. See it here :)

I've left the contents of this post alone (it starts just below), but you really do want to go and read the update - really! :)

So - onto the original post...

I've heard of CSS expressions before, and the msdn doco on it is pretty skimpy, so i never really knew what they were. They're not talked about that much, so i never found out.

But now i have. All i can say is that this is cool. Expressions in CSS are an IE 5+ only thing. This doesn't worry me, as our target platform that we target our applications at work already stipulates IE 5.5 or greater, and i prefer IE myself anyway. All you freaky firefox, mozilla, opera and safari wierdo scum just have to live without :P (don't flame me, i know you probably don't want it anyway - you've got tabs, what else is there to wish for in a browser? *grin*)

Anyway, we needed to make a TBODY scrollable at work. It's been done before, but normally involves two table tags. My partner-in-code found out about expressions however, and it amazed me at how much power you could have. (have i used that term before? I think it's a good way of referring to the guy i'm currently coding with at work :)

An example is probably best. I wanted this (roughly..this is a simple sample):

Col 1 Col 2 Col 3 Col 4 Col 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5

Depending on what you read this in, it might not render correctly. If you scroll the above table an the column headers scroll away, then try looking at this post in an IE browser.

And to do it, all that you need is this:

<STYLE type="text/css" media="screen">
    #container
    {
        border: solid 1px black;
        width: 50%;
        height: 150px;
        overflow: auto;
    }
    .noScroll
    {
        position:relative;
        top:expression(this.offsetParent.scrollTop); 
        background-color:white;
        font-family: Arial, Helvetica, sans-serif;
    }
    TH
    {
        text-align: left;
    }
</STYLE>
<div id="container">
    <table border="0" cellpadding="0" cellspacing="0" style="width: 100%">
        <thead>
            <tr class="noScroll">
                <TH>Col 1</TH><TH>Col 2</TH><TH>Col 3</TH><TH>Col 4</TH><TH>Col 5</TH>
            </tr>
        </thead>
        <tbody>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
        </tbody>
    </TABLE>
</div>

Pretty cool huh? End result: javascript in CSS. Even to the level of having the 'this' object available. Sweet.

A quick item of note: You really need to set the background color on the row you don't want to scroll - if you don't, it stays transparent, and you can see the scrolling text behind the thead. Whoops :)

Of course, now i'm worried about CSS based virus's. Perhaps *.css needs to be marked as an unsafe attachment in Outlook :)

Posted: Saturday, October 23, 2004 7:44 PM by Geoff Appleby

Comments

Scott Galloway said:

Works fine in Firefox so far as I can see...
# October 23, 2004 10:15 PM

Geoff Appleby said:

Really? Sweet.
# October 24, 2004 2:54 AM

Eric Neff said:

Firefox v0.9.3 didn't work
v0.10.1 didn't work either.

Otherwise this was a great tip that I will be using on my project immediately. This solves the problem of needing 2 tables and having to maintain the widths of both.
# October 24, 2004 10:31 AM

Mischa Kroon said:

It scrolls in FireFox it just doesn't leave the top column.
# October 25, 2004 1:00 PM

Geoff Appleby said:

Oh well, at least the page renders :)

I said you guys had to go without!
# October 25, 2004 1:27 PM

JosephCooney said:

To make the body scroll in firefox you go tbody style="overflow:scroll" - IE just makes you jump through hoops.
# October 25, 2004 4:07 PM

Geoff Appleby said:

Yes, this is exactly how it _should_ be in IE. IE's table implementation is pretty shoddy.
# October 25, 2004 4:48 PM

boconnor said:

Great solution, we've been trying to do this for quite a while... We'll be implementing it in all our web apps immediately too. It goes hand in hand with a resizeable div tag to limit amount of the table to display based on page size.

FYI found another solution similar that used javascript calculation instead of the expression... Author says it will work on more browsers, but I found it fails if you resize your screen to a small size...

<a href="http://www.imaputz.com/cssStuff/bigFourVersion.html">Another">http://www.imaputz.com/cssStuff/bigFourVersion.html">Another way</a> or
http://www.imaputz.com/cssStuff/bigFourVersion.html

Keep up the good work!
# November 2, 2004 7:39 PM

nira and alex said:

amazing !!!!

well done.

# November 3, 2004 11:40 AM

nira said:

there is a problem when adding
color to the div

<div id="container" style="background-color:yellow;">

the heading are flushing .

is any one have a solution ?
# November 17, 2004 7:23 PM

Donovan Marsh said:

If you have any "Select" boxes in the table it puts the select boxes on top of the Table head. Any idea if that can be fixed?
# December 7, 2004 10:29 PM

Michael A-P said:

Sorry for the "me too" comment but this is great. Just whay I had always been looking for.

To avoid using an Expression to change the TOP value of the header (hich is the bit that I IE5.5 specific as I read the post) could we not use JScript to modify the style via DOM when ever the page is resized/the object scrolled? Might work on more browsers.
# December 8, 2004 7:07 AM

Geoff Appleby said:

Donovan: Interesting - I'll have a ook at this tonight :)

Michael: I've been meaning to post an update to this. Thanks for the reminder :)
# December 8, 2004 7:12 AM

Martin Sundberg said:

Great! saved me a lot of hours

About the "SELECT" boxes. I solved this by a little javascript function. Not as nice as the rest, but working

function hideSelect(){
// loop through all SELECT elements
var elements=document.body.getElementsByTagName("SELECT");
for (i=0; i<elements.length; i++) {
var element = elements[i];

// get top of TBODY
var tbodyTop = element.parentElement.parentElement.parentElement.offsetTop;

// compare top of cell to original top of body
if (element.parentElement.offsetTop < (tbodyTop + Rightpane.scrollTop)) {
element.style.visibility = 'hidden';
} else {
element.style.visibility = 'visible';
}
}
}
# December 8, 2004 8:46 PM

G said:

Great!!
# December 14, 2004 7:10 PM

WStoreyII said:

WHAT ABOUT A FOOTER?

how can i make the footer static?

Thanks

WStoreyII
# December 16, 2004 10:09 AM

adi said:

Hi,
About the "SELECT" boxes. I didn't undertand how do you catch the scroll event , and what is the Rightpane.
# December 17, 2004 8:27 AM

David Carrington said:

Ta, I was using a alightly more long-winded "expression" to get IE to work with something that is very easy in Mozilla. "this.offsetParent.scrollTop" is better than "this.parentNode.parentNode.parentNode.scrollTop" by a long way.

Now I just need to figure out Opera too.
# December 21, 2004 1:40 PM

Geoff Appleby said:

parentNode.parentNode.parentNode? Sheesh!

Don't forget to read the article i linked to up the top. You don't need the expression anymore! (well, most of the time) :)
# December 21, 2004 2:23 PM

Martin Sundberg said:

On the "DIV" tag there is an event caller "onscroll" where you can call this function. "Rightpane" is simply my ID for the div-tag.

# December 21, 2004 2:29 PM

tim meehle said:

This SOOOO rocks!!!!
# December 30, 2004 6:05 PM

hima said:

how can i make the footer static.

Thanks.

# December 31, 2004 9:11 AM

Geoff Appleby said:

hima: If you read up the top, I've redone this post and gave link to a new article that discusses this all in more depth. Included in it i discussed static footers a bit too :)
# December 31, 2004 1:31 PM

chip said:

friggin' sweet... but would you happen to know what to do if you wanted to make the height of the table dynamic (i.e. a percentage of the page rather than a set pixel)? I have a parent <div> whose overflow:auto keeps taking precedence...
# January 4, 2005 12:47 AM

RP said:

Thank you! Works great!!!!
# January 5, 2005 5:34 PM

Sid said:

This is genius!!
# January 13, 2005 7:13 PM

Kevin said:

Why not juse use proper css and use overflow: scroll? Oh, wait, that would require designing pages for a web browser that isn't garbage.
# January 22, 2005 8:53 AM

Andrew said:

Can't see the header in IE 6, just a blank line which disappears when text is scrolled up.

Crap browser. Crap, crap, crap. It gets <colgroup> and <col> correct and that's the only thing it does better than Gecko- and KHTML-based renderers.

Crap.
# February 8, 2005 6:44 AM

Joe said:

Some of the styling is lost. cell borders are replaced by a transparent strip the same width as the border was. colors from the scrolling tbody show thru.

# July 21, 2005 11:36 AM

David said:

This causes a massive performance hit if you have a lot of rows in your table. Not recommended!
# July 7, 2006 4:40 AM

Jason said:

Hi,

Glad I found this page it's really cool! Thanks to all! I noticed that SELECTs render over the table head also and so did my client so I checked back on this page for further info. With regards to Martin Sundbergs' solution of hiding the SELECTs with a Javascript function I made a couple of changes to it:

function hideSelect(t){

// loop through all SELECT elements

var elements=t.getElementsByTagName("SELECT");

for (i=0; i<elements.length; i++) {

var element = elements[i];

// get top of TBODY

var tbodyTop = element.parentElement.parentElement.parentElement.offsetTop;

// compare top of cell to original top of body

if (element.parentElement.offsetTop < (tbodyTop + t.scrollTop)) {

element.style.visibility = 'hidden';

} else {

element.style.visibility = 'visible';

}

}

}

If you just then add onScroll="hideSelect(this)" your container it seems to work perfectly for me in IE >=6

# February 12, 2007 4:01 AM

flash tekkie said:

Any script execution at the Style Sheet stack of the browser is a performance issue and more importantly a security threat. No wonder it makes IE the most insecure browser on the market.

Good news is <a href="http://tekkie.flashbit.net/browsers/internet-explorer-dumping-css-hacks-to-comply-with-standards" title="Internet Explorer dumping CSS hacks to comply with standards">Microsoft is ending expressions in Internet Explorer</a> as announced on Thursday earlier this week making it a very nice move towards the standard-compliant browser.

# October 18, 2008 3:18 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

To submit your comment, click on these pictures:
  • Happy Geoff
  • Geoff's big sister's tongue
  • Searching Geoff
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Can't recognise the people in these pictures? Look here for a quick introduction.
There's a time limit for you to get your comment submitted before this set of pictures expires. If you think it's been longer than 10 minutes, get some new pictures first (you won't lose what you've typed so far).
Get some new pictures 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS