CSS: Обрізати клітинки таблиці, але максимально вмістити


223

Знайомтесь з Фредом. Він стіл:

Одна клітина має більше вмісту і ширша, інша має менший вміст і вужча

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

Квартира Фреда має химерну звичку змінювати розміри, тому він навчився приховувати частину свого вмісту, щоб не штовхати всі інші осередки і відштовхувати віталь місіс Вітфорд у небуття:

Осередки тепер однакового розміру, але лише одна має урізаний вміст, і схоже, якби інша комірка дала, якщо якийсь пробіл, вони могли б обидва вміститися.

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

Це спрацьовує, але у Фреда виникає неприємне відчуття, що якби його права клітина (яку він прозвав Celldito) дала трохи місця, його ліва клітина не була б укорочена стільки часу. Чи можете ви зберегти його розум?


Підсумовуючи: Як клітини таблиці можуть переповнюватися рівномірно, і лише тоді, коли всі вони відмовилися від усього пробілу?


95
+1 Для характеристики віртуального об'єкта, приємно один сер :)
Майлз Грей

6
Я підозрюю, що вам доведеться вдатися до JavaScript, щоб вирішити це.
тридцятьдот

6
Lolz .. +1 для вартості розваг :) ... це має бути динамічним чи не можна просто встановити ширину для кожного стовпця?
Війна

Відповіді:


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
Тьфу. Працює так чудово, але я поняття не маю, чому це мене нервує :(
Shaun Rowan

Дякую! Не робить саме те, що було сказано в питанні (обрізати всі стовпці рівномірно), але поведінка цього коду - це те, що я шукав.
Сем

3
Також зауважте, що ви можете усунути <col>s, замість цього попередньо додавши ширину до <td>стилів: jsfiddle.net/7CURQ/64
Sam

2
Насправді це, мабуть, псує динамічне розмір стовпців незрізаних стовпців. Вони, здається, завжди стискаються до мінімальної ширини.
Сем

38

Я вважаю, що у мене є рішення без JavaScript! Краще пізно, ніж ніколи, правда? Зрештою, це відмінне запитання, і Google все на цьому. Я не хотів погоджуватися на виправлення javascript, оскільки я вважаю, що незначне тремтіння речей, що рухаються після завантаження сторінки, є неприйнятним.

Особливості :

  • Немає JavaScript
  • Немає фіксованої верстки
  • Ніяких хитрощів із зважуванням чи відсотковою шириною
  • Працює з будь-якою кількістю стовпців
  • Просте покоління на сервері та оновлення на стороні клієнта (не потрібен розрахунок)
  • Сумісний веб-браузер

Як це працює : Всередині комірки таблиці розмістіть дві копії вмісту у двох різних елементах у відносно розташованому елементі контейнера. Роздільний елемент розташований статично і як такий впливатиме на ширину комірок таблиці. Дозволяючи загортати вміст розпірної комірки, ми можемо отримати "найкраще" ширину комірок таблиці, які ми шукаємо. Це також дозволяє нам використовувати абсолютно позиціонований елемент для обмеження ширини видимого вмісту до ширини відносно розташованого батька.

Тестували та працювали в: IE8, IE9, IE10, Chrome, Firefox, Safari, Opera

Зображення результатів :

Приємні пропорційні ширини Приємна пропорційна вирізка

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

Зразок 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
Якщо ваш вміст - це дуже довге слово без пробілів, це не працює, але вам просто потрібно додати дефіс до конента в проставці з & shy; jsfiddle.net/zAeA2/160
Ріккардо Касатта

2
це досить приголомшливо! Я створив свій власний варіант, використовуючи attr, щоб уникнути дублювання вмісту: jsfiddle.net/coemL8rf/2
Jayen

@Jayen Nice - Можливо, скористайтеся titleзамість цього, data-spacerщоб отримати підказку на миші :)
William George

@Jayen, я просто спробував ваш, і він, схоже, не вкорочує клітинку з правого боку, тому він не відповідає вимозі, що клітини переповнюються рівномірно. Я використовую Chrome 46.
Сем

@Sam так, це правильно. мій приклад показує лише, що обидва типи комірок можна зробити без дублювання вмісту. я не намагався відповісти на питання, просто показав інший шлях. якщо ви міняєте HTML-код у моєму прикладі, він працює як ви хочете.
Jayen

24

