248 votes

Comment puis-je tronquer les cellules d'un tableau, tout en conservant le maximum de contenu possible ?

Rencontrez Fred. C'est une table :

One cell has more content and is wider, the other has less content and is narrower

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

L'appartement de Fred a la fâcheuse habitude de changer de taille, il a donc appris à cacher une partie de son contenu pour ne pas bousculer tous les autres logements et pousser le salon de Mme Whitford dans l'oubli :

The cells are now the same size, but only one has its content truncated, and it looks like if the other cell gave if some whitespace, they could both fit.

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

Cela fonctionne, mais Fred a le sentiment tenace que si sa cellule droite (qu'il a surnommée Celldito) cédait un peu d'espace, sa cellule gauche ne serait pas tronquée aussi souvent. Pouvez-vous sauver sa santé mentale ?


En résumé : comment les cellules d'un tableau peuvent-elles déborder de manière uniforme, et seulement lorsqu'elles ont toutes abandonné tout leur espace blanc ?

7 votes

Je pense que vous devrez recourir à JavaScript pour résoudre ce problème.

8 votes

Lolz ... +1 pour la valeur de divertissement :) ... cela doit-il être dynamique ou ne pouvez-vous pas simplement définir une largeur pour chaque colonne ?

108voto

ladislav Points 41
<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/

18 votes

Ugh. Ça marche tellement bien, mais je ne sais pas pourquoi, ce qui me rend nerveux :(

0 votes

Merci ! Cela ne fait pas exactement ce que la question demandait (tronquer toutes les colonnes uniformément), mais le comportement de ce Le code est ce que je recherchais.

4 votes

Notez également que vous pouvez éliminer le <col> en faisant précéder les largeurs d'un préfixe. <td> les styles : jsfiddle.net/7CURQ/64

41voto

Lucifer Sam Points 1768

Je crois que j'ai une solution non-JavaScript ! Je ne voulais pas me contenter d'une solution JavaScript car je trouve inacceptable la légère gigue des choses qui se déplacent après le chargement de la page.

Caractéristiques :

  • Pas de JavaScript
  • Pas de mise en page fixe
  • Pas d'astuces de pondération ou de pourcentage de largeur
  • Fonctionne avec n'importe quel nombre de colonnes
  • Génération simple côté serveur et mise à jour côté client (aucun calcul nécessaire)
  • Compatible avec tous les navigateurs

Comment cela fonctionne : À l'intérieur de la cellule du tableau, placez deux copies du contenu dans deux éléments différents au sein d'un élément conteneur relativement positionné. L'élément d'espacement est positionné de manière statique et, en tant que tel, il affecte la largeur des cellules du tableau. En permettant au contenu de la cellule d'espacement de s'enrouler, nous pouvons obtenir la largeur "optimale" des cellules du tableau que nous recherchons. Cela nous permet également d'utiliser l'élément à positionnement absolu pour limiter la largeur du contenu visible à celle du parent à positionnement relatif.

Testé et fonctionnant dans : IE8, IE9, IE10, Chrome, Firefox, Safari, Opera

Résultat Images :

Nice proportional widthsNice proportional clipping

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

Exemple de 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 votes

Si votre contenu est un mot très long sans espace, cela ne fonctionne pas mais il suffit d'ajouter le trait d'union au conent dans spacer avec &shy ; jsfiddle.net/zAeA2/160

2 votes

c'est assez génial ! j'ai fait ma propre variante en utilisant attr pour éviter de dupliquer le contenu : jsfiddle.net/coemL8rf/2

0 votes

@Jayen Nice - Peut-être utiliser title au lieu de data-spacer pour obtenir une info-bulle au passage de la souris :)

26voto

Henry Feesler Points 21

J'ai été confronté au même défi il y a quelques jours. Il semble Lucifer Sam trouvé la meilleure solution.

Mais j'ai remarqué que vous devez dupliquer le contenu de l'élément d'espacement. J'ai pensé que ce n'était pas si mal, mais j'aimerais aussi appliquer les règles suivantes title popup pour le texte coupé. Et cela signifie que le texte long apparaîtra pour la troisième fois dans mon code.

Je propose ici d'accéder title de l'attribut :after pseudo-élément pour générer un espacement et garder le HTML propre.

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

0 votes

bien mieux que les autres solutions css parce qu'il fonctionne dans les deux ordres, c'est-à-dire si la cellule de plus de contenu est après la cellule de moins de contenu.

1 votes

Un autre bon effet secondaire est qu'il fonctionne en combinaison avec -webkit-line-clamp pour réaliser une troncature multiligne si on le souhaite et si ce n'est pas nécessaire pour supporter l'IE. jsfiddle.net/katdLfe5

18voto

samplebias Points 19805

Si Javascript est acceptable, j'ai mis au point une routine rapide que vous pouvez utiliser comme point de départ. Elle essaie d'adapter dynamiquement la largeur des cellules en utilisant la largeur intérieure d'un span, en réaction aux événements de redimensionnement de la fenêtre.

Actuellement, il part du principe que chaque cellule occupe normalement 50 % de la largeur de la ligne, et il réduit la cellule de droite pour maintenir la cellule de gauche à sa largeur maximale afin d'éviter tout débordement. Vous pouvez mettre en œuvre une logique d'équilibrage de la largeur beaucoup plus complexe, en fonction de vos cas d'utilisation. J'espère que cela vous aidera :

Balisage de la ligne que j'ai utilisée pour les tests :

<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 qui s'accroche à l'événement de redimensionnement :

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

12voto

Andre Haverdings Points 434

Le problème vient de la propriété 'table-layout:fixed' qui crée des colonnes de largeur fixe et régulièrement espacées. Mais la désactivation de cette propriété css va tuer le débordement de texte parce que la table va devenir aussi grande que possible (et qu'il n'y a rien à déborder).

Je suis désolé mais dans ce cas, Fred ne peut pas avoir le beurre et l'argent du beurre. A moins que le propriétaire ne donne à Celldito moins d'espace pour travailler, Fred ne peut pas utiliser son

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X