Using calc() with tables

17,480

Tables have difficult rules about distributing the space of the columns because they distribute space dependent on the content of the cells by default. Calc (atm) just wont work with that.

What you can do however is to set the table-layout attribute for the table to force the child td elements to get the exact width you declared. For this to work you also need a width (100% works) on the table.

table{
   table-layout:fixed; /* this keeps your columns with at the defined width */
   width: 100%;        /* a width must be specified */

   display: table;     /* required for table-layout to be used 
                          (since this is the default value it is normally not necessary;
                          just included for completeness) */
}

and then use plain percentages on the remaining columns.

td.title, td.interpret{
    width:40%;
}
td.album{
    width:20%;
}

After using up the space for the fixed width columns, the remaining space is distributed between the columns with relative width.

For this to work you need the default display type display: table (as opposed to say, display: block). This however means you can no longer have a height (including min-height and max-height) for the table.

See your modified Example.

Share:
17,480

Related videos on Youtube

Marc Becker
Author by

Marc Becker

Updated on July 15, 2022

Comments

  • Marc Becker
    Marc Becker almost 2 years

    I'm trying to get a table with fixed-width tds and variable-width tds.

    Im using the CSS calc() function, but somehow it seems like I can't use % in tables.

    So that is what I have so far:

    <table border="0" style="width:100%;border-collapse:collapse;">
        <tr style="width:100%">
            <td style="width:30px;">1</td> <!--Fixed width-->
            <td style="width: calc( (100% - 230px) / 100 * 40);">Title</td> <!--Width should be 40% of the remaining space-->
            <td style="width: calc( (100% - 230px) / 100 * 40);">Interpret</td> <!--Width should be 40% of the remaining space-->
            <td style="width: calc( (100% - 230px) / 100 * 20);">Album</td> <!--Width should be 20% of the remaining space-->
            <td style="width:80px;">Year</td><!--Fixed width-->
            <td style="width:180px;">YouTube</td><!--Fixed width-->
        </tr>
    </table>
    

    How I see it, it should work, but it isn't.

    Does anybody know how to solve this? Or maybe has an other suggestion how I could reach my goal?

    • Axente Paul
      Axente Paul about 11 years
      I wouldn't use calc yet :) Wait at least 6 more months until the support for cal reaches every browser, this way you'll avoid lot's of compatibility issues. For different TD width's try to use <colgroup>. Have fun.
  • Christoph
    Christoph about 11 years
    firefox dropped the prefix somehere with version 18 or so, chrome also dropped it some while ago. So you only need the -webkit prefix for safari. Opera does not support this at all.
  • He Hui
    He Hui about 11 years
    ahh. I didnt know that. Regardless of the syntax though, his approach does not have a solution with calc.
  • Christoph
    Christoph about 11 years
    incidentally the width of one column should be 20%, so it sums up to exactly 100% of remaining space, which in theory should work out fine. The problem just lies in the nature of tables distributing the space of the columns dependent on the content in the default table-layout setting.
  • He Hui
    He Hui about 11 years
    technically, if each column is 20%, then you could just set 20% width. Why use calc at all right?
  • Christoph
    Christoph about 11 years
    OP wants to have some colums with a fixed width and the rest of the columns shall occupy the remaining space in 4|4|2 distribution. That's why he is using calc to calculate the remaining space of the table.
  • Lawrence Dol
    Lawrence Dol over 9 years
    I really wish that it worked this way, but on at least current FF (35) and GC (40) it doesn't. Putting in the percentages squashes the width of the other cells to their minimum render width as if "auto" was set. Perhaps because my first row, where I am setting the widths, is a header row (th cells)??
  • Christoph
    Christoph over 9 years
    @LawrenceDol let me see your example and we will figure it out together.
  • Lawrence Dol
    Lawrence Dol over 9 years
    @Christoph: It seems like the crucial missing factor is that the table must have a width set; setting width:100% resolves my problem and causes the fixed layout to work as expected.
  • Lawrence Dol
    Lawrence Dol over 9 years
    The other mistake I had made was setting the table to display: block to get it to respect a min-height. It must be display: table to have the fixed layout respected.
  • Christoph
    Christoph over 7 years
    @LawrenceDol A table should never have another display type than display:table. If it does, there is something wrong and probably different markup (most likely plain divs) should be used. Also, nowadays the flex-box layout can be used to take care of a lot of things which "in the old days" were accomplished by table layouts. But thanks for the edit, the width indeed is an important factor!