CSS: Memotong sel tabel, tapi muat sebanyak mungkin

223

Temui Fred. Dia adalah sebuah meja:

Satu sel memiliki lebih banyak konten dan lebih luas, yang lain memiliki lebih sedikit konten dan lebih sempit

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

Apartemen Fred memiliki kebiasaan aneh dalam mengubah ukuran, jadi dia belajar menyembunyikan sebagian isinya agar tidak mendorong semua unit lain dan mendorong ruang tamu Ny. Whitford untuk dilupakan:

Sel-sel sekarang memiliki ukuran yang sama, tetapi hanya satu yang kontennya terpotong, dan sepertinya jika sel lain memberi jika beberapa spasi, keduanya bisa muat.

<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>

Ini bekerja, tetapi Fred memiliki perasaan mengomel bahwa jika sel kanannya (yang dia juluki Celldito) menyerah sedikit, sel kirinya tidak akan terpotong sepanjang waktu. Bisakah kamu menyelamatkan kewarasannya?


Singkatnya: Bagaimana sel-sel tabel dapat melimpah secara merata, dan hanya ketika mereka semua telah menyerahkan semua spasi putihnya?

s4y
sumber
95
+1 Untuk karakterisasi objek virtual, baik satu pak :)
Myles Gray
6
Saya menduga Anda harus menggunakan JavaScript untuk menyelesaikan ini.
fiftydot
6
Lolz .. +1 untuk nilai hiburan :) ... apakah ini harus dinamis atau tidak bisakah Anda menetapkan lebar pada setiap kolom?
War

Jawaban:

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/

Ladislav
sumber
9
Ugh. Bekerja sangat bagus, tetapi saya tidak tahu mengapa, yang membuat saya gugup :(
Shaun Rowan
Terima kasih! Tidak melakukan persis apa yang dikatakan pertanyaan (memotong semua kolom secara merata), tetapi perilaku kode ini adalah apa yang saya cari.
Sam
3
Juga, perhatikan bahwa Anda dapat menghilangkan huruf<col> s dengan mengganti lebar lebar dengan <td>gaya: jsfiddle.net/7CURQ/64
Sam
2
Sebenarnya, ini tampaknya merusak ukuran kolom dinamis dari kolom yang tidak terpotong. Mereka tampaknya selalu menyusut hingga lebar minimum.
Sam
38

Saya yakin saya punya solusi non-javascript! Lebih baik terlambat daripada tidak, kan? Bagaimanapun, ini adalah pertanyaan yang sangat bagus dan Google sudah mengatasinya. Saya tidak ingin menerima perbaikan javascript karena saya menemukan sedikit kegelisahan tentang hal-hal yang bergerak setelah halaman dimuat menjadi tidak dapat diterima.

Fitur :

  • Tidak ada javascript
  • Tidak ada tata letak yang diperbaiki
  • Tidak ada trik berbobot atau persentase lebar
  • Bekerja dengan sejumlah kolom
  • Pembuatan sisi server dan pembaruan sisi klien yang sederhana (tidak perlu perhitungan)
  • Kompatibel lintas browser

Cara kerjanya : Di dalam sel tabel, tempatkan dua salinan konten dalam dua elemen berbeda dalam elemen kontainer yang diposisikan relatif. Elemen spacer diposisikan secara statis dan karenanya akan mempengaruhi lebar sel tabel. Dengan membiarkan isi sel spacer untuk membungkus kita bisa mendapatkan "paling cocok" lebar sel tabel yang kita cari. Ini juga memungkinkan kami untuk menggunakan elemen yang diposisikan benar-benar untuk membatasi lebar konten yang terlihat dengan induk yang diposisikan relatif.

Diuji dan bekerja di: IE8, IE9, IE10, Chrome, Firefox, Safari, Opera

Gambar Hasil :

Lebar proporsional yang bagus Kliping proporsional yang bagus

JSFiddle : http://jsfiddle.net/zAeA2/

Contoh 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;
}
Lucifer Sam
sumber
3
Jika konten Anda adalah kata yang sangat panjang tanpa spasi, ini tidak berfungsi tetapi Anda hanya perlu menambahkan tanda hubung pada conent di spacer dengan & shy; jsfiddle.net/zAeA2/160
Riccardo Casatta
2
ini sangat mengagumkan! saya membuat varian saya sendiri menggunakan attr untuk menghindari duplikasi konten: jsfiddle.net/coemL8rf/2
Jayen
@ Jay Nice - Mungkin menggunakan titlealih-alih data-spacermendapatkan tooltip di mouse :)
William George
@ Jayen, saya baru saja mencoba milik Anda dan sepertinya tidak memotong sel di sisi kanan, sehingga tidak memenuhi persyaratan sel-sel meluap secara merata. Saya menggunakan Chrome 46.
Sam
@ Sam ya itu benar. contoh saya hanya menunjukkan bahwa kedua jenis sel dapat dibuat tanpa duplikat konten. Saya tidak mencoba menjawab pertanyaan, hanya menunjukkan cara lain. jika Anda mengubah HTML dalam contoh saya, ini berfungsi seperti yang Anda inginkan.
Jayen
24

