CSS: Cắt bớt các ô của bảng, nhưng phù hợp nhất có thể


223

Gặp Fred. Anh ấy là một cái bàn:

Một ô có nhiều nội dung hơn và rộng hơn, ô còn lại có ít nội dung hơn và hẹp hơn

<table border="1" style="width: 100%;">
    <tr>
        <td>This cells has more content</td>
        <td>Less content here</td>
    </tr>
</table>

Căn hộ của Fred có thói quen thay đổi kích thước kỳ lạ, vì vậy anh đã học cách che giấu một số nội dung của mình để không đẩy tất cả các đơn vị khác qua và đẩy phòng khách của bà Whitford vào quên lãng:

Các ô bây giờ có cùng kích thước, nhưng chỉ có một ô có nội dung bị cắt bớt và có vẻ như nếu ô kia đưa ra nếu có khoảng trắng, cả hai đều có thể vừa.

<table border="1" style="width: 100%; white-space: nowrap; table-layout: fixed;">
    <tr>
        <td style="overflow: hidden; text-overflow: ellipsis">This cells has more content</td>
        <td style="overflow: hidden; text-overflow: ellipsis">Less content here</td>
    </tr>
</table>

Điều này hoạt động, nhưng Fred có một cảm giác khó chịu rằng nếu tế bào bên phải của anh ta (mà anh ta có biệt danh là Celldito) đã từ bỏ một không gian nhỏ, thì tế bào bên trái của anh ta sẽ không bị cắt cụt nhiều thời gian. Bạn có thể cứu sự tỉnh táo của anh ấy?


Tóm lại: Làm thế nào các ô của bảng có thể tràn đều và chỉ khi tất cả chúng đã từ bỏ tất cả khoảng trắng của chúng?


95
+1 Để mô tả đặc tính của một vật thể ảo, độc đáo thưa ngài :)
Myles Grey

6
Tôi nghi ngờ bạn sẽ phải dùng đến JavaScript để giải quyết vấn đề này.
ba mươi

6
Lolz .. +1 cho giá trị giải trí :) ... điều này có cần phải động hay bạn không thể đơn giản đặt chiều rộng cho mỗi cột?
Chiến tranh

Câu trả lời:


82
<table border="1" style="width: 100%;">
    <colgroup>
        <col width="100%" />
        <col width="0%" />
    </colgroup>
    <tr>
        <td style="white-space: nowrap; text-overflow:ellipsis; overflow: hidden; max-width:1px;">This cell has more content.This cell has more content.This cell has more content.This cell has more content.This cell has more content.This cell has more content.</td>
        <td style="white-space: nowrap;">Less content here.</td>
    </tr>
</table>

http://jsfiddle.net/7CURQ /


