Pourquoi les points de suspension CSS ne fonctionnent-ils pas dans une cellule de tableau?

150

Prenons l'exemple suivant: ( démo en direct ici )

$(function() {
  console.log("width = " + $("td").width());
});
td {
  border: 1px solid black;
  width: 50px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tbody>
    <tr>
      <td>Hello Stack Overflow</td>
    </tr>
  </tbody>
</table>

Le résultat est: width = 139et les points de suspension n'apparaissent pas.

Qu'est-ce que j'oublie ici?

Misha Moroshko
la source
2
duplication possible d'un dépassement de texte CSS dans une cellule de tableau?
BoltClock
En quelque sorte en double, mais la réponse ne fournit pas de solution de contournement (comme le fait Arlen Cuss).
Florian Margaine
1
widthet heightsur les cellules de table sont toujours utilisées comme largeur et hauteur minimales . Les cellules du tableau sont différentes!
Mr Lister
1
@FlorianMargaine En fait, l'autre question fournit une solution de contournement: mettre un div dans la cellule avec la largeur souhaitée.
Mr Lister
Cependant, je préfère toujours les réponses listées sur cette page.
Florian Margaine

Réponses:

102

Apparemment, en ajoutant:

td {
  display: block; /* or inline-block */
}

résout également le problème.


Une autre solution possible consiste à définir table-layout: fixed;la table et à la définir width. Par exemple: http://jsfiddle.net/fd3Zx/5/

Misha Moroshko
la source
4
Exactement. Les éléments avec display: table-cell(par défaut pour les tdéléments) n'acceptent pas de largeur.
Michael Mior
29
display: block;sorte de vaincre le but d'utiliser une table. J'aime l' table-layout: fixed;option, cela a bien fonctionné pour moi.
Alex K
7
table-layout:fixeddistribue la largeur des colonnes de manière moins intelligente. Existe-t-il une autre option qui affectera la largeur de colonne de la même manière table-layout: normaltout en affichant correctement les points de suspension?
nid le
Cela se visse avec la bordure de la table; pas l'utilisation de max-width.
Charlie
85

Il est également important de mettre

table-layout:fixed;

Sur la table contenant, il fonctionne donc bien dans IE9 (si vous utilisez max-width) également.

éclairage public
la source
7
cela garantira également que le débordement de texte fonctionne dans des mises en page réactives
jao
3
C'est exactement ce dont j'avais besoin. J'ai la largeur de la table à 100%. Et toutes les colonnes sauf une avec une largeur fixe. Cela permet à la dernière colonne de prendre autant d'espace qu'il en reste.
matthew_360
78

Comme dit précédemment, vous pouvez utiliser td { display: block; }mais cela va à l'encontre de l'objectif d'utiliser une table.

Vous pouvez l'utiliser, table { table-layout: fixed; }mais vous souhaitez peut-être qu'il se comporte différemment pour certaines colonnes.

Donc, la meilleure façon d'obtenir ce que vous voulez serait d'encapsuler votre texte dans un <div>et d'appliquer votre CSS au <div>(pas au <td>) comme ceci:

td {
  border: 1px solid black;
}
td > div {
  width: 50px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
marcosbdm
la source
2
C'est la méthode la plus simple que j'ai vue et elle fonctionne réellement dans IE8.
Keith Ketterer
2
C'est en fait la meilleure solution que j'ai vue sur les points de suspension dans les tableaux.
membre du
41

Essayez d'utiliser à la max-widthplace de width, le tableau calculera toujours la largeur automatiquement.

Fonctionne même en ie11(avec le mode de compatibilité ie8).

td.max-width-50 {
  border: 1px solid black;
  max-width: 50px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
<table>
  <tbody>
    <tr>
      <td class="max-width-50">Hello Stack Overflow</td>
    </tr>
    <tr>
      <td>Hello Stack Overflow</td>
    </tr>
    <tr>
      <td>Hello Stack Overflow</td>
    </tr>
  </tbody>
</table>

jsfiddle .

Asherah
la source
1
Bien repéré. Il est probablement préférable d'utiliser les deux , afin que l'élément ait une largeur fixe. Sinon, il pourrait être plus court si le contenu le permettait.
LSerni
Bien mieux que l'affichage de hack; displayhack vis avec la bordure de la table.
Charlie
21

Page de démonstration

Pour les tableaux avec une largeur dynamique, j'ai trouvé le moyen ci-dessous de produire des résultats satisfaisants. Chacun <th>qui souhaite avoir une capacité de texte coupé doit avoir un élément d'habillage interne qui enveloppe le contenu de l' <th>autorisation text-overflowde travailler.

Le vrai truc est de définir max-width(sur le <th>) en vwunités .

Cela entraînera effectivement que la largeur de l'élément soit "liée" à la largeur de la fenêtre (fenêtre du navigateur) et entraînera un découpage de contenu réactif. Réglez les vwunités sur une valeur satisfaisante nécessaire.

CSS minimal:

th{ max-width:10vw; }
      
th > .wrap{ 
   text-overflow:ellipsis;
   overflow:hidden;
   white-space:nowrap;
}

Voici une démo exécutable:

table {
  font: 18px Arial;
  width: 40%;
  margin: 1em auto;
  color: #333;
  border: 1px solid rgba(153, 153, 153, 0.4);
}

table td, table th {
  text-align: left;
  padding: 1.2em 20px;
  white-space: nowrap;
  border-left: 1px solid rgba(153, 153, 153, 0.4);
}

table td:first-child, table th:first-child {
  border-left: 0;
}

table th {
  border-bottom: 1px solid rgba(153, 153, 153, 0.4);
  font-weight: 400;
  text-transform: uppercase;
  max-width: 10vw;
}

table th > .wrap {
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}
<table>
    <thead>
        <tr>
            <th>
                <div class="wrap" title="Some long title">Some long title</div>
            </th>
            <th>
                <div class="wrap">Short</div>
            </th>
            <th>
                <div class="wrap">medium one</div>
            </th>
            <th>
                <div class="wrap" title="endlessly super long title which no developer likes to see">endlessly super long title which no developer likes to see</div>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>-</td>
            <td>-</td>
            <td>-</td>
            <td>very long text here</td>
        </tr>
    </tbody>
</table>

vsync
la source
3

Le simple fait de proposer une alternative car j'avais ce problème et aucune des autres réponses ici n'a eu l'effet souhaité que je voulais. Alors à la place, j'ai utilisé une liste. Maintenant, sémantiquement, les informations que je produisais auraient pu être considérées à la fois comme des données tabulaires mais aussi comme des données répertoriées.

Donc à la fin ce que j'ai fait était:

<ul>
    <li class="group">
        <span class="title">...</span>
        <span class="description">...</span>
        <span class="mp3-player">...</span>
        <span class="download">...</span>
        <span class="shortlist">...</span>
    </li>
    <!-- looped <li> -->
</ul>

Donc, fondamentalement, ulest table, liest tret spanest td.

Ensuite, en CSS, j'ai défini les spanéléments comme étant display:block;et float:left;(je préfère cette combinaison à inline-blockcar elle fonctionnera dans les anciennes versions d'IE, pour effacer l'effet flottant, voir: http://css-tricks.com/snippets/css/clear- fix / ) et pour avoir aussi les ellipses:

span {
    display: block;
    float: left;
    width: 100%;

    // truncate when long
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

Ensuite, tout ce que vous faites est de définir max-widthsvos portées et cela donnera à la liste l'apparence d'un tableau.

Diggersworld
la source
pouvez-vous appliquer ul à l'intérieur de td (par exemple <td><ul>...</ul></td>)? Cela ne semble pas fonctionner pour moi :(
Sam
2

Au lieu d'utiliser des points de suspension pour résoudre le problème du texte débordant, j'ai trouvé qu'une entrée désactivée et stylisée avait une meilleure apparence et permettait toujours à l'utilisateur de visualiser et de sélectionner la chaîne entière s'il en avait besoin.

<input disabled='disabled' style="border: 0; padding: 0; margin: 0" />

Il ressemble à un champ de texte mais est surligné, donc plus convivial

craigsnyders
la source
2
Ce n'est pas convivial car en utilisant des technologies d'assistance, cela est mal lu en tant qu'entrée et ainsi l'utilisateur pense qu'il peut entrer quelque chose. Il n'est tout à fait pas normal de mal utiliser la sémantique des éléments.
Carlo le
OMG, c'est tellement intelligent! puisqu'il fait partie du tableau, définissez simplement l'entrée comme sans bordure avec un arrière-plan transparent. J'adore cette solution!
Sam le
1

Vérifiez la box-sizingpropriété css de vos tdéléments. J'ai eu un problème avec le modèle css qui le met à border-boxvaleur. Vous avez besoin de set box-sizing: content-box.

David Slavík
la source
0

Laissez vos tables telles qu'elles sont. Enveloppez simplement le contenu dans les TD avec une étendue sur laquelle le CSS de troncature est appliqué.

/* CSS */
.truncate {
    width: 50px; /*your fixed width */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: block; /* this fixes your issue */
}

<!-- HTML -->
<table>
    <tbody>
        <tr>
            <td>
                <span class="truncate">
                    Table data to be truncated if it's too long.
                </span>
            </td>
        </tr>
    </tbody>
</table>
Jeff Sieffert
la source
J'ai essayé cela, cela ne fonctionne pas sur DataTables.net. une idée?
Sam le
-2

Si vous ne voulez pas définir max-width sur td (comme dans cette réponse ), vous pouvez définir max-width sur div:

function so_hack(){}

function so_hack(){} http://jsfiddle.net/fd3Zx/754/ function so_hack(){}

function so_hack(){}

Remarque: 100% ne fonctionne pas, mais 99% fait l'affaire dans FF. Les autres navigateurs modernes n'ont pas besoin de hacks div idiots.

td {
  bordure: 1px noir uni;
    padding-left: 5px;
    padding-right: 5px;
}
td> div {
    largeur max: 99%;
    débordement caché;
    text-overflow: points de suspension;
    espace blanc: nowrap;

}
Timo Kähkönen
la source