Saya telah menghadapi tantangan yang sama beberapa hari yang lalu. Tampaknya Lucifer Sam menemukan solusi terbaik.

Tapi saya perhatikan Anda harus menduplikasi konten di elemen spacer. Saya pikir itu tidak terlalu buruk, tetapi saya juga ingin menerapkan titlepopup untuk teks terpotong. Dan itu berarti teks panjang akan muncul ketiga kali dalam kode saya.

Di sini saya mengusulkan untuk mengakses titleatribut dari :afterpseudo-element untuk menghasilkan spacer dan menjaga HTML tetap bersih.

Bekerja pada 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/

Henry Feesler
sumber
Sangat setuju, brilian!
Mikhail
jauh lebih baik daripada solusi css lainnya karena ia bekerja di kedua perintah, yaitu jika semakin banyak sel konten setelah semakin sedikit sel konten.
buggedcom
19

Jika Javascript dapat diterima, saya menyusun rutinitas cepat yang dapat Anda gunakan sebagai titik awal. Secara dinamis mencoba untuk menyesuaikan lebar sel menggunakan lebar bagian dalam rentang, sebagai reaksi terhadap peristiwa ukuran jendela.

Saat ini diasumsikan bahwa setiap sel biasanya mendapatkan 50% dari lebar baris, dan itu akan menutup sel kanan untuk menjaga sel kiri pada lebar maksimum untuk menghindari meluap. Anda bisa menerapkan logika penyeimbang lebar yang jauh lebih kompleks, tergantung pada kasus penggunaan Anda. Semoga ini membantu:

Markup untuk baris yang saya gunakan untuk pengujian:

<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 yang menghubungkan acara pengubahan ukuran:

$(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);
        }
    });
});
samplebias
sumber
18

Ada solusi yang jauh lebih mudah dan lebih elegan.

Di dalam sel tabel yang ingin Anda terapkan pemotongan, cukup sertakan div kontainer dengan tata letak tabel css: diperbaiki. Wadah ini mengambil lebar penuh sel tabel induk, sehingga bahkan bertindak responsif.

Pastikan untuk menerapkan pemotongan ke elemen dalam tabel.

Bekerja dari 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>

dan css:

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

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

inilah Fiddle yang berfungsi https://jsfiddle.net/d0xhz8tb/

satyavh
sumber
Solusi ini membutuhkan 2 elemen level blok tambahan untuk mencapai efek non-struktural. Dimungkinkan untuk mengatur satu sel tabel ke "display: table", yang memungkinkan Anda menyingkirkan salah satu div. jsfiddle.net/rza4hfcv Tidak yakin, apa yang harus saya pikirkan tentang ini. Tetapi terima kasih telah membagikan solusi Anda!
armin
Apakah Anda mengalami masalah dengan solusi itu? Saya sedang berpikir untuk menggunakannya dalam pengaturan profesional.
armin
@armin, cobalah untuk menduplikasi sel yang ingin Anda potong: Anda tidak dapat meletakkan lebih dari satu sisi secara berdampingan.
DanielM
Saya tidak akan mengatakan ini adalah solusi final. Anda kehilangan salah satu manfaat utama dari tabel: bahwa ukuran kolom disesuaikan dengan kontennya. Jika Anda mengatur setiap kolom seperti ini, semuanya akan memiliki lebar yang sama, tidak peduli panjang kontennya.
DanielM
@DanielM Anda dapat memperluas solusinya dengan lebih lanjut menyarangkan tabel - seperti di tabel-layout-hari yang lama - tetapi sekarang hanya dengan css.
armin
11

Masalahnya adalah 'table-layout: fixed' yang membuat kolom dengan lebar spasi tetap. Tetapi menonaktifkan properti-css ini akan membunuh text-overflow karena tabel akan menjadi sebesar mungkin (dan tidak ada yang ingin meluap).

Maaf, tetapi dalam hal ini Fred tidak dapat memiliki kue dan memakannya .. kecuali jika pemiliknya memberi Celldito lebih sedikit ruang untuk bekerja, Fred tidak dapat menggunakan ...

Andre Haverdings
sumber
9

Anda dapat mencoba "memberi bobot" pada kolom tertentu, seperti ini:

<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>

Anda juga dapat mencoba beberapa tweak yang lebih menarik, seperti menggunakan kolom bandwidth 0% dan menggunakan beberapa kombinasi white-spaceproperti CSS.

<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>

Anda mendapatkan idenya.

Elliot Cameron
sumber
3

Ya saya akan mengatakan tiga puluh tidak memilikinya, tidak ada cara untuk melakukannya kecuali Anda menggunakan metode js. Anda berbicara tentang serangkaian kondisi render kompleks yang harus Anda tetapkan. misalnya apa yang terjadi ketika kedua sel menjadi terlalu besar untuk apartemen mereka, Anda harus memutuskan siapa yang memiliki prioritas atau hanya memberi mereka persentase dari area dan jika mereka berlebihan mereka akan mengambil area itu dan hanya jika ada yang memiliki spasi Anda meregangkan kaki di sel lain, atau tidak ada cara untuk melakukannya dengan css. Meskipun ada beberapa hal yang cukup funky yang dilakukan orang dengan css yang belum saya pikirkan. Saya benar-benar ragu Anda bisa melakukan ini.