9
Ừ Hoạt động rất tuyệt, nhưng tôi không biết tại sao, điều đó khiến tôi lo lắng :(
Shaun Rowan

Cảm ơn! Không thực hiện chính xác những gì các câu hỏi nói (cắt tất cả các cột đồng đều), nhưng hành vi của này đang là những gì tôi đang tìm kiếm.
Sam

3
Ngoài ra, lưu ý rằng bạn có thể loại bỏ <col>s bằng cách thay vào đó là thêm các chiều rộng cho các <td>kiểu: jsfiddle.net/7CURQ/64
Sam

2
Trên thực tế, điều này dường như làm hỏng kích thước cột động của các cột không bị cắt cụt. Chúng dường như luôn được thu nhỏ đến chiều rộng tối thiểu.
Sam

38

Tôi tin rằng tôi có một giải pháp không phải là javascript! Muộn còn hơn không, phải không? Sau tất cả, đây là một câu hỏi xuất sắc và Google là tất cả. Tôi không muốn giải quyết một bản sửa lỗi javascript vì tôi thấy sự lộn xộn nhỏ của những thứ di chuyển xung quanh sau khi trang được tải là không thể chấp nhận được.

Các tính năng :

  • Không có javascript
  • Không có bố cục cố định
  • Không có thủ thuật trọng số hoặc tỷ lệ phần trăm chiều rộng
  • Hoạt động với bất kỳ số lượng cột
  • Tạo phía máy chủ đơn giản và cập nhật phía máy khách (không cần tính toán)
  • Tương thích trình duyệt chéo

Làm thế nào nó hoạt động : Bên trong ô bảng đặt hai bản sao nội dung trong hai thành phần khác nhau trong một thành phần chứa tương đối được định vị. Phần tử spacer được định vị tĩnh và như vậy sẽ ảnh hưởng đến chiều rộng của các ô của bảng. Bằng cách cho phép bọc nội dung của ô đệm, chúng ta có thể có được độ rộng "phù hợp nhất" của các ô bảng mà chúng ta đang tìm kiếm. Điều này cũng cho phép chúng tôi sử dụng phần tử được định vị tuyệt đối để hạn chế độ rộng của nội dung hiển thị so với phần tử được định vị tương đối.

Đã thử nghiệm và làm việc trong: IE8, IE9, IE10, Chrome, Firefox, Safari, Opera

Hình ảnh kết quả :

Chiều rộng tỷ lệ đẹp Cắt tỷ lệ đẹp

Mã thông báo : http://jsfiddle.net/zAeA2/

Mẫu HTML / CSS :

<td>
    <!--Relative-positioned container-->
    <div class="container">
        <!--Visible-->
        <div class="content"><!--Content here--></div>
        <!--Hidden spacer-->
        <div class="spacer"><!--Content here--></div>
        <!--Keeps the container from collapsing without
            having to specify a height-->
        <span>&nbsp;</span>
     </div>
</td>

.container {
    position: relative;
}
.content {
    position: absolute;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.spacer {
    height: 0;
    overflow: hidden;
}

3
Nếu nội dung của bạn là một từ rất dài không có dấu cách, thì điều này không hoạt động nhưng bạn chỉ cần thêm dấu gạch nối vào conent trong spacer với & shy; jsfiddle.net/zAeA2/160
Riccardo Casatta

2
Điều này là khá tuyệt vời! tôi đã làm biến thể của riêng tôi sử dụng attr để tránh nội dung trùng lặp: jsfiddle.net/coemL8rf/2
Jayen

@Jayen Nice - Có lẽ sử dụng titlethay vì data-spacerlấy một chú giải công cụ trên chuột :)
William George

@Jayen, tôi vừa thử máy của bạn và nó dường như không cắt được ô ở phía bên phải, vì vậy nó không đáp ứng yêu cầu của các ô tràn đều. Tôi đang sử dụng Chrome 46.
Sam

@ Có, đúng vậy. ví dụ của tôi chỉ cho thấy rằng cả hai loại ô có thể được tạo mà không cần sao chép nội dung. tôi đã không cố gắng trả lời câu hỏi, chỉ đơn giản là chỉ ra một cách khác. nếu bạn thay đổi HTML trong ví dụ của tôi, nó sẽ hoạt động như bạn muốn.
Jayen

24

Tôi đã phải đối mặt với thử thách tương tự vài ngày trước. Có vẻ như Lucifer Sam đã tìm ra giải pháp tốt nhất.

Nhưng tôi nhận thấy bạn nên sao chép nội dung ở phần tử spacer. Nghĩ rằng nó không quá tệ, nhưng tôi cũng muốn áp dụng titlecửa sổ bật lên cho văn bản được cắt. Và nó có nghĩa là văn bản dài sẽ xuất hiện lần thứ ba trong mã của tôi.

Ở đây tôi đề xuất truy cập titlethuộc tính từ :afterphần tử giả để tạo spacer và giữ HTML sạch.

Hoạt động trên IE8 +, FF, Chrome, Safari, Opera

<table border="1">
  <tr>
    <td class="ellipsis_cell">
      <div title="This cells has more content">
        <span>This cells has more content</span>
      </div>
    </td>
    <td class="nowrap">Less content here</td>
  </tr>
</table>
.ellipsis_cell > div {
    position: relative;
    overflow: hidden;
    height: 1em;
}

/* visible content */
.ellipsis_cell > div > span {
    display: block;
    position: absolute; 
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1em;
}

/* spacer content */
.ellipsis_cell > div:after {
    content: attr(title);
    overflow: hidden;
    height: 0;
    display: block;
}

http://jsfiddle.net/feesler/HQU5J/


Không thể đồng ý nhiều hơn, rực rỡ!
Mikhail

tốt hơn nhiều so với các giải pháp css khác vì nó hoạt động trong cả hai đơn hàng, tức là nếu càng nhiều ô nội dung thì càng ít ô nội dung.
buggedcom

19

Nếu Javascript có thể chấp nhận được, tôi kết hợp một thói quen nhanh mà bạn có thể sử dụng làm điểm bắt đầu. Nó tự động cố gắng điều chỉnh độ rộng của ô bằng cách sử dụng độ rộng bên trong của một khoảng, để phản ứng với các sự kiện thay đổi kích thước cửa sổ.

Hiện tại, nó giả định rằng mỗi ô thường lấy 50% chiều rộng của hàng và nó sẽ thu gọn ô bên phải để giữ ô bên trái ở chiều rộng tối đa của nó để tránh tràn. Bạn có thể thực hiện logic cân bằng chiều rộng phức tạp hơn nhiều, tùy thuộc vào trường hợp sử dụng của bạn. Hi vọng điêu nay co ich:

Đánh dấu cho hàng tôi đã sử dụng để thử nghiệm:

<tr class="row">
    <td style="overflow: hidden; text-overflow: ellipsis">
    <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
    </td>
    <td style="overflow: hidden; text-overflow: ellipsis">
    <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
    </td>
</tr>

JQuery kết nối sự kiện thay đổi kích thước:

$(window).resize(function() {
    $('.row').each(function() {
        var row_width = $(this).width();
        var cols = $(this).find('td');
        var left = cols[0];
        var lcell_width = $(left).width();
        var lspan_width = $(left).find('span').width();
        var right = cols[1];
        var rcell_width = $(right).width();
        var rspan_width = $(right).find('span').width();

        if (lcell_width < lspan_width) {
            $(left).width(row_width - rcell_width);
        } else if (rcell_width > rspan_width) {
            $(left).width(row_width / 2);
        }
    });
});

18

Có một giải pháp dễ dàng và thanh lịch hơn nhiều.

Trong ô bảng mà bạn muốn áp dụng cắt bớt, chỉ cần bao gồm một div container với bố trí bảng css: đã sửa. Container này lấy toàn bộ chiều rộng của ô bảng cha, do đó, nó thậm chí còn hoạt động đáp ứng.

Hãy chắc chắn để áp dụng cắt ngắn cho các yếu tố trong bảng.

Hoạt động từ IE8 +

<table>
  <tr>
    <td>
     <div class="truncate">
       <h1 class="truncated">I'm getting truncated because I'm way too long to fit</h1>
     </div>
    </td>
    <td class="some-width">
       I'm just text
    </td>
  </tr>
</table>

và css:

    .truncate {
      display: table;
      table-layout: fixed;
      width: 100%;
    }

    h1.truncated {
      overflow-x: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

đây là một Fiddle hoạt động https://jsfiddle.net/d0xhz8tb/


Giải pháp này đòi hỏi 2 yếu tố cấp khối bổ sung để đạt được hiệu ứng phi cấu trúc. Có thể đặt một ô trong bảng thành "display: table", cho phép bạn thoát khỏi một trong các div. jsfiddle.net/rza4hfcv Không chắc chắn, tôi nên nghĩ gì về điều này. Nhưng cảm ơn vì đã chia sẻ giải pháp của bạn!
armin

Bạn có gặp bất kỳ vấn đề với giải pháp đó? Tôi đang suy nghĩ về việc sử dụng nó trong một môi trường chuyên nghiệp.
armin

@armin, hãy thử nhân đôi ô bạn muốn cắt bớt: bạn không thể đặt nhiều hơn một cạnh nhau.
DanielM

Tôi sẽ không nói đây là một giải pháp cuối cùng. Bạn mất một trong những lợi ích chính của bảng: rằng các cột thay đổi kích thước theo nội dung của nó. Nếu bạn thiết lập mọi cột như thế này, tất cả chúng sẽ có cùng chiều rộng, bất kể độ dài của nội dung của nó.
DanielM

@DanielM Bạn có thể mở rộng giải pháp bằng cách lồng thêm bảng - như trong cách bố trí bảng cũ - nhưng bây giờ chỉ với css.
armin

11

Vấn đề là 'bố cục bảng: đã cố định' tạo ra các cột có chiều rộng cố định cách đều nhau. Nhưng việc vô hiệu hóa thuộc tính css này sẽ giết chết tràn văn bản vì bảng sẽ trở nên lớn nhất có thể (và hơn là không có ghi chú tràn).

Tôi xin lỗi nhưng trong trường hợp này Fred không thể có bánh của mình và ăn nó .. trừ khi chủ nhà cho Celldito ít không gian để làm việc ở nơi đầu tiên, Fred không thể sử dụng ..


9

Bạn có thể thử "cân" các cột nhất định, như thế này:

<table border="1" style="width: 100%;">
    <colgroup>
        <col width="80%" />
        <col width="20%" />
    </colgroup>
    <tr>
        <td>This cell has more content.</td>
        <td>Less content here.</td>
    </tr>
</table>

Bạn cũng có thể thử một số điều chỉnh thú vị hơn, như sử dụng các cột có độ rộng 0% và sử dụng một số kết hợp của thuộc tính white-spaceCSS.

<table border="1" style="width: 100%;">
    <colgroup>
        <col width="100%" />
        <col width="0%" />
    </colgroup>
    <tr>
        <td>This cell has more content.</td>
        <td style="white-space: nowrap;">Less content here.</td>
    </tr>
</table>

Bạn có được ý tưởng.


3

Yep tôi sẽ nói ba mươidot có nó, không có cách nào để làm điều đó trừ khi bạn sử dụng phương pháp js. Bạn đang nói về một tập hợp các điều kiện kết xuất phức tạp mà bạn sẽ phải xác định. ví dụ: điều gì xảy ra khi cả hai ô trở nên quá lớn đối với căn hộ của họ, bạn sẽ phải quyết định ai là người ưu tiên hoặc chỉ đơn giản là cung cấp cho họ phần trăm diện tích và nếu họ quá đầy thì cả hai sẽ chiếm diện tích đó và chỉ khi một người có khoảng trắng sẽ bạn duỗi chân trong tế bào khác, dù bằng cách nào thì cũng không có cách nào để làm điều đó với css. Mặc dù có một số điều khá thú vị mà mọi người làm với css mà tôi không nghĩ tới. Tôi thực sự nghi ngờ bạn có thể làm điều này mặc dù.


3

Giống như câu trả lời samplebias, một lần nữa nếu Javascript là câu trả lời chấp nhận được, tôi đã tạo một plugin jQuery dành riêng cho mục đích này: https://github.com/marcogrcr/jquery-tableoverflow

Để sử dụng plugin, chỉ cần gõ

$('selector').tableoverflow();

Ví dụ đầy đủ: http://jsfiddle.net/Cw7TD/3/embedded/result/

Chỉnh sửa:

  • Sửa lỗi trong jsfiddle để tương thích với IE.
  • Khắc phục trong jsfiddle để tương thích trình duyệt tốt hơn (Chrome, Firefox, IE8 +).

3

Sử dụng một số hack css, có vẻ như display: table-column;có thể đến để giải cứu:

<div class="myTable">
    <div class="flexibleCell">A very long piece of content in first cell, long enough that it would normally wrap into multiple lines.</div>
    <div class="staticCell">Less content</div>
</div>

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

.myTable:before {
    display: table-column;
    width: 100%;
    content: '';
}

.flexibleCell {
    display: table-cell;
    max-width:1px;
    white-space: nowrap;
    text-overflow:ellipsis;
    overflow: hidden;
}

.staticCell {
    white-space: nowrap;
}

JSFiddle: http://jsfiddle.net/blai/7u59asyp/


Giải pháp tuyệt vời! Cảm ơn!
Valeriu92

Trông khá tốt cho đến khi tôi thêm một ô tĩnh trước một ô linh hoạt: jsfiddle.net/7u59asyp/5
Sam

đây là cái duy nhất làm việc cho tôi, mặc dù không hoàn hảo, vì tôi có 4 cột với kích thước nội dung dự kiến ​​khác nhau
hạ cấp

3

Chỉ cần thêm các quy tắc sau vào td:

overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
// These ones do the trick
width: 100%;
max-width: 0;

Thí dụ:

table {
  width: 100%
}

td {
  white-space: nowrap;
}

.td-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
  max-width: 0;
}
<table border="1">
  <tr>
    <td>content</td>
    <td class="td-truncate">long contenttttttt ttttttttt ttttttttttttttttttttttt tttttttttttttttttttttt ttt tttt ttttt ttttttt tttttttttttt ttttttttttttttttttttttttt</td>
    <td>other content</td>
  </tr>
</table>

PS: Nếu bạn muốn đặt chiều rộng tùy chỉnh cho thuộc tdtính sử dụng khác min-width.


Vấn đề với điều này là theo mặc định, các cột trong bảng tiêu thụ không gian theo tỷ lệ. Nếu nội dung của một hàng dài hơn một hàng khác, nó sẽ phân bổ nhiều chiều rộng hơn. Tuy nhiên, kỹ thuật này chia đều không gian. Có một công việc xung quanh?
Malik Brahimi

2

Câu hỏi này xuất hiện hàng đầu trong Google, vì vậy, trong trường hợp của tôi, tôi đã sử dụng đoạn trích css từ https://css-tricks.com/snippets/css/truncate-opes-with-ellipsis/ nhưng áp dụng nó cho td KHÔNG cho kết quả mong muốn.

Tôi đã phải thêm một thẻ div xung quanh văn bản trong td và dấu chấm lửng cuối cùng đã hoạt động.

Mã HTML viết tắt;

<table style="width:100%">
 <tr>
    <td><div class='truncate'>Some Long Text Here</div></td>
 </tr>
</table>

CSS viết tắt;

.truncate { width: 300px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

0

Kiểm tra xem "nowrap" có giải quyết được vấn đề không. Lưu ý: nowrap không được hỗ trợ trong HTML5

<table border="1" style="width: 100%; white-space: nowrap; table-layout: fixed;">
<tr>
    <td style="overflow: hidden; text-overflow: ellipsis;" nowrap >This cells has more content  </td>
    <td style="overflow: hidden; text-overflow: ellipsis;" nowrap >Less content here has more content</td>
</tr>


white-space: nowrapcó tác dụng tương tự như nowrapthuộc tính (và tôi đang sử dụng nó trong ví dụ). Thêm nó ở đây không thay đổi bất cứ điều gì, như tôi có thể nói.
s4y

0

bạn có thể đặt chiều rộng của ô bên phải ở mức tối thiểu của chiều rộng yêu cầu, sau đó áp dụng tràn văn bản + tràn văn bản vào bên trong ô bên trái, nhưng Firefox bị lỗi ở đây ...

Mặc dù, dường như, flexbox có thể giúp


0

Gần đây tôi đã làm việc về nó. Kiểm tra bài kiểm tra jsFiddle này , hãy tự thử thay đổi độ rộng của bảng cơ sở để kiểm tra hành vi).

Giải pháp là nhúng một bảng vào một bảng khác:

<table style="width: 200px;border:0;border-collapse:collapse">
    <tbody>
        <tr>
            <td style="width: 100%;">
                <table style="width: 100%;border:0;border-collapse:collapse">
                    <tbody>
                        <tr>
                            <td>
                                <div style="position: relative;overflow:hidden">
                                    <p>&nbsp;</p>
                                    <p style="overflow:hidden;text-overflow: ellipsis;position: absolute; top: 0pt; left: 0pt;width:100%">This cells has more content</p>
                                </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </td>
            <td style="white-space:nowrap">Less content here</td>
        </tr>
    </tbody>
</table>

Bây giờ Fred có hài lòng với bản mở rộng của Celldito không?


Xin lỗi vì sự thiếu phản ứng! Tôi không thể thấy cách này hoạt động khác với một bảng. Khi tôi xem fiddle trong Chrome hoặc Firefox, nó trông giống hệt như ảnh chụp màn hình thứ hai từ câu hỏi. Tui bỏ lỡ điều gì vậy?
s4y

Xin lỗi, liên kết không phải là một trong những tôi đã đăng. Đây thực sự là một jsfiddle.net/VSZPV/2 . Thay đổi văn bản của cả hai ô và chiều rộng của bảng chính để kiểm tra. Hy vọng đó là những gì bạn đang tìm kiếm ...
IG Pascual

0

Không biết điều này có giúp được ai không, nhưng tôi đã giải quyết một vấn đề tương tự bằng cách chỉ định kích thước chiều rộng cụ thể theo tỷ lệ phần trăm cho mỗi cột. Rõ ràng, điều này sẽ hoạt động tốt nhất nếu mỗi cột có nội dung với chiều rộng không thay đổi quá rộng rãi.


-1

Tôi có cùng một vấn đề, nhưng tôi cần hiển thị nhiều dòng ( text-overflow: ellipsis;không thành công). Tôi giải quyết nó bằng cách sử dụng textareabên trong a TDvà sau đó tạo kiểu cho nó hoạt động giống như một ô bảng.

    textarea {
        margin: 0;
        padding: 0;
        width: 100%;
        border: none;
        resize: none;

        /* Remove blinking cursor (text caret) */
        color: transparent;
        display: inline-block;
        text-shadow: 0 0 0 black; /* text color is set to transparent so use text shadow to draw the text */
        &:focus {
            outline: none;
        }
    }

-2

Cho rằng 'bố cục bảng: cố định' là yêu cầu bố cục thiết yếu, điều này tạo ra các cột không thể điều chỉnh cách đều nhau, nhưng bạn cần tạo các ô có độ rộng phần trăm khác nhau, có thể đặt 'colspan' của các ô của bạn thành bội số?

Ví dụ: sử dụng tổng chiều rộng 100 để tính toán tỷ lệ phần trăm dễ dàng và nói rằng bạn cần một ô là 80% và một ô khác là 20%, hãy xem xét:

<TABLE width=100% style="table-layout:fixed;white-space:nowrap;overflow:hidden;">
     <tr>
          <td colspan=100>
               text across entire width of table
          </td>
     <tr>
          <td colspan=80>
               text in lefthand bigger cell
          </td>
          <td colspan=20>
               text in righthand smaller cell
          </td>
</TABLE>

Tất nhiên, đối với các cột 80% và 20%, bạn chỉ có thể đặt colspan 100% chiều rộng thành 5, 80% thành 4 và 20% thành 1.


1
Này @Siubear. Làm thế nào khác với việc chỉ định một phần trăm chiều rộng trên tds?
s4y

Sử dụng colspan theo cách như vậy là một ý tưởng khủng khiếp. Tại sao không sử dụng chiều rộng thay thế?
Percy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.