web-dev-qa-db-fra.com

CSS: tronque les cellules du tableau, mais s'adapte autant que 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>

La maison de Fred a l’habitude bizarre de changer de taille. Il a donc appris à cacher une partie de son contenu afin de ne pas renverser toutes les autres unités et de 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 persistant que si sa cellule droite (surnommée Celldito) cédait un peu d'espace, sa cellule gauche ne serait pas tronquée autant que possible. Pouvez-vous sauver sa santé mentale?


En résumé: Comment les cellules d'une table peuvent-elles déborder de manière égale et uniquement lorsqu'elles ont toutes abandonné tous leurs espaces?

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

64
ladislav

Je pense avoir une solution non-javascript! Mieux vaut tard que jamais, n'est-ce pas? Après tout, c’est une excellente question et Google est partout. Je ne voulais pas me contenter d'un correctif javascript, car je trouve inacceptable le léger vacillement provoqué par le déplacement des objets après le chargement de la page.

Caractéristiques :

  • Pas de javascript
  • Pas de disposition fixe
  • Aucune astuce de pondération ou de largeur en pourcentage
  • 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 plusieurs navigateurs

Fonctionnement : Dans la cellule de tableau, placez deux copies du contenu dans deux éléments différents dans un élément de conteneur positionné de manière relative. L'élément d'espacement est positionné de manière statique et en tant que tel affectera la largeur des cellules du tableau. En laissant le contenu de la cellule d'espacement s'emballer, nous pouvons obtenir la largeur "optimale" des cellules du tableau que nous recherchons. Cela nous permet également d’utiliser l’élément positionné de manière absolue pour limiter la largeur du contenu visible à celle du parent relatif.

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

Images de résultat :

Nice proportional widthsNice proportional clipping

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

Exemple de code 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;
}
36
Lucifer Sam

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

Mais j'ai remarqué que vous devriez dupliquer le contenu de l'élément spacer. Je pensais que ce n'était pas si grave, mais j'aimerais aussi appliquer title popup pour le texte coupé. Et cela signifie que le texte long apparaîtra pour la troisième fois dans mon code.

Ici, je propose d'accéder à l'attribut title de :after pseudo-élément afin de générer un espaceur et de conserver du 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/

23
Henry Feesler

Si Javascript est acceptable, je vous ai concocté une routine rapide que vous pouvez utiliser comme point de départ. Il essaie dynamiquement d'adapter les largeurs de cellule à l'aide de la largeur intérieure d'une plage, en réaction aux événements de redimensionnement de la fenêtre.

Actuellement, il est supposé que chaque cellule obtient normalement 50% de la largeur de la ligne, et elle réduira la cellule de droite pour conserver la cellule de gauche à sa largeur maximale afin d'éviter tout débordement. Vous pouvez implémenter une logique d'équilibrage de largeur beaucoup plus complexe, en fonction de vos cas d'utilisation. J'espère que cela t'aides:

Balisage pour 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 relie 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);
        }
    });
});
18
samplebias

Il existe une solution beaucoup plus simple et élégante.

Dans la cellule de tableau à laquelle vous souhaitez appliquer la troncature, incluez simplement un conteneur div avec css table-layout: fixed. Ce conteneur occupe toute la largeur de la cellule du tableau parent, il réagit donc même.

Assurez-vous d'appliquer une troncature aux éléments du tableau.

Travaux à partir de 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>

et css:

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

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

voici un Fiddlede travail _ https://jsfiddle.net/d0xhz8tb/

15
satyavh

Le problème est le 'tableau-layout: fixed' qui crée des colonnes à largeur fixe et à espacement régulier. Mais la désactivation de cette propriété css supprimera le débordement de texte, car la table deviendra aussi grande que possible (et qu'il n'y ait rien à déborder).

Je suis désolé mais dans ce cas, Fred ne peut pas avoir son gâteau et le manger pour .. sauf si le propriétaire donne à Celldito moins d'espace pour travailler en premier lieu, Fred ne peut pas utiliser le sien ..

11
Andre Haverdings

Vous pouvez essayer de "pondérer" certaines colonnes, comme ceci:

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

Vous pouvez également essayer quelques ajustements plus intéressants, comme utiliser des colonnes à 0% de largeur et utiliser une combinaison de la propriété white-space 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>

Vous avez eu l'idée.

9
Elliot Cameron

Utilisez un peu de css, il semble que le display: table-column; puisse venir à la rescousse:

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

3
blai

Comme samplebias answer, si JavaScript est une réponse acceptable, j’ai créé un plugin jQuery spécialement conçu à cet effet: https://github.com/marcogrcr/jquery-tableoverflow

Pour utiliser le plugin, tapez simplement

$('selector').tableoverflow();

Exemple complet: http://jsfiddle.net/Cw7TD/3/embedded/result/

Modifications:

  • Correction dans jsfiddle pour la compatibilité IE.
  • Correction dans jsfiddle pour une meilleure compatibilité de navigateur (Chrome, Firefox, IE8 +).
3
Marco

Hé oui, je dirais que c'est le cas, il n'y a aucun moyen de le faire à moins d'utiliser une méthode js. Vous parlez d'un ensemble complexe de conditions de rendu que vous devrez définir. par exemple. qu’arrivera-t-il lorsque les deux cellules deviendront trop grandes pour leurs appartements, vous devrez décider qui a la priorité ou simplement leur donner un pourcentage de la superficie et s’ils sont surchargés, ils s’occuperont tous les deux de cette zone et c’est seulement Étirez vos jambes dans l'autre cellule, de toute façon, il n'y a aucun moyen de le faire avec CSS. Bien qu'il y ait certaines choses assez géniales que les gens font avec les CSS, auxquelles je n'ai pas pensé. Je doute vraiment que vous puissiez le faire.

3
user648116

Cette question apparaît tout en haut dans Google. Dans mon cas, j’ai donc utilisé le fragment de code CSS de https://css-tricks.com/snippets/css/truncate-string-with-Ellipsis/ mais en appliquant il n'a pas donné le résultat souhaité au td.

J'ai dû ajouter une balise div autour du texte dans le td et l'Ellipsis a finalement fonctionné.

Code HTML abrégé;

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

CSS abrégé;

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

vous pouvez définir la largeur de la cellule droite sur la largeur minimale requise, puis appliquer le débordement masqué + débordement du texte à l'intérieur de la cellule gauche, mais Firefox est bogué ici ...

bien que, apparemment, flexbox puisse vous aider

0
4esn0k

Vérifiez si "nowrap" résout le problème dans une certaine mesure. Remarque: Nowrap n'est pas pris en charge en 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>
0
amlan

Je ne sais pas si cela aidera quelqu'un, mais j'ai résolu un problème similaire en spécifiant des tailles de largeur spécifiques en pourcentage pour chaque colonne. Évidemment, cela fonctionnerait mieux si chaque colonne avait un contenu dont la largeur ne variait pas trop.

0
DKO

J'ai récemment travaillé dessus. Regardez ceci test jsFiddle , essayez vous-même de changer la largeur de la table de base pour vérifier le comportement).

La solution consiste à incorporer une table dans une autre:

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

Fred est-il maintenant satisfait de l'expansion de Celldito?

0
I.G. Pascual