Limitez la longueur du texte à n lignes à l'aide de CSS


516

Est-il possible de limiter une longueur de texte à "n" lignes en utilisant CSS (ou de le couper en cas de débordement vertical).

text-overflow: ellipsis; ne fonctionne que pour le texte d'une ligne.

texte original:

Ultrices natoque mus mattis, aliquam, cras en pellentesque
tincidunt elit purus lectus, vel ut aliquet, elementum nunc
nunc rhoncus placerat urna! Sit est sed! Ut penatibus turpis
mus tincidunt! Dapibus sed aenean, magna sagittis, lorem velit

sortie souhaitée (2 lignes):

Ultrices natoque mus mattis, aliquam, cras in pellentesque
tincidunt elit purus lectus, vel ut aliquet, elementum ...


1
Juste une note: les ellipses de débordement de texte ne sont pas prises en charge sur Firefox, voir bugzilla.mozilla.org/show_bug.cgi?id=312156
Joril

8
semble que quelqu'un s'est enfui en le faisant avec juste css mobify.com/dev/multiline-ellipsis-in-pure-css
Gaurav Shah

ne fonctionne pas sur IE10. Il fonctionne le 11.
user2060451

@GauravShah Merci. Il fonctionne également sur IE10. La plupart des solutions ici ne sont pas multi-navigateurs.
user2060451

Réponses:


656

Il existe un moyen de le faire en utilisant la syntaxe non officielle de raccourcissement de ligne , et à partir de Firefox 68, il fonctionne dans tous les principaux navigateurs.

body {
   margin: 20px;
}

.text {
   overflow: hidden;
   text-overflow: ellipsis;
   display: -webkit-box;
   -webkit-line-clamp: 2; /* number of lines to show */
   -webkit-box-orient: vertical;
}
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam consectetur venenatis blandit. Praesent vehicula, libero non pretium vulputate, lacus arcu facilisis lectus, sed feugiat tellus nulla eu dolor. Nulla porta bibendum lectus quis euismod. Aliquam volutpat ultricies porttitor. Cras risus nisi, accumsan vel cursus ut, sollicitudin vitae dolor. Fusce scelerisque eleifend lectus in bibendum. Suspendisse lacinia egestas felis a volutpat.
</div>

Sauf si vous vous souciez des utilisateurs d'IE, il n'y a pas besoin de le faire line-heightet de recourir à des max-heightsolutions de rechange.


3
par exemple, avec une certaine taille de police à hauteur de ligne, vous pouvez voir une partie de la ligne suivante également avec text-align: justifier, les points de suspension ne sont pas à la fin de la dernière ligne, mais chevauchent le texte à la position, il serait, si le texte était aligné à gauche
Matus

3
voici le violon: jsfiddle.net/csYjC/1122 pendant que je le préparais, j'ai découvert, qu'une partie de la dernière ligne n'est visible que lorsqu'il y a du rembourrage
Matus

Eh bien, personne n'a dit que cette magie noire non standard uniquement Webkit fonctionnerait parfaitement tout le temps. Vous pouvez utiliser un remplissage sur un autre conteneur, peut-être parent. L'encadrement de texte dans la balise <p> est parfaitement logique: jsfiddle.net/csYjC/1129
Evgeny

2
Notez que, à partir de ce commentaire, -webkit-line-clamp ne respecte pas la visibilité: caché. Cela m'a coûté quelques heures de débogage. Voici un rapport de bogue de support: bugs.webkit.org/show_bug.cgi?id=45399 .
Kevin

3
Si vous rencontrez des problèmes pour -webkit-box-orient: vertical;être caché lors de la compilation de scss, essayez ceci /* autoprefixer: ignore next */ -webkit-box-orient: vertical;
Salam

110

Ce que vous pouvez faire est le suivant:

