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?



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/


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.


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

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 .


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>


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.


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


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.


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>

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;

}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.