Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Element With A Display of 'Table-Cell' Won't Fill Available Space Like A Table Cell

Tags: modal left height

Element With A Display of 'Table-Cell' Won't Fill Available Space Like A Table Cell

Problem

UPDATE APRL 30: I've decided against the javascript solution. The only way to make sure it always works is to put it in setInterval() going every few seconds. Don't want to do that. I know this CSS is possible, I've seen it work. I'll re-open the bounty for more like 150 if it ends.

So I've got this little Modal popup. It's made up of 2 sections; left and right. Within both sections are a label above and the content below. The label is fixed at a certain number of pixels, but the bottom area needs to be able to fill the remaining space, so I'm using display:table on the left and right sides and table-cell on the inner sections to achieve this "fill remaining space" effect. It works great in Chrome and Safari:

http://hashtraffic.com (Hit "try" and then click one of the hashtags)

Here's the CSS magic:

#tagBoxLeft,#tagBoxRight {
    display: table;
    height: 100%;
    width: 50%;
    position: absolute;
    right: 0;
    opacity: 0;
}
#tagBoxLeft { left: 0 }
#tagBoxDescription {
    display: table-row;
    -webkit-border-top-left-radius: 20px;
    width: 100%;
    word-break: break-all;
    word-wrap: break-word;
    -webkit-box-shadow: 0 1px 0 #FFF;
    -moz-box-shadow: 0 1px 0 #FFF;
    box-shadow: 0 1px 0 #FFF;
}
.nano {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    display: table-cell;
}
#taglabel {
    display: table-row;
    z-index: 10000;
    border-top: 1px solid #FFF;
    width: 100%;
    height: 39px;
}

And it just makes a bunch of divs into a table so they can have heights that are relative to each other. Also notice that the left and right sides are relative to the browser window, so that's why I can't just use percentages.

THE ISSUE IS that in Firefox & opera, the #tagBoxLeft and #tagBoxRight sides sections refuse to accept height:100%; while they have display:table;. So then it won't force the bottom sections up responsively. I've got a jsfiddle demo that works in both Firefox & Opera, so I know it's possible: http://jsfiddle.net/Qxswa/ But why does all my content overflow in Firefox and Opera?

Here's a screenshot of the issue: http://cl.ly/G0iP

Thanks!

Problem courtesy of: alt

Solution

Here's an alternative to using display:table and friends, which uses the oft-neglected ability of absolutely positioned elements to have both their top and bottom (and left and right) values set. It essentially 'sticks' the top and bottom edge, giving you a height relative to a container, but without explicitly setting a height.

UDPATED: As Jackson mentioned, the CSS-only version of this code doesn't provide an auto-height, fixed panel in the column. A simple bit of JS will fix that - you'd just need to set a sensible default height for users without JS. The JS only needs to run when you load the modal, not at intervals.

Here's the updated fiddle: http://jsfiddle.net/cxY7D/5

and here's the simplified HTML:


and CSS:

body {
      background:#444;
    }
     #modal {
       background:#FFF;
       position: absolute;
       top: 4em;
       bottom: 4em;
       left: 6em;
       right: 6em;
     }

     #modal .left,
     #modal .right {
       position:absolute;
       top: 0;
       bottom: 0;
     }

     #modal .left {
       background:#ACF9E4;
       left: 0;
       right:50%;
     }

     #modal .right {
       background:#FCFFCD;
       right: 0;
       left:50%;
     }

     #modal .contents {
      position:absolute;
      top: 0;
      bottom: 0;
      width: 100%;
      overflow-y:auto;
     }

     #modal .description {
       height: 8em;
     }

     #modal .description + .contents {
       top: 10em;
   }

     #modal .header,
     #modal .description,
     .contents li {
       border-bottom:1px solid #CCC;
       padding: 1em;
     }

     #modal .description dt {
       float: left;
       padding-right: 1em;
     }

It's a really useful and robust technique. A lot of people get the shudders when you mention 'absolute positions', but used like this, it's really liberating!

The JS (assuming jQuery)

$(function(){
    $('#modal').on('display', function(){
        //Calculate the height of the top left panel, and provide the remaining space to the bottom left
        var leftColumn = $(this).find('.left'),
            descriptionHeight = leftColumn.find('.description').height('auto').outerHeight(); //Set the height to auto, then read it

        leftColumn.find('.contents').css('top', descriptionHeight)//Apply the height to the scrolling contents pane     
    });

    $('#modal').trigger('display');
});​

The JS resets the top-left pane to auto-height, then reads the height and applies it as the top co-ordinate of the bottom-left panel. It's applied as a custom event, so you can trigger it as part of your modal display code.

Here's an answer I gave, using a similar technique, and more explanations of the hows and whys: The Impossible Layout?. Check the A list apart article for more discussion, and some simple fixes that make it work in IE6 (if you care about that).

Solution courtesy of: Beejamin

Discussion

View additional discussion.



This post first appeared on CSS3 Recipes - The Solution To All Your Style Problems, please read the originial post: here

Share the post

Element With A Display of 'Table-Cell' Won't Fill Available Space Like A Table Cell

×

Subscribe to Css3 Recipes - The Solution To All Your Style Problems

Get updates delivered right to your inbox!

Thank you for your subscription

×