.max-lines {
  display: block;/* or inline-block */
  text-overflow: ellipsis;
  word-wrap: break-word;
  overflow: hidden;
  max-height: 3.6em;
  line-height: 1.8em;
}
<p class="max-lines">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vitae leo dapibus, accumsan lorem eleifend, pharetra quam. Quisque vestibulum commodo justo, eleifend mollis enim blandit eu. Aenean hendrerit nisl et elit maximus finibus. Suspendisse scelerisque consectetur nisl mollis scelerisque.</p>

max-height:= line-height:× <number-of-lines>in em.



Semble être la meilleure solution possible pour moi aussi, mais comme l'a noté @rishiAgar ne se termine pas par des points de suspension. Continue de fonctionner comme un clip.
David Carrigan

Je pense que vous devrez ajouter les attributs display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;pour faire apparaître les points de suspension. Mais cela ne fonctionnera que dans Chrome. Pour une solution qui fonctionne également sur Firefox, regardez ici: stackoverflow.com/a/20595073/1884158 Et voici un tutoriel utile sur le sujet: css-tricks.com/line-clampin
modulitos

34

Solution multi-navigateur fonctionnelle

Ce problème nous tourmente tous depuis des années.

Pour vous aider dans tous les cas, j'ai présenté l'approche CSS uniquement et une approche jQuery au cas où les mises en garde CSS poseraient problème.

Voici une seule solution CSS que j'ai trouvée qui fonctionne en toutes circonstances, avec quelques mises en garde mineures.

Les bases sont simples, elles masquent le débordement de la travée et définissent la hauteur maximale en fonction de la hauteur de ligne comme suggéré par Eugene Xa.

Ensuite, il y a une pseudo-classe après le div contenant qui place bien les points de suspension.

Avertissements

Cette solution placera toujours les points de suspension, indépendamment de la nécessité.

Si la dernière ligne se termine par une phrase de fin, vous vous retrouverez avec quatre points ....

Vous devrez être satisfait de l'alignement du texte justifié.

Les points de suspension seront à droite du texte, ce qui peut sembler bâclé.

Code + extrait

jsfiddle

.text {
  position: relative;
  font-size: 14px;
  color: black;
  width: 250px; /* Could be anything you like. */
}

.text-concat {
  position: relative;
  display: inline-block;
  word-wrap: break-word;
  overflow: hidden;
  max-height: 3.6em; /* (Number of lines you want visible) * (line-height) */
  line-height: 1.2em;
  text-align:justify;
}

.text.ellipsis::after {
  content: "...";
  position: absolute;
  right: -12px; 
  bottom: 4px;
}

/* Right and bottom for the psudo class are px based on various factors, font-size etc... Tweak for your own needs. */
<div class="text ellipsis">
  <span class="text-concat">
Lorem ipsum dolor sit amet, nibh eleifend cu his, porro fugit mandamus no mea. Sit tale facete voluptatum ea, ad sumo altera scripta per, eius ullum feugait id duo. At nominavi pericula persecuti ius, sea at sonet tincidunt, cu posse facilisis eos. Aliquid philosophia contentiones id eos, per cu atqui option disputationi, no vis nobis vidisse. Eu has mentitum conclusionemque, primis deterruisset est in.

Virtute feugait ei vim. Commune honestatis accommodare pri ex. Ut est civibus accusam, pro principes conceptam ei, et duo case veniam. Partiendo concludaturque at duo. Ei eirmod verear consequuntur pri. Esse malis facilisis ex vix, cu hinc suavitate scriptorem pri.
  </span>
</div>

Approche jQuery

À mon avis, c'est la meilleure solution, mais tout le monde ne peut pas utiliser JS. Fondamentalement, le jQuery vérifiera n'importe quel élément .text, et s'il y a plus de caractères que la var max prédéfinie, il coupera le reste et ajoutera des points de suspension.

Il n'y a aucune mise en garde à cette approche, mais cet exemple de code est uniquement destiné à démontrer l'idée de base - je ne l'utiliserais pas en production sans l'améliorer pour deux raisons:

