Limite la longitud del texto a n líneas usando CSS

515

¿Es posible limitar la longitud de un texto a "n" líneas usando CSS (o cortarlo cuando se desborda verticalmente)?

text-overflow: ellipsis; solo funciona para texto de 1 línea.

texto original:

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

salida deseada (2 líneas):

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

Peter
fuente
1
Sólo una nota: la elipsis de texto de desbordamiento no es compatible con Firefox, ver bugzilla.mozilla.org/show_bug.cgi?id=312156
Joril
8
Parece que alguien se escapó haciéndolo con solo css mobify.com/dev/multiline-ellipsis-in-pure-css
Gaurav Shah
no funciona en IE10. Funciona el 11.
user2060451
@GauravShah Gracias. Funciona también en IE10. La mayoría de las soluciones aquí no son cross browser.
user2060451

Respuestas:

655

Hay una manera de hacerlo usando la sintaxis no oficial de abrazadera de línea , y comenzando con Firefox 68, funciona en todos los principales navegadores.

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>

A menos que te preocupes por los usuarios de IE, no hay necesidad de hacer line-heighty max-heightretroceder.

Evgeny
fuente
3
por ejemplo, con cierto tamaño de fuente a altura de línea, puede ver parte de la siguiente línea también con alineación de texto: justifique, los puntos suspensivos no están al final de la última línea, sino que se superponen al texto en la posición, sería, si el texto estuviera alineado a la izquierda
Matus
3
aquí está el violín: jsfiddle.net/csYjC/1122 mientras lo preparaba, descubrí que parte de la última línea solo es visible cuando hay relleno
Matus
Bueno, nadie dijo que esta magia negra no estándar solo para webkit funcionará perfectamente todo el tiempo. Puede usar relleno en algún otro contenedor, quizás principal. Escribir texto en la etiqueta <p> tiene mucho sentido: jsfiddle.net/csYjC/1129
Evgeny
2
Tenga en cuenta que, a partir de este comentario, -webkit-line-clamp no respeta la visibilidad: oculto. Esto me costó algunas horas de depuración. Aquí hay un informe de error de respaldo: bugs.webkit.org/show_bug.cgi?id=45399 .
Kevin
3
Si tiene problemas para -webkit-box-orient: vertical;estar oculto al compilar scss, intente esto /* autoprefixer: ignore next */ -webkit-box-orient: vertical;
Salam
110

Lo que puedes hacer es lo siguiente:

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

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

Erik Aigner
fuente
13
Está funcionando como desbordamiento de texto: clip, ya que no se muestra (...)
rishiAgar
Parece ser la mejor solución posible para mí también, pero como señaló @rishiAgar no termina con puntos suspensivos. Continúa funcionando como un clip.
David Carrigan
Creo que tendrá que agregar los atributos display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;para que aparezcan los puntos suspensivos. Pero esto solo funcionará en Chrome. Para una solución que también funcione en Firefox, mira aquí: stackoverflow.com/a/20595073/1884158 Y aquí hay un tutorial útil sobre el tema: css-tricks.com/line-clampin
modulitos
34

Solución de trabajo entre navegadores

Este problema nos ha estado afectando a todos por años.

Para ayudar en todos los casos, he presentado el enfoque solo CSS y un enfoque jQuery en caso de que las advertencias css sean un problema.

Aquí hay una solución de CSS que se me ocurrió que funciona en todas las circunstancias, con algunas advertencias menores.

Los conceptos básicos son simples, oculta el desbordamiento del tramo y establece la altura máxima en función de la altura de la línea como lo sugiere Eugene Xa.

Luego hay una pseudo clase después del div que contiene que coloca bien los puntos suspensivos.

Advertencias

Esta solución siempre colocará los puntos suspensivos, independientemente de si es necesario.

Si la última línea termina con una oración final, terminarás con cuatro puntos ...

Deberá estar contento con la alineación de texto justificada.

Los puntos suspensivos estarán a la derecha del texto, que puede verse descuidado.

Código + Fragmento

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>

Enfoque jQuery

En mi opinión, esta es la mejor solución, pero no todos pueden usar JS. Básicamente, jQuery verificará cualquier elemento .text, y si hay más caracteres que el valor máximo predeterminado var, cortará el resto y agregará puntos suspensivos.

No hay advertencias para este enfoque, sin embargo, este ejemplo de código solo pretende demostrar la idea básica: no usaría esto en producción sin mejorarlo por dos razones:

1) Reescribirá el html interno de .text elems. si es necesario o no 2) No hace ninguna prueba para verificar que el html interno no tenga elementos anidados, por lo que confía mucho en el autor para usar el .text correctamente.

Editado

Gracias por la captura @markzzz

Fragmento de código

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

