开发者

CSS: Constrain a table with long cell contents to page width?

Take the following CSS+HTML:

<style>
    div.stuff {
        overflow: hidden;
        width: 100%;
        white-space: nowrap;
    }
    table { width: 100%; }
    td { border: 1px dotted black; }
</style>

<table>
    <tr><td>
        <div class='stuff'>Long text long text lon开发者_开发技巧g text long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text</div>
    </td></tr>
</table>

This causes the table to grow to accommodate the entire long text. (Make your browser window smaller to see if you have a humongous screen resolution.)

I added width: 100% and overflow: hidden to indicate that the long text should simply be cut off, but it seems to ignore that. How do I constrain the table/the table cell/the div in such a way that the table’s width does not exceed the width of the document?

(Please don’t comment on the merits of using a table at all. I am indeed displaying tabular data, so the use of a table is semantically correct. Also please don’t question the user-friendliness of cutting off the text; there is actually an “expand” button that allows the user to view the full contents. Thanks!)

(Edit: I tried max-width too, to no avail.)


To achieve this, you have to wrap the long text into two divs. The outer one gets position: relative and contains only the inner one. The inner one gets position: absolute, overflow: hidden, and width: 100% (this constrains it to the size of the table cell).

The table-layout algorithm now considers those table cells empty (because absolutely-positioned elements are excluded from layout calculations). Therefore we have to tell it to grow that column regardless. Interestingly, setting width: 100% on the relevant <col> element works, in the sense that it doesn’t actually fill 100% of the width, but 100% minus the width of all the other columns (which are automatically-sized). It also needs a vertical-align: top as otherwise the (empty) outer div is aligned middle, so the absolutely-positioned element will be off by half a line.

Here is a full example with a three-column, two-row table showing this at work:

CSS:

div.outer {
    position: relative;
}
div.inner {
    overflow: hidden;
    white-space: nowrap;
    position: absolute;
    width: 100%;
}
table {
    width: 100%;
    border-collapse: collapse;
}
td {
    border: 1px dotted black;
    vertical-align: top;
}
col.fill-the-rest { width: 100%; }

HTML:

<table>
    <col><col><col class="fill-the-rest">
    <tr>
        <td>foo</td>
        <td>fooofooooofooooo</td>
        <td>
            <div class='outer'>
                <div class='inner'>
                    Long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text
                </div>
            </div>
        </td>
    </tr>
    <tr>
        <td>barbarbarbarbar</td>
        <td>bar</td>
        <td>
            <div class='outer'>
                <div class='inner'>
                    Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text
                </div>
            </div>
        </td>
    </tr>
</table>

In this example, the first two columns will have the minimum possible size (i.e. spaces will make them wrap a lot unless you also add white-space: nowrap to them).

jsFiddle: http://jsfiddle.net/jLX4q/


I added width: 100% and overflow: hidden to indicate that the long text should simply be cut off, but it seems to ignore that.

It's not ignoring that, your div is expanding 100% the width of your table, which is set to expand 100% as it is, just give your td a max-width and it should cutoff as you expect.


Building off of @Timwi's solution...

table {
 width: 100%;
 border: 1px solid #ccc;
}

td {
 padding: 14px;
 line-height: 1.5;
 border: 1px solid #ccc;
}

.outer {
 position:relative;
 height: 22px;
}

.inner {
  position: absolute;
  overflow: hidden;
  width: 100%;
  white-space: nowrap;
  margin: auto;
  top: 0;
  bottom:0;
}

<table>
  <tr>
    <td>
      <div class="outer">
        <div class="inner">
          this_is_a_really_long_string_of_text
        </div>
      </div>
    </td>
    <td>
      222222222
    </td>
  </tr>
</table>

I'm using bootstrap 2.3.2 so that's where the height value is coming from. Here's a link to the fiddle http://jsfiddle.net/YFCV6/


Slightly different answer: If you'd prefer the table to display all its contents, while still being constrained to the page width, try using overflow-wrap: anywhere. This forces text to wrap, breaking on word boundaries when possible.

To support older browsers, you can use the legacy word-break: break-word with word-break: break-all as a fallback.

Example here: https://jsfiddle.net/joseph_white3/nhj9fLrw/

Also note: only set table-layout: fixed if you want the column widths to be determined based on just the first row. See the documentation on MDN.


you have nowrap set so the td cannot properly constrain the content. Removing that value should achieve the desired result.


As long as you have any width: 100% tags, it going to expand to contain the content.

One way to get the desired result (text that does not wrap) is to have an outer div w/ overflow hidden + a set width, then an inner div with a super wide width.

http://jsfiddle.net/xvaEw/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