2

I have a 100% width table containing several cells. I want one of this cells to always show its contents in one line white-space: nowrap and to display an ellipsis at the end of the line if the contents exceed the table cell text-overflow: ellipsis.

The problem i have is that the table will stop contracting it's with when reaching the cells content. So the minium width of the cell will allways be the width of its content instead the table will be pushed out as a whole.

I just can't figure out how to solve this:

My HTML:

<div class="otrCompactView">
    <div class="otrLastEditTable">
        <div class="otrLastEditRow">
            <div class="otrLastEditor">LastEditor</div>
            <div class="otrLastEdited">LastModified</div>
        </div>
    </div>
    <div class="otrTitleRow otrRow">
        <div class="otrTitle">Title asdasdasdas asd asd asd asdas as asd </div>
    </div>
    <div vlass="otrTaskRow otrRow">
    </div>
    <div class="otrColumnsRow otrRow">
        <div class="otrColumns"></div>
    </div>
</div>

My CSS:

.otrCompactView {
    display: table;
    background: yellow;
    width: 100%;
    height: 100%;
}

.otrRow {
    display: table-row;
}

.otrLastEditTable {
    display: table;
    width: 100%;
}

.otrLastEditRow {
    display: table-row;
}

.otrLastEditor {
    display: table-cell;
}

.otrLastEdited {
    display: table-cell;
    text-align: right;
}

.otrTitle {
    border: 1px dotted red;
    min-width: 50px;
    white-space: nowrap;
}

And a fiddle for direct testing:

http://jsfiddle.net/67B6G/

Chris
  • 7,675
  • 8
  • 51
  • 101

2 Answers2

8

Does this look like what you're after?

updated

HTML

 <div class='table'>
    <div class='row'>
        <div class='cell'>Something quite long</div>  
    </div>
    <div class='row'>
        <div class='cell'>
            here is some moreSomething quite long that should exceed the table cell.Something quite long that should exceed the table cell.
        </div>          
    </div>
</div>

CSS

.table{
    margin:0;
    padding:0;
    display:table;
    table-layout: fixed;
    width:100%;
    max-width:100%;
}
.row{
    display:table-row;
}
.cell{
    display:table-cell;
    border:1px solid grey;
}
.cell:last-child{
    white-space: nowrap;
    overflow:hidden;
    text-overflow: ellipsis;    
}
SW4
  • 69,876
  • 20
  • 132
  • 137
  • Yes, seems like, `overflow:hidden` and `table-layout: fixed` where the missing things. Thanks a lot! – Chris Nov 22 '13 at 15:01
0

Here's a way to do it without using table-layout: fixed that allows you to keep dynamic widths with jQuery.

HTML:

<div class="table">
    <div class="left">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
    <div class="right">Lorem Ipsum</div>
</div>

In the CSS, you use your standard ellipsis code but add max-width: 0 (as explained here with respect to actual table elements):

.table {
    display: table;
    width: 100%;
}

.left, .right {
    display: table-cell;
    padding: 0 5px 0 5px;

    max-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

If you stopped there, you'd end up with each child div taking up 50% of the total width of the parent div, so you still wouldn't have fit-to-content dynamic widths. To remedy this, I adapted this code, which calculates the width of the text in an element, to calculate the width and then use that to dynamically set the width of the right column. The left column will then have the ellipsis.

// Calculate width of text from DOM element or string. By Phil Freo <http://philfreo.com>
$.fn.textWidth = function(text, font) {
    if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
    $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font'));
    return $.fn.textWidth.fakeEl.width();
};

$('.right').on('input', function() {
    var $width = $(this).textWidth(); // Get width of text
    $width += 10; // Add left and right padding
    $(this).width($width); // Set width
}).trigger('input');

Note that the above code requires you to take padding into account; otherwise, the right column will have an ellipsis as well. Here's a fiddle.

To use this in a table with multiple rows, you could modify the jQuery iterate over the cells in a column and set the width of the column to the requisite width of the widest cell in the column. Or, if you know which one is the widest, you can just direct the jQuery to get the width of that.

Community
  • 1
  • 1
Vincent
  • 2,689
  • 3
  • 24
  • 40