asimovwasright
fuente
3
Su solución CSS no es tan buena, porque ¿qué pasa con el caso de que el texto no se desborde? también se muestra "..." ...
user5260143
Pero también la versión jQuery agrega puntos si el texto es más corto: jsfiddle.net/o82opadm/35
markzzz
@markzzz: gracias por eso, no tengo idea de cómo me lo perdí :-) Lo revisé ahora, pero no es algo que usaría en producción sin un poco más de trabajo. Pero al menos se presenta la idea básica.
asimovwasright
1
Descubrí que la solución solo CSS parece funcionar bien, pero solo si usa solo mediciones de píxeles. Los EM y los porcentajes me metieron en problemas. Y agregué los puntos suspensivos como un <a> estilo de posición: absoluto en la parte inferior derecha para aquellos que quieran hacer clic en el enlace y leer más. En mi caso, sabía que el texto siempre se desbordaría, por lo que jQuery no era necesario. ¡Gracias por la útil solución CSS!
Mentalista
30

Por lo que puedo ver, esto sería posible solo usando height: (some em value); overflow: hiddene incluso entonces no tendría la fantasía ...al final.

Si esa no es una opción, creo que es imposible sin algún preprocesamiento del lado del servidor (difícil porque el flujo de texto es imposible de predecir de manera confiable) o jQuery (posible pero probablemente complicado).

Pekka 웃
fuente
16
Esto parece funcionar para cualquier tamaño de fuente .mytext {overflow: hidden; altura de línea: 1.2em; altura máxima: 2.4em; }
Peter
1
@Pedro sí. Es posible que pueda ejecutar cada uno .mytextutilizando jQuery, averiguar si tiene más contenido del que es visible y agregar uno ...manualmente. De esa manera, eres compatible con clientes sin JS, y los clientes con JS pueden tener la decoración. Quizás valga la pena una pregunta separada para que un jQuery Guru responda; podría ser posible hacerlo con relativa facilidad
Pekka,
15

La solución de este hilo es usar el plugin jquery dotdotdot . No es una solución CSS, pero le ofrece muchas opciones para enlaces "leer más", cambio de tamaño dinámico, etc.

Martin Andersson
fuente
10

La siguiente clase CSS me ayudó a obtener puntos suspensivos de dos líneas.

  .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;
    }
Mohammad Salman
fuente
5

Actualmente no puedes, pero en el futuro podrás usarlo text-overflow:ellipis-lastline. Actualmente está disponible con el prefijo de proveedor en Opera 10.60+: ejemplo

soñador_
fuente
55
Eso no funciona para cadenas multilínea, ya que también requiere establecer white-scace: nowrap. Ver aquí .
Sebastian Noack
4

Tengo una solución que funciona bien, pero en lugar de puntos suspensivos, usa un gradiente. Funciona cuando tiene texto dinámico, por lo que no sabe si será lo suficientemente largo como para necesitar una elipse. Las ventajas son que no tiene que hacer ningún cálculo de JavaScript y funciona para contenedores de ancho variable, incluidas las celdas de la tabla, y es un navegador cruzado. Utiliza un par de divs adicionales, pero es muy fácil de implementar.

Margen:

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

entrada en el blog: http://salzerdesign.com/blog/?p=453

página de ejemplo: http://salzerdesign.com/test/fade.html

Miriam Salzer
fuente
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;
}
Ali
fuente
0

Realmente me gusta el bloqueo de línea, pero aún no hay soporte para Firefox ... así que voy con un cálculo matemático y simplemente oculto el desbordamiento

.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*/
}

ahora digamos que desea eliminar y agregar esta clase a través de jQuery con un enlace, necesitará tener un píxel adicional para que la altura máxima sea de 63 px, esto se debe a que debe verificar cada vez si la altura es mayor que 62px, pero en el caso de 4 líneas obtendrá un falso verdadero, por lo que un píxel adicional lo solucionará y no creará ningún problema adicional

pegaré un coffeescript para esto solo para ser un ejemplo, usa un par de enlaces que están ocultos por defecto, con clases read-more y read-less, eliminará los que el desbordamiento no necesita y eliminará el cuerpo clases de desbordamiento

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()
Alexis
fuente
por cierto, no agregue una línea de abrazadera a esto, establecerá la altura a 62px (para este caso) y no tendrá la comprabation de jquery
Alexis
0

Si quieres enfocarte en cada letteruno, puedes hacer eso, me refiero a esta pregunta

Si quieres concentrarte en cada worduno, puedes hacerlo así + espacio

Si quieres enfocarte en cada worduno, puedes hacerlo así + sin espacio

revs Nisharg Shah
fuente
-1

Código de ejemplo básico, aprender a codificar es fácil. Verifique los comentarios de estilo CSS.

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>

KingRider
fuente
44
El OP está buscando una solución de líneas múltiples. Esto solo funciona en líneas de texto individuales.
asimovwasright
-11

He estado buscando esto, pero luego me doy cuenta de que mi sitio web usa php. ¿Por qué no utilizar la función de recorte en la entrada de texto y jugar con la longitud máxima ...

Aquí hay una posible solución también para aquellos que usan 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;
?>
Maxime
fuente
18
No puede utilizar de forma segura el procesamiento del lado del servidor porque no puede saber de antemano cuánto espacio ocupará el texto en la página. Depende del tamaño de fuente, la configuración del tamaño del texto del navegador, el nivel de zoom del navegador, etc.
ermannob