2

The basic problem has been raised many times in this forum but never satisfactorily answered, IMO. How to stretch a div within a table cell so that it fills the cell (vertically, horizontally or both)?

Make a div fill an entire table cell

Stretch div to 100% of height in a table cell

Streching div vertically inside a table cell

How can I scale a div to 100% height and width inside of another element

Full height div inside td

100% height div inside a display:table-cell div

etc., etc.

Yes I'm aware I will be regarded as yet another fossil for thinking in terms of embedding divs within table cells when I should be creating tables entirely by elegant CSS, as extolled by Rachel Andrew and Kevin Yank in Everything You Know About CSS Is Wrong! (2008). But after trying out what they and others have written, I'm less than impressed. The secret of their "success" revolves around relying on the display:table family of attributes to create a CSS "table", so what do you end up with? A div (box) acting like a table, table row or table cell. You can't make its corners rounded (one reason why I need to embed a div within a table cell), there's no provision for spanning rows and columns (which I need) and you can't stretch any enclosed div to full height without embedding it within another box or table, so you're back to square one as far as this problem goes. Tables don't make good divs, and vice versa.

As someone in one of the above linked posts mentioned, the basic problem is that table cells don't volunteer their height in pixels to any contained div, so including "height:100%" or even "min-height:100%" in the stylesheet with no other workaround will be ignored. Cells are cells and divs are divs, and never the twain shall meet, unless you're handy with Javascript, which I'm not. I simply wanted a non-script, robust markup to make the vertical height of a particular div match that of the enclosing table cell, so that if adjacent cells were higher, my div would stretch as the whole row stretched, to maintain 100%.

I didn't want to use position:absolute; top: 0; bottom: 0 with a defined cell height in pixels, since the row height will depend on the height of whichever cell is tallest.

Well, I thought I'd actually achieved the holy grail, as follows. Here is a one-row table containing 3 divs (actually navs in HTML5). I want the middle (i.e., second) one to stretch to the full height of the row. (Added - So that as text is appended to, or deleted from, columns 1 or 3, thus extending or contracting the vertical height of the whole row, column 2 will always remain at the full vertical height of the cell enclosing it. This means extra whitespace (pink space, see code!) below the text if an adjacent column contains more text. Also, it doesn't matter if column 2 contains more text than columns 1 or 3; they can shrink as far as I'm concerned.)

    <!DOCTYPE html>
  <html>
  <html lang="en">
    <meta charset="utf-8">
    <title></title>
    <link href="style4.css" rel="stylesheet">
  </head>
  <body>

    <table id="tbl_main" border="1" style="width:60%; table-layout:fixed">
    <!-- Creates columns of equal width -->

      <tr class="v_align_top">
        <td><nav id="col1" class="normal">COL 1 Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.

  Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus. </nav>
        </td>

        <td height="100%">
          <table id="tbl_inner">
            <tr>
              <td style="height:100%">
                <nav id="col2" class="vstretch">COL 2 Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.
               </nav>
             </td>
            </tr>
          </table>
        </td>

        <td><nav id="col3" class="normal">COL 3 Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.</nav></td>
      </tr>
    </table>

  </body>
</html>

and here's the CSS:

#tbl_main {
    border: 1px solid black;
    border-collapse:collapse;
}

#tbl_inner {
    border: 1px solid black;
    border-collapse:collapse;
  height:100%;  /* min-height doesn't work here */
}

tr.v_align_top{
    vertical-align: top;
}

.normal {
    border-radius: 20px 20px 20px 20px;
    border: 3px solid rgb(0, 0, 0);
    padding: 10px;
}

.vstretch {
    border-radius: 20px 20px 20px 20px;
    border: 3px solid rgb(0, 0, 0);
    padding: 10px;
}

#col1 {
    background-color: rgb(220, 220, 220);
    margin:5px;
}

#col2 {  /* stretch to 100% height of table cell */
    background-color: rgb(255, 220, 220);
    margin:5px 5px 5px 5px;
  height:100%;
}

#col3 {
    background-color: rgb(220, 220, 220);
    margin:5px;
}

(added) You can play with it here: jsFiddle link

Here's how it looks (Firefox 10 on Windows 7):

3 cell table

Unfortunately, as I haven't made enough posts yet to have earned the right to post a picture directly, you will have to make do with this link.

I deliberately made the table borders visible. Oops. The middle div extends below the enclosing table, by the same number of pixels, it seems, no matter whether I add or subtract text from Col 1. How bizarre. Reducing the height of #col2 to, say, 95% is not a solution as it is only a fluctuating approximation.

So near and yet so far. I have tried everything I can think of, from bottom-margin: -10px to border-spacing: 20px without solving this. Can anyone suggest an answer, or maybe come up with a bit of simple Javascript to solve it once and for all? Big thanks in advance.

Community
  • 1
  • 1
maximus
  • 165
  • 2
  • 7
  • I don't see them stretching at all in [this fiddle](http://jsfiddle.net/jgoemat/nS2ar/), is there something I'm missing? – Jason Goemaat May 26 '12 at 06:27
  • (I also added a fiddle (see my post) before noticing your reply. They both appear the same.) – maximus May 26 '12 at 07:42
  • (I also added a fiddle (see my post) before noticing your reply. They both appear the same.) The purpose of the code is to make the middle (pink) column stretch to match the longer of the two grey ones, in this case the left hand one. If you for example cut out the last paragraph in Col1, this will shorten the column, and the middle one will also shorten, but the match will never be exact (always by the same amount of overlap of Col2). I would like to adjust Col2 so that its length (curved corners and all) exactly matches that of Col1. – maximus May 26 '12 at 07:50
  • Are you just trying to create [three equal height columns](http://jsfiddle.net/robertc/tSRJ3/) or are you aiming for something more complex than that? – robertc May 26 '12 at 09:56
  • @robertc: I'm not aiming to create three equal height columns. I want the height of the second column (the pink one) always to fill its table cell vertically. The height of the table cell, like all the others in its row, adjusts to match the height of the tallest cell within that row, i.e., the one with the most data. This is a cut-down version of a more complex design, but if I can get this part right, the rest will fall into place. Hope this answers your question. – maximus May 26 '12 at 13:57
  • I'm not really clear what the difference is between what your saying and 'three equal height columns'? You want the second column to be equal in height to the tallest column - that's one of the other two, so we've got two equal height columns, what do you want the third one to do? – robertc May 26 '12 at 16:35

2 Answers2

1

Here is my solution to that issue: Table stretched by content height

The original idea starts here

table
{
    table-layout: fixed;
}
Andrey Hohutkin
  • 2,703
  • 1
  • 16
  • 17
0

Height is exclusive of margins, so your 100% really means 100% + 5px top margin + 5px bottom margin. I couldn't get it to display like yours on chrome unless I took out your table in column 2 and made the nav display: inline-block. I added padding-bottom: 10px to that table cell and it looks good to me:

Fiddle: http://jsfiddle.net/jgoemat/4wFJH/1/

Jason Goemaat
  • 28,692
  • 15
  • 86
  • 113
  • Thanks Jason, I took a look at your fiddle but it doesn't solve my problem :( . To solve it, the center column needs to extend the full vertical width of its enclosing table cell, i.e., match the height of the first (leftmost) column, which is the tallest. Your comments about the margin are relevant. I need to reduce the bottom margin of column 2 by a certain number of pixels so that it will be level with the bottom of column 1. I tried a negative margin-bottom setting but this doesn't work. Has anyone any other suggestions? Thanks. – maximus May 26 '12 at 14:02