pengguna648116
sumber
3

Gunakan beberapa css hack, tampaknya display: table-column;bisa menyelamatkan:

<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/

blai
sumber
Solusi bagus! Terima kasih!
Valeriu92
Terlihat cukup bagus sampai saya menambahkan sel statis sebelum sel yang fleksibel: jsfiddle.net/7u59asyp/5
Sam
ini adalah satu-satunya yang bekerja untuk saya, meskipun tidak sempurna, karena saya memiliki 4 kolom dengan ukuran konten yang diharapkan bervariasi
turun
3

Cukup tambahkan aturan berikut ke td:

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

Contoh:

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: Jika Anda ingin mengatur lebar kustom ke tdproperti penggunaan lain min-width.

Alexandre Annic
sumber
Masalah dengan ini adalah bahwa secara default kolom tabel mengkonsumsi ruang secara proporsional. Jika konten dari satu baris lebih panjang dari yang lain, itu akan mengalokasikan lebih dari lebarnya. Namun, teknik ini membagi ruang secara merata. Apakah ada pekerjaan?
Malik Brahimi
2

Pertanyaan ini muncul di bagian atas Google, jadi dalam kasus saya, saya menggunakan potongan css dari https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/ tetapi menerapkannya pada td TIDAK memberikan hasil yang diinginkan.

Saya harus menambahkan tag div di sekitar teks di td dan elipsis akhirnya berfungsi.

Kode HTML Singkatan;

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

CSS disingkat;

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

Periksa apakah "nowrap" menyelesaikan masalah sampai batas tertentu. Catatan: nowrap tidak didukung dalam 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>

amlan
sumber
white-space: nowrapmemiliki efek yang sama dengan nowrapatribut (dan saya menggunakannya dalam contoh). Menambahkannya di sini tidak mengubah apa pun, sejauh yang saya tahu.
s4y
0

Anda dapat mengatur lebar sel kanan ke minimum lebar yang diperlukan, lalu menerapkan overflow-hidden + text-overflow ke bagian dalam sel kiri, tetapi Firefox bermasalah di sini ...

meskipun, tampaknya, flexbox dapat membantu

4esn0k
sumber
0

Saya baru-baru ini mengerjakannya. Lihatlah tes jsFiddle ini , cobalah sendiri mengubah lebar tabel dasar untuk memeriksa perilaku).

Solusinya adalah dengan menyematkan tabel ke tabel lain:

<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>

Apakah Fred sekarang senang dengan ekspansi Celldito?

IG Pascual
sumber
Maaf atas kurangnya tanggapan! Saya tidak bisa melihat bagaimana ini berperilaku berbeda dari satu meja. Ketika saya melihat biola di Chrome atau Firefox, tampilannya persis seperti tangkapan layar kedua dari pertanyaan. Apakah saya melewatkan sesuatu?
s4y
Maaf, tautannya bukan yang saya posting. Sebenarnya ini jsfiddle.net/VSZPV/2 . Ubah teks dari kedua sel dan lebar tabel utama untuk diuji. Semoga itulah yang Anda cari ...
IG Pascual
0

Tidak tahu apakah ini akan membantu siapa pun, tapi saya memecahkan masalah yang sama dengan menentukan ukuran lebar spesifik dalam persentase untuk setiap kolom. Jelas, ini akan bekerja paling baik jika setiap kolom memiliki konten dengan lebar yang tidak terlalu bervariasi.

DKO
sumber
-1

Saya memiliki masalah yang sama, tetapi saya perlu menampilkan beberapa baris (jika text-overflow: ellipsis;gagal). Saya menyelesaikannya dengan menggunakan textareadi dalam TDdan kemudian gaya untuk berperilaku seperti sel tabel.

    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;
        }
    }
Nicero
sumber
-2

Mengingat bahwa 'tata letak tabel: diperbaiki' adalah persyaratan tata letak yang penting, bahwa ini menciptakan kolom yang tidak dapat disetel secara merata, tetapi bahwa Anda perlu membuat sel dengan lebar persentase berbeda, mungkin mengatur 'colspan' sel Anda menjadi beberapa?

Misalnya, menggunakan lebar total 100 untuk perhitungan persentase mudah, dan mengatakan bahwa Anda memerlukan satu sel 80% dan 20% lainnya, pertimbangkan:

<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>

Tentu saja, untuk kolom 80% dan 20%, Anda bisa mengatur colspan sel lebar 100% menjadi 5, 80% menjadi 4, dan 20% menjadi 1.

Siubear
sumber
1
HaiSiubear. Bagaimana itu berbeda dari menentukan lebar persen pada tds?
s4y
Menggunakan colspan sedemikian rupa adalah ide yang mengerikan. Mengapa tidak menggunakan lebar saja?
Percy