Débordement de texte CSS dans une cellule de tableau?

501

Je souhaite utiliser CSS text-overflowdans une cellule de tableau, de sorte que si le texte est trop long pour tenir sur une seule ligne, il se coupera avec des points de suspension au lieu de passer à plusieurs lignes. Est-ce possible?

J'ai essayé ceci:

td {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

Mais le white-space: nowrapsemble faire en sorte que le texte (et sa cellule) se développe continuellement vers la droite, poussant la largeur totale du tableau au-delà de la largeur de son conteneur. Sans elle, cependant, le texte continue de se dérouler sur plusieurs lignes lorsqu'il atteint le bord de la cellule.

daGUY
la source
9
Les cellules du tableau ne gèrent pas overflowbien. Essayez de mettre un div dans la cellule et de le styliser.
M. Lister

Réponses:

898

Pour découper du texte avec des points de suspension lorsqu'il déborde d'une cellule de tableau, vous devrez définir la max-widthpropriété CSS sur chaque tdclasse pour que le débordement fonctionne. Aucun div supplémentaire de mise en page n'est requis

td {
    max-width: 100px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

Pour des mises en page réactives; utilisez la max-widthpropriété CSS pour spécifier la largeur minimale effective de la colonne, ou utilisez simplement max-width: 0;pour une flexibilité illimitée. En outre, la table contenant aura généralement besoin d'une largeur spécifique width: 100%;, et les colonnes auront généralement leur largeur définie en pourcentage de la largeur totale

table {
    width: 100%;
}
td {
    max-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
td.columnA {
    width: 30%;
}
td.columnB {
    width: 70%;
}

Historique: pour IE 9 (ou moins), vous devez l'avoir dans votre code HTML, pour résoudre un problème de rendu spécifique à IE

<!--[if IE]>
<style>
    table {
        table-layout: fixed;
        width: 100px;
    }
</style>
<![endif]-->
TFD
la source
7
Le tableau a également besoin d'une largeur pour que cela fonctionne dans IE. jsfiddle.net/rBthS/69
Trevor Dixon
1
Si vous définissez width: 100%;et que min-width: 1px;la cellule sera toujours aussi large que possible et n'utilisera des points de suspension pour tronquer le texte qu'en cas de besoin (pas lorsque la largeur de l'élément atteint une certaine taille) - cela est très utile pour les mises en page réactives.
Duncan Walker
2
@OzrenTkalcecKrznaric, il fonctionne en display: table-celleffet, mais pas lorsque le max-widthest défini en pourcentage (%). Testé sur FF 32
Greg
14
(Suite à ce qui précède) dans le cas où vous utilisez des valeurs%, alors utiliser uniquement table-layout: fixedsur l'élément avec display: tablefera l'affaire
Greg
1
Que diriez-vous si vous souhaitez que la largeur des colonnes soit affectée automatiquement sur un mode réactif comme le tableau réactif bootstrap? la définition d'une largeur max va empiéter sur cela. Y at-il un travail autour?
nid
81

La spécification d'une max-widthlargeur fixe ou fixe ne fonctionne pas dans toutes les situations, et le tableau doit être fluide et espacer automatiquement ses cellules. C'est à ça que servent les tables.

Utilisez ceci: http://jsfiddle.net/maruxa1j/

HTML:

<td class="ellipsis">
    <span>This Text Overflows and is too large for its cell.</span>
</td>

CSS:

.ellipsis {
    position: relative;
}
.ellipsis:before {
    content: '&nbsp;';
    visibility: hidden;
}
.ellipsis span {
    position: absolute;
    left: 0;
    right: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

Fonctionne sur IE9 et autres navigateurs.

AnthumChris
la source
Remarque: cette solution encapsule le contenu des cellules dans des <span>éléments.
Roy Tinker
2
C'est une solution vraiment intelligente et fonctionne bien pour toutes les tables pour lesquelles j'aurais besoin d'une solution. Cependant, il vous oblige à définir des largeurs si vous ne voulez pas que toutes les cellules du tableau soient de la même largeur.
Kevin Beal
Lorsqu'il n'y a pas de largeurs fixes, cette solution fonctionne mieux. Très intelligent en effet!
avidenic
1
Cela maintient l'alignement vertical lorsque display: blockaucune autre solution comme celle-ci ne l'a pas fait
j3ff
La meilleure solution de tous les temps! Assez ingénieux. Merci beaucoup.
ClownCoder
39

Pourquoi cela se produit-il?

Il semble que cette section sur w3.org suggère que le débordement de texte ne s'applique qu'aux éléments de bloc :

11.1.  Overflow Ellipsis: the ‘text-overflow’ property

text-overflow      clip | ellipsis | <string>  
Initial:           clip   
APPLIES TO:        BLOCK CONTAINERS               <<<<
Inherited:         no  
Percentages:       N/A  
Media:             visual  
Computed value:    as specified  

Le MDN dit la même chose .

Ce jsfiddle a votre code (avec quelques modifications de débogage), qui fonctionne bien s'il est appliqué à un divau lieu d'un td. Il a également la seule solution de contournement à laquelle je pouvais rapidement penser, en enveloppant le contenu du tddans un divbloc conteneur. Cependant, cela ressemble à un balisage "moche" pour moi, donc j'espère que quelqu'un d'autre aura une meilleure solution. Le code pour tester cela ressemble à ceci:

td, div {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border: 1px solid red;
  width: 80px;
}
Works, but no tables anymore:
<div>Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah.</div>

Works, but non-semantic markup required:
<table><tr><td><div>Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah.</div></td></tr></table>

Jeroen
la source
2
Bien, merci. Je ne pouvais pas supprimer les cellules du tableau de mon balisage, alors à la place, j'ai simplement enveloppé le contenu dans des divs (avec leurs largeurs définies sur les largeurs des cellules) et y ai appliqué le débordement à la place. A fonctionné comme un charme!
daGUY
28

Dans le cas où vous ne souhaitez pas définir de largeur fixe

La solution ci-dessous vous permet d'avoir un contenu de cellule de tableau qui est long, mais ne doit pas affecter la largeur du tableau parent, ni la hauteur de la ligne parent. Par exemple, lorsque vous souhaitez avoir un tableau avec width:100%lequel s'applique toujours la fonction de dimensionnement automatique à toutes les autres cellules. Utile dans les grilles de données avec une colonne "Notes" ou "Commentaire" ou quelque chose.

entrez la description de l'image ici

Ajoutez ces 3 règles à votre CSS:

.text-overflow-dynamic-container {
    position: relative;
    max-width: 100%;
    padding: 0 !important;
    display: -webkit-flex;
    display: -moz-flex;
    display: flex;
    vertical-align: text-bottom !important;
}
.text-overflow-dynamic-ellipsis {
    position: absolute;
    white-space: nowrap;
    overflow-y: visible;
    overflow-x: hidden;
    text-overflow: ellipsis;
    -ms-text-overflow: ellipsis;
    -o-text-overflow: ellipsis;
    max-width: 100%;
    min-width: 0;
    width:100%;
    top: 0;
    left: 0;
}
.text-overflow-dynamic-container:after,
.text-overflow-dynamic-ellipsis:after {
    content: '-';
    display: inline;
    visibility: hidden;
    width: 0;
}

Formatez HTML comme ceci dans n'importe quelle cellule de tableau dont vous voulez un débordement de texte dynamique:

<td>
  <span class="text-overflow-dynamic-container">
    <span class="text-overflow-dynamic-ellipsis" title="...your text again for usability...">
      //...your long text here...
    </span>
  </span>
</td>

Appliquez en outre souhaité min-width(ou aucun) à la cellule du tableau.

Bien sûr, le violon: https://jsfiddle.net/9wycg99v/23/

Alph.Dev
la source
La réponse la plus utile, les points de suspension dynamiques sont tout simplement géniaux.
lucifer63
Cela gâche les limites de largeur sélectionnées de chaque colonne, par exemple si vous avez défini certaines colonnes car max-width: Xelles peuvent maintenant être plus larges - je pensais que c'était à cause de display: flexleur utilisation, mais j'ai supprimé cela et ne vois aucune différence ...
user9645
24

Il semble que si vous spécifiez table-layout: fixed;sur l' tableélément, vos styles pour tddevraient prendre effet. Cela affectera également la taille des cellules.

Sitepoint discute un peu des méthodes de disposition de table ici: http://reference.sitepoint.com/css/tableformatting

jongala
la source
2
Cela devrait être la bonne réponse lorsque vous ne souhaitez pas spécifier la largeur du tableau.
adriaan
20

Si vous souhaitez simplement que le tableau soit automatiquement mis en page

Sans utiliser max-width, ni pourcentage de largeur de colonne, table-layout: fixedetc.

https://jsfiddle.net/tturadqq/

Comment ça fonctionne:


Étape 1: laissez simplement la mise en page automatique du tableau faire son travail.

Lorsqu'il y a une ou plusieurs colonnes avec beaucoup de texte, cela réduira autant que possible les autres colonnes, puis encapsulera le texte des longues colonnes:

entrez la description de l'image ici


Étape 2: enveloppez le contenu des cellules dans un div, puis définissez ce div sur max-height: 1.1em

(le 0.1em supplémentaire est pour les caractères qui s'affichent un peu en dessous de la base de texte, comme la queue de 'g' et 'y')

entrez la description de l'image ici


Étape 3: réglez titleles divs

C'est bon pour l'accessibilité, et c'est nécessaire pour la petite astuce que nous utiliserons dans un instant.

entrez la description de l'image ici


Étape 4: ajouter un CSS ::aftersur le div

C'est la partie délicate. Nous définissons un CSS ::after, avec content: attr(title), puis le positionnons au-dessus du div et définissons text-overflow: ellipsis. Je l'ai colorée en rouge ici pour que ce soit clair.

(Notez comment la longue colonne a maintenant des points de suspension)

entrez la description de l'image ici


Étape 5: définissez la couleur du texte div sur transparent

Et c'est fini!

entrez la description de l'image ici

Cameron Price-Austin
la source
2
C'est une solution impressionnante et parfaite! Je me demande pourquoi cela a obtenu un vote négatif au lieu de la plupart des votes positifs !!
zendu
2
Homme merveilleux! (@ user9645 - ce n'est pas vrai: faites-le fonctionner avec une table rendue avec Vue.js - assurez-vous de mettre les titres sur les div, pas sur les td)
Christian Opitz
@ChristianOpitz - Ouais, je dois l'avoir foiré en quelque sorte ... réessayé et ça marche.
user9645
J'ai observé que cette approche échoue lors de l'utilisation <a>au lieu de l' <div>intérieur de la cellule du tableau. L'ajout word-break: break-all;résout le problème. Exemple: jsfiddle.net/de0bjmqv
zendu
Tout simplement génial. Et vous n'avez même pas besoin d'avoir le même texte dans les cellules (les titres suffisent), et alors vous n'avez pas besoin de max-height: 1.1em etc - tout ce dont vous avez besoin pour les divs est position: relative ;.
KS74
13

Lorsqu'il est en pourcentage de largeur de tableau, ou que vous ne pouvez pas définir de largeur fixe sur la cellule du tableau. Vous pouvez demander table-layout: fixed;à le faire fonctionner.

table {
  table-layout: fixed;
  width: 100%;
}
td {
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  border: 1px solid red;
}
<table>
  <tr>
    <td>Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah.</td>
    <td>Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah.</td>
  </tr>
</table>

Autocollants
la source
5

Enveloppez le contenu des cellules dans un bloc flexible. En prime, la cellule s'adapte automatiquement à la largeur visible.

table {
  width: 100%;
}

div.parent {
  display: flex;
}

div.child {
  flex: 1;
  width: 1px;
  overflow-x: hidden;
  text-overflow: ellipsis;
}
<table>
  <tr>
    <td>
      <div class="parent">
        <div class="child">
          xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        </div>
      <div>
    </td>
  </tr>
</table>

abbr
la source
3
J'ai également dû ajouter white-space: nowrap;à la childclasse.
Ross Allen
3

J'ai résolu cela en utilisant un div absolument positionné à l'intérieur de la cellule (relatif).

td {
    position: relative;
}
td > div {
    position: absolute;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;        
}

C'est ça. Ensuite, vous pouvez soit ajouter une valeur top: à la div, soit la centrer verticalement:

td > div {      
    top: 0;
    bottom: 0;
    margin: auto 0;
    height: 1.5em; // = line height 
}

Pour obtenir de l'espace sur le côté droit, vous pouvez réduire un peu la largeur maximale.

Kjetil Hansen
la source
ce serait bien avec un JSFiddle, comme beaucoup d'autres réponses à cette question populaire.
oma
Oui, cela fonctionne, mais j'ai utilisé des styles un peu différents pour les divs: left: 0; top: 0; right: 0; bottom: 0; padding: 2px; pour obtenir la bonne position et avoir le même rembourrage que dans les cellules du tableau.
KS74
0

Cela a fonctionné dans mon cas, à la fois dans Firefox et Chrome:

td {
  max-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  width: 100%;
}
user1338062
la source
-5

Il s'agit de la version qui fonctionne dans IE 9.

http://jsfiddle.net/s27gf2n8/

<div style="display:table; table-layout: fixed; width:100%; " >
        <div style="display:table-row;">
            <div style="display:table-cell;">
                <table style="width: 100%; table-layout: fixed;">
                    <div style="text-overflow:ellipsis;overflow:hidden;white-space:nowrap;">First row. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
                </table>
            </div>
            <div style="display:table-cell;">
                Top right Cell.
            </div>
        </div>
        <div style="display:table-row;">
            <div style="display:table-cell;">
                <table style="width: 100%; table-layout: fixed;">
                    <div style="text-overflow:ellipsis;overflow:hidden;white-space:nowrap;">Second row - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
                </table>
            </div>
            <div style="display:table-cell;">
                Bottom right cell.
            </div>
        </div>
    </div>
Ryan O'Connell
la source
6
un <div> en tant qu'enfant direct de <table>? Cela ne semble pas juste!
Michiel
@michiel FYI - les navigateurs peuvent gérer les Divs sous les balises du tableau.
Ryan O'Connell