Я зіткнувся з тим же викликом кілька днів тому. Здається, Луцифер Сем знайшов найкраще рішення.

Але я помітив, що ви повинні дублювати вміст у розпірнім елементі. Думав, що це не так вже й погано, але я також хотів би застосувати titleспливаюче вікно для відрізаного тексту. А це означає, що довгий текст з’явиться в моєму коді втретє.

Тут я пропоную отримати доступ до titleатрибуту з :afterпсевдоелемента для створення розпірки та підтримання чистоти HTML.

Працює на 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/


Не могла погодитися більше, геніальне!
Михайло

набагато краще, ніж інші рішення css, тому що вони працюють в обох порядках, тобто якщо більше комірок вмісту знаходиться після комірки з меншим вмістом.
buggedcom

19

Якщо Javascript прийнятний, я склав швидку процедуру, яку ви можете використовувати як вихідну точку. Він динамічно намагається адаптувати ширину комірок, використовуючи внутрішню ширину прольоту, в реакцію на події зміни розміру вікна.

В даний час передбачається, що кожна комірка зазвичай отримує 50% від ширини рядка, і вона зруйнує праву комірку, щоб утримати ліву комірку на максимальній ширині, щоб уникнути переповнення. Ви можете реалізувати набагато складнішу логіку балансування ширини, залежно від випадків використання. Сподіваюсь, це допомагає:

Розмітка для рядка, який я використовував для тестування:

<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, який підключає подію зміни розміру:

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

Є набагато простіше і елегантніше рішення.

У комірці таблиці, до якої потрібно застосувати усікання, просто включіть div-контейнер із компонуванням таблиці css: fix. Цей контейнер займає повну ширину комірки батьківської таблиці, тому він навіть діє чуйно.

Обов’язково застосуйте усічення до елементів таблиці.

Працює від 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>

та css:

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

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

ось робочий Fiddle https://jsfiddle.net/d0xhz8tb/


Це рішення потребує 2 додаткових блокових елементів для досягнення неструктурного ефекту. Можна встановити одну клітинку таблиці на "display: table", що дозволяє позбутися однієї з дівок. jsfiddle.net/rza4hfcv Не впевнений, що я повинен з цього приводу думати. Але дякую, що поділилися своїм рішенням!
армін

У вас виникли проблеми з цим рішенням? Я думаю про використання цього в професійній обстановці.
армін

@armin, спробуйте дублювати клітинку, яку ви хочете усікати: ви не можете ставити більше однієї сторони.
DanielM

Я б не сказав, що це остаточне рішення. Ви втрачаєте одну з головних переваг таблиці: розмір стовпців відповідно до їх вмісту. Якщо встановити кожен стовпець подібним чином, усі вони матимуть однакову ширину, незалежно від довжини його вмісту.
DanielM

@DanielM Ви можете розширити рішення шляхом подальшого введення таблиці - як у старих днях-макетів таблиці - але тепер лише за допомогою css.
армін

11

Проблема полягає у «макеті таблиці: фіксований», який створює стовпчики рівномірно розташованої фіксованої ширини. Але вимкнення цього властивості css призведе до вбивства переповнення тексту, оскільки таблиця стане максимально великою (і чим не зазначається переповнення).

Вибачте, але в цьому випадку Фред не може мати свій торт і їсти його .. якщо тільки орендодавець не дасть Celldito менше місця для роботи, в першу чергу, Фред не може використовувати його ..


9

Ви можете спробувати «зважити» певні стовпці, наприклад:

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

Ви також можете спробувати ще кілька цікавих налаштувань, як-от використання стовпців із шириною 0% та використання комбінації властивості 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>

Ви отримуєте ідею.


3

Так, я б сказав, що у тридцяти пісень це є, немає способу це зробити, якщо ви не використовуєте метод js. Ви говорите про складний набір умов надання, який вам доведеться визначити. наприклад, що станеться, коли обидві клітини стають занадто великими для своїх квартир, вам доведеться вирішити, хто має пріоритет, або просто просто надати їм відсоток площі, і якщо вони будуть переповнені, вони обидва займуть цю площу, і лише якщо у них буде пробіл ви розтягуєте ноги в іншій комірці, в будь-якому випадку немає можливості зробити це з css. Хоча є деякі досить прикольні речі, які люди роблять із css, про які я не думав. Я дуже сумніваюся, що ти можеш це зробити.


3

