tags:

views:

473

answers:

2

Before I explain what I'm trying to do, note that I have the good fortune of only having to target Webkit (meaning, I can use lots of neat CSS).

So, basically, I want to have a block with a flexible height, position fixed, maximum height being that of the available window height, with some elements at the top and bottom of the block that are always visible, and in the middle an area with overflow auto. Basically it'd look like this:

----------------------
| Top item  |        |
|           |        |
|   stuff   |        |
|           |        |
|           |        |
| Last item |        |
|------------        |
|                    |
|                    |
----------------------

----------------------
| Top item  |        |
|-----------|        |
|  lots   |^|        |
|   of    |_|        |
|  stuff  |_|        |
|         | |        |
|         | |        |
|-----------|        |
| Last item |        |
----------------------

Can it be done with CSS? Or will I have to hack it with Javascript? I'd be willing to accept a little div-itis if that's what it takes to make this work—better div-itis than trying to account for every stupid little thing like reflow and window resize and all of that nonsense.

I'm prepared for the bad news that this isn't something CSS can do, but I've been pleasantly surprised by the magic some folks on SO can work before.

+1  A: 

This looks like your ticket

Chris Serra
No, I think that does more or less the opposite of what I'm looking for. Gotta hit the sack, if it's still unclear in the morning I'll clarify the question.
eyelidlessness
Ahh, ok. So it starts off not at max height of the window, but can only reach the maximum height. Yeah, it was late for me last night too :)
Chris Serra
+1  A: 

Okay, I figured it out, using a bit of Javascript but none of the complexity that would be necessary if this were cross-browser. I'll post the answer in case anyone cares.

Markup:

<div class="complex-height">
    <div class="top"><!-- stuff --></div>
    <div class="middle"><!-- stuff --></div>
    <div class="bottom"><!-- stuff --></div>
</div>

CSS:

.complex-height {
    position: fixed;
    top: 0;
    left: 0;
    max-height: 100%;
    width: 300px; /* Can be whatever, but must specify a width */
    overflow: auto;
}
.complex-height .top, .complex-height .bottom {
    width: 100%;
    position: absolute;
    z-index: 2; /* make sure they overlap the center */
}
.complex-height .top {
    top: 0;
}
.complex-height .bottom {
    bottom: 0;
}

Javascript (assume Prototype, but is trivial to write straight up or to another lib):

$$('.complex-height .middle').each(function(middle) {
    middle.setStyle({
        paddingTop: middle.up('.complex-height').down('.top').getHeight() + 'px',
        paddingBottom: middle.up('.complex-height').down('.bottom').getHeight() + 'px'
    });
});
$$('.complex-height').invoke('observe', 'scroll', function(e) {
    this.down('.top').setStyle({
        top: this.scrollTop + 'px'
    });
    this.down('.bottom').setStyle({
        bottom: (0 - this.scrollTop) + 'px'
    });
});
eyelidlessness