1) Il réécrira le html interne des elems .text. si nécessaire ou non. 2) Il ne fait aucun test pour vérifier que le html interne n'a pas d'elems imbriqués - vous comptez donc beaucoup sur l'auteur pour utiliser correctement le .text.

Édité

Merci pour la capture @markzzz

Extrait de code

jsfiddle

setTimeout(function()
{
	var max = 200;
  var tot, str;
  $('.text').each(function() {
  	str = String($(this).html());
  	tot = str.length;
    str = (tot <= max)
    	? str
      : str.substring(0,(max + 1))+"...";
    $(this).html(str);
  });
},500); // Delayed for example only.
.text {
  position: relative;
  font-size: 14px;
  color: black;
  font-family: sans-serif;
  width: 250px; /* Could be anything you like. */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="text">
Old men tend to forget what thought was like in their youth; they forget the quickness of the mental jump, the daring of the youthful intuition, the agility of the fresh insight. They become accustomed to the more plodding varieties of reason, and because this is more than made up by the accumulation of experience, old men think themselves wiser than the young.
</p>

<p class="text">
Old men tend to forget what thought was like in their youth;
</p>
 <!-- Working Cross-browser Solution

This is a jQuery approach to limiting a body of text to n words, and end with an ellipsis -->


3
Votre solution CSS n'est pas si bonne, car qu'en est-il que le texte ne déborde pas? c'est aussi montrer "..." ...
user5260143

Mais la version jQuery ajoute également des points si le texte est plus court: jsfiddle.net/o82opadm/35
markzzz

@markzzz - merci pour ça, aucune idée de comment j'ai raté ça :-) Je l'ai révisé maintenant, mais ce n'est pas quelque chose que j'utiliserais en production sans un peu plus de travail. Mais au moins l'idée de base est énoncée.
asimovwasright

1
J'ai trouvé que la solution CSS uniquement semble bien fonctionner, mais uniquement si vous n'utilisez que des mesures de pixels. Les EM et les pourcentages m'ont causé des ennuis. Et j'ai ajouté les points de suspension comme un <a> style à position: absolu en bas à droite pour ceux qui veulent cliquer sur le lien et en savoir plus. Dans mon cas, je savais que le texte déborderait toujours, donc jQuery n'était pas nécessaire. Merci pour la solution CSS utile!
Mentalist

30

Pour autant que je puisse voir, cela ne serait possible qu'en utilisant height: (some em value); overflow: hiddenet même alors, cela n'aurait pas la fantaisie ...à la fin.

Si ce n'est pas une option, je pense que c'est impossible sans un certain prétraitement côté serveur (difficile car le flux de texte est impossible à prévoir de manière fiable) ou jQuery (possible mais probablement compliqué).


16
Cela semble fonctionner pour n'importe quelle taille de police .mytext {overflow: hidden; hauteur de ligne: 1,2 em; hauteur max: 2,4 em; }
Peter

1
@Pedro ouais. Vous pourrez peut-être les parcourir en .mytextutilisant jQuery, savoir s'il a plus de contenu que ce qui est visible et en ajouter un ...manuellement. De cette façon, vous êtes compatible avec les clients sans JS et les clients avec JS peuvent avoir la décoration. Peut-être vaut-il la peine de poser une question distincte à un gourou jQuery; pourrait être possible de le faire assez facilement
Pekka

15

La solution de ce fil est d'utiliser le plugin jquery dotdotdot . Pas une solution CSS, mais elle vous donne beaucoup d'options pour les liens "en savoir plus", le redimensionnement dynamique, etc.


10

la classe CSS suivante m'a aidé à obtenir des points de suspension sur deux lignes.

  .two-line-ellipsis {
        padding-left:2vw;
        text-overflow: ellipsis;
        overflow: hidden;
        width: 325px;
        line-height: 25px;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        padding-top: 15px;
    }

5

Actuellement, vous ne pouvez pas, mais à l'avenir, vous pourrez utiliser text-overflow:ellipis-lastline. Actuellement, il est disponible avec le préfixe du fournisseur dans Opera 10.60+: exemple


5
Cela ne fonctionne pas pour les chaînes multilignes, car cela nécessite également de définir white-scace: nowrap. Voyez ici .
Sebastian Noack

4

J'ai une solution qui fonctionne bien mais à la place des points de suspension, elle utilise un dégradé. Cela fonctionne lorsque vous avez du texte dynamique, vous ne savez donc pas s'il sera assez long pour avoir besoin d'une ellipse. Les avantages sont que vous n'avez pas à faire de calculs JavaScript et cela fonctionne pour les conteneurs de largeur variable, y compris les cellules de tableau, et est multi-navigateur. Il utilise quelques divs supplémentaires, mais il est très facile à implémenter.

Balisage:

<td>
    <div class="fade-container" title="content goes here">
         content goes here
         <div class="fade">
    </div>
</td>

CSS:

.fade-container { /*two lines*/
    overflow: hidden;
    position: relative;
    line-height: 18px; 
    /* height must be a multiple of line-height for how many rows you want to show (height = line-height x rows) */
    height: 36px;
    -ms-hyphens: auto;
    -webkit-hyphens: auto;
    hyphens: auto;
    word-wrap: break-word;
}

.fade {
        position: absolute;
        top: 50%;/* only cover the last line. If this wrapped to 3 lines it would be 33% or the height of one line */
        right: 0;
        bottom: 0;
        width: 26px;
        background: linear-gradient(to right,  rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%);
}

article de blog: http://salzerdesign.com/blog/?p=453

exemple de page: http://salzerdesign.com/test/fade.html


3
.class{
   word-break: break-word;
   overflow: hidden;
   text-overflow: ellipsis;
   display: -webkit-box;
   line-height: 16px; /* fallback */
   max-height: 32px; /* fallback */
   -webkit-line-clamp: 2; /* number of lines to show */
   -webkit-box-orient: vertical;
}

0

J'aime vraiment le line-clamp, mais pas encore de support pour firefox .. donc je vais avec un calcul mathématique et je cache juste le débordement

.body-content.body-overflow-hidden h5 {
    max-height: 62px;/* font-size * line-height * lines-to-show(4 in this case) 63px if you go with jquery */
    overflow: hidden;
}
.body-content h5 {
    font-size: 14px; /* need to know this*/
    line-height:1,1; /*and this*/
}

permet maintenant de dire que vous voulez supprimer et ajouter cette classe via jQuery avec un lien, vous aurez besoin d'avoir un pixel supplémentaire donc la hauteur maximale sera de 63 px, c'est parce que vous devez vérifier à chaque fois si la hauteur est supérieure à 62px, mais dans le cas de 4 lignes, vous obtiendrez un faux vrai, donc un pixel supplémentaire corrigera cela et ne créera aucun problème supplémentaire

je vais coller un coffeescript pour que ce soit juste un exemple, utilise quelques liens qui sont cachés par défaut, avec des classes en lecture et en lecture, il supprimera ceux dont le débordement n'est pas nécessaire et supprimera le corps -classes de débordement

jQuery ->

    $('.read-more').each ->
        if $(this).parent().find("h5").height() < 63
             $(this).parent().removeClass("body-overflow-hidden").find(".read-less").remove()
             $(this).remove()
        else
            $(this).show()

    $('.read-more').click (event) ->
        event.preventDefault()
        $(this).parent().removeClass("body-overflow-hidden")
        $(this).hide()
        $(this).parent().find('.read-less').show()

    $('.read-less').click (event) ->
        event.preventDefault()
        $(this).parent().addClass("body-overflow-hidden")
        $(this).hide()
        $(this).parent().find('.read-more').show()

au fait, n'ajoutez pas de line-clamp à cela, cela réglera la hauteur à 62px (dans ce cas) et vous n'aurez pas la compilation jquery
Alexis

0

Si vous voulez vous concentrer sur chacun, lettervous pouvez faire comme ça, je me réfère à cette question

Si vous voulez vous concentrer sur chacun, wordvous pouvez faire comme ça + espace

Si vous voulez vous concentrer sur chacun, wordvous pouvez faire comme ça + sans espace


-1

Exemple de code de base, apprendre à coder est facile. Vérifiez les commentaires CSS de style.

table tr {
  display: flex;
}
table tr td {
  /* start */
  display: inline-block; /* <- Prevent <tr> in a display css */
  text-overflow: ellipsis;
  white-space: nowrap;
  /* end */
  padding: 10px;
  width: 150px; /* Space size limit */
  border: 1px solid black;
  overflow: hidden;
}
<table>
  <tbody>
    <tr>
      <td>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla egestas erat ut luctus posuere. Praesent et commodo eros. Vestibulum eu nisl vel dui ultrices ultricies vel in tellus.
      </td>
      <td>
        Praesent vitae tempus nulla. Donec vel porta velit. Fusce mattis enim ex. Mauris eu malesuada ante. Aenean id aliquet leo, nec ultricies tortor. Curabitur non mollis elit. Morbi euismod ante sit amet iaculis pharetra. Mauris id ultricies urna. Cras ut
        nisi dolor. Curabitur tellus erat, condimentum ac enim non, varius tempor nisi. Donec dapibus justo odio, sed consequat eros feugiat feugiat.
      </td>
      <td>
        Pellentesque mattis consequat ipsum sed sagittis. Pellentesque consectetur vestibulum odio, aliquet auctor ex elementum sed. Suspendisse porta massa nisl, quis molestie libero auctor varius. Ut erat nibh, fringilla sed ligula ut, iaculis interdum sapien.
        Ut dictum massa mi, sit amet interdum mi bibendum nec.
      </td>
    </tr>
    <tr>
      <td>
        Sed viverra massa laoreet urna dictum, et fringilla dui molestie. Duis porta, ligula ut venenatis pretium, sapien tellus blandit felis, non lobortis orci erat sed justo. Vivamus hendrerit, quam at iaculis vehicula, nibh nisi fermentum augue, at sagittis
        nibh dui et erat.
      </td>
      <td>
        Nullam mollis nulla justo, nec tincidunt urna suscipit non. Donec malesuada dolor non dolor interdum, id ultrices neque egestas. Integer ac ante sed magna gravida dapibus sit amet eu diam. Etiam dignissim est sit amet libero dapibus, in consequat est
        aliquet.
      </td>
      <td>
        Vestibulum mollis, dui eu eleifend tincidunt, erat eros tempor nibh, non finibus quam ante nec felis. Fusce egestas, orci in volutpat imperdiet, risus velit convallis sapien, sodales lobortis risus lectus id leo. Nunc vel diam vel nunc congue finibus.
        Vestibulum turpis tortor, pharetra sed ipsum eu, tincidunt imperdiet lorem. Donec rutrum purus at tincidunt sagittis. Quisque nec hendrerit justo.
      </td>
    </tr>
  </tbody>
</table>


4
L'OP recherche une solution multi-lignes. Cela ne fonctionne que sur des lignes de texte uniques.
asimov était

-11

J'ai cherché autour de ça, mais je me rends compte, bon sang mon site utilise php !!! Pourquoi ne pas utiliser la fonction de découpage sur la saisie de texte et jouer avec la longueur maximale ....

Voici également une solution possible pour ceux qui utilisent php: http://ideone.com/PsTaI

<?php
$s = "In the beginning there was a tree.";
$max_length = 10;

if (strlen($s) > $max_length)
{
   $offset = ($max_length - 3) - strlen($s);
   $s = substr($s, 0, strrpos($s, ' ', $offset)) . '...';
}

echo $s;
?>

18
Vous ne pouvez pas utiliser le traitement côté serveur en toute sécurité car vous ne pouvez pas savoir à l'avance combien d'espace le texte prendra dans la page. Cela dépend de la taille de la police, des paramètres de taille du texte du navigateur, du niveau de zoom du navigateur, etc.
ermannob
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.