Як і samplebias відповідь, якщо Javascript - прийнятна відповідь, я створив плагін jQuery спеціально для цієї мети: https://github.com/marcogrcr/jquery-tableoverflow

Щоб використовувати плагін, просто введіть

$('selector').tableoverflow();

Повний приклад: http://jsfiddle.net/Cw7TD/3/embedded/result/

Зміни:

  • Виправити jsfiddle для сумісності IE.
  • Виправте jsfiddle для кращої сумісності браузера (Chrome, Firefox, IE8 +).

3

Скористайтеся деяким хакером css, мабуть, display: table-column;може допомогти:

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


Чудове рішення! Дякую!
Valeriu92

Виглядав досить добре, поки я не додав статичну комірку перед гнучким осередком: jsfiddle.net/7u59asyp/5
Сем

це єдиний, хто працював для мене, хоча і не ідеально, оскільки у мене є 4 стовпчики з різним очікуваним розміром вмісту
вниз

3

Просто додайте до своїх правил такі правила td:

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

Приклад:

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: Якщо ви хочете встановити власну ширину для іншого tdвластивості використання min-width.


Проблема з цим полягає в тому, що стовпці таблиці за замовчуванням споживають простір пропорційно. Якщо вміст одного ряду довший, ніж іншого, він виділить більше ширини. Однак ця техніка рівномірно розділяє простір. Чи є робота навколо?
Малік Брахімі

2

Це питання спливає в Google, тому в моєму випадку я використовував фрагмент css з https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/ але застосувавши його до td, НЕ дав бажаний результат.

Мені довелося додати тег div навколо тексту в td, і еліпсис нарешті спрацював.

Скорочений HTML-код;

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

Скорочений CSS;

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

0

Перевірте, чи "норап" вирішує проблему в такій мірі. Примітка: nowrap не підтримується в 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: nowrapмає той же ефект, що і nowrapатрибут (і я використовую його в прикладі). Додавання сюди нічого не змінює, наскільки я можу сказати.
s4y

0

ви можете встановити ширину правої комірки на мінімальну необхідну ширину, а потім застосувати переповнений + переповнення тексту до внутрішньої частини лівої комірки, але Firefox тут баггі ...

хоча, здається, флешбокс може допомогти


0

Я нещодавно працюю над цим. Перевірте цей тест jsFiddle , спробуйте самостійно змінити ширину базової таблиці, щоб перевірити поведінку).

Рішення полягає в тому, щоб вбудувати таблицю в іншу:

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

Чи задоволений зараз Фред розширенням Celldito?


Вибачте за відсутність відповіді! Я не бачу, як це поводиться по-різному від однієї таблиці. Коли я переглядаю загадку в Chrome або Firefox, вона виглядає точно як другий скріншот із запитання. Я щось пропускаю?
s4y

Вибачте, посилання було не тим, яке я публікував. Це насправді цей jsfiddle.net/VSZPV/2 . Змініть текст обох комірок та ширину основної таблиці для тестування. Сподіваюся, це те, що ви шукаєте ...
IG Pascual

0

Не знаю, чи це комусь допоможе, але я вирішив подібну проблему, вказавши конкретні розміри ширини у відсотках для кожного стовпця. Очевидно, це було б найкраще, якщо кожен стовпець має вміст із шириною, яка не дуже варіюється.


-1

У мене був той самий випуск, але мені потрібно було відображати кілька рядків (де text-overflow: ellipsis;не вдається). Я вирішую це за допомогою textareaвнутрішнього а, TDа потім стилю його поводитись як клітинка таблиці.

    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

З огляду на те, що "таблиця-макет: виправлена" є найважливішою вимогою компонування, що це створює рівномірно розташовані нерегульовані стовпці, але що вам потрібно зробити комірки різної процентної ширини, можливо, встановіть "colspan" ваших комірок на множину?

Наприклад, використовуючи загальну ширину 100 для легких підрахунків відсотків і кажучи, що вам потрібна одна клітинка 80%, а інша 20%, врахуйте:

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

Звичайно, для стовпців 80% і 20% ви можете просто встановити 100% ширину кольшану на 5, 80% на 4 та 20% на 1.


1
Гей @Siubear. Чим це відрізняється від визначення відсоткової ширини на tds?
s4y

Використовувати кольспан таким чином - жахлива ідея. Чому б замість цього не використовувати ширину?
Персі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.