Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I limit the table width to the containing element (or screen)?

I need to show tabular data using a table, but it will be within a fluid layout; I want to have a it fill the entire available width but not to expand horizontally beyond maximum screen-width, such that the body does not get a horizontal scrollbar. Instead the too wide td elements shall get the scrollbar.

In the example there is DATA in the table, the table has border:1px solid black and the output shall be for easy parsing when piped from curl as well (hence the white-space:pre); The div is just the normal CSS layout helper, if possible let's get rid of that, too!

The important part is, that it shall be no fixed pixel width layout type, and the table shall be smaller than the available width in case the data does not need that much room. So to sum it up, a plain table which just does not get wider than the screen. Ideally the table would only stretch the parental element until the max-width of that enclosing element is reached and then do not get wider.

In Chrome, with something I consider to be an evil hack, I got to keep the table at the maximum width available and to display the scrollbars on the td if needed. However this does not work for FF, nor is that solution something which can be considered a correct one.

Following example of that can be found at https://hydra.geht.net/table-quirx.html for a while:

.nw             { white-space:nowrap }
.quirx div      { width:100%; max-width:100%; white-space:pre }
.quirx td       { max-width:90px; border:1px solid black }
.quirx td+td    { max-width:500px; overflow:auto }
table.quirx     { width:100%; max-width:100%; border:1px solid black; border-collapse:collapse }
td              { align:left; max-width:100% }
<head>
<title>Obey max-width for table</title>

</head>
<body>
<table summary="" class="quirx"><tr><td colspan="3">
Just some info
</td></tr><tr><td>KEY</td><td><div>DATA (which might contain long lines PRE formatted) XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX </div>
</td></tr></table>
</body>

Note that the "colspan=3" is no error here, in my app sometimes a third column may show up, this cannot be known at the time the table header is output. (Some style things are redundant, too.)

The trick above is, that the td's max-width together are smaller than the usual screen (590px) and the table then is stretched to the given width, which is 100%. As the tds do not stretch beyond the screen, the inner div's overflow property can work as expected. However in FF it does not work this way, neither with width nor with max-width (which is probably due to their inline-status). In Chrome a width:100% or similar does not work on the td nor the tr elements. Note that with max-width one gets a more pleasant table layout than with width (I do not understand that difference).

Besides the bug that this only works in Chrome, another bug is, that the table uses the full screen-width even if that is not needed if there is only small data to display.

Some notes about that all:

  • I think this here is a very basic thing and I am puzzled why it seems so hard to express with CSS
  • A goal is to keep it free of any JavaScript, so only CSS with hacks
  • The user can resize the window, for example from 800px to 1920px or even wider, and so the table's width shall automatically follow (without JavaScript)
  • It shall display good on text based browsers like Lynx and w3m, too
  • Output shall not be too cluttered for easy parsing when piped from curl
  • It shall display more or less properly on the major 4 (IE, FF, Chrome, Safari)
  • It shall not break on others (it can have render bugs, but content must not be hidden)

I really have no idea how to archive that. Perhaps it's a FAQ, but I was unable to spot a solution myself.

like image 292
Tino Avatar asked Feb 06 '11 19:02

Tino


1 Answers

I'm including some markup below that tests the HTML/CSS to achieve what I believe you want.

There is a fixed-width cell style .fixedcell and fluid width cell style .fluidcell. I've set a fixed width (75px for this example) simply to illustrate things better.

The fluid width ones have width:auto so they fill the width of the remaining table space; they also importantly have white-space:nowrap so the text doesn't expand the cell height-wise (white-space:pre works too); and finally they have overflow:hidden so the text doesn't overflow the width and make things ugly, alternatively you could set overflow:scroll for it to have a scrollbar in those cells when/if necessary.

The table is set to be 100% width so it will expand to fit the screen/etc as needed. And the important thing regarding the table's style is the table-layout:fixed, this makes the table adhere to the layout of the page rather than auto-sizing itself based on its own content (table-layout:auto).

I also added some borders to help illustrate the boundaries of the table and cells.

<html>
<head>
    <title>Table with auto-width sizing and overflow hiding.</title>
    <style type="text/css">
        table {width:100%; border:solid 1px red; table-layout:fixed;}
        table td {border:solid 1px green;}
        .fixedcell {width:75px;}
        .fluidcell {width:auto; overflow:hidden; white-space:nowrap;}
    </style>
</head>
<body>
    Table with one fluid column:
    <table>
        <tr>
            <td class="fixedcell">row 1</td>
            <td class="fluidcell">a whole bunch of content could go here and it still needs to fit nice into the cell without mucking things up</td>
            <td class="fixedcell">fixie</td>
            <td class="fixedcell">another</td>
        </tr>
    </table>

    Table with two fluid columns:
    <table>
        <tr>
            <td class="fixedcell">row 1</td>
            <td class="fluidcell">a whole bunch of content could go here and it still needs to fit nice into the cell without mucking things up</td>
            <td class="fluidcell">blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah</td>
            <td class="fixedcell">fixie</td>
            <td class="fixedcell">another</td>
        </tr>
    </table>
</body>
</html>

I tested it in several modern browsers and seemed to work correctly in each.

PS. Although tables are a no-no for page layout in general, tables are correct and encouraged for tabular data layout.

like image 173
devlop Avatar answered Oct 08 '22 04:10

devlop