Limitar o comprimento do texto a n linhas usando CSS

515

É possível limitar um comprimento de texto a "n" linhas usando CSS (ou cortá-lo quando estourar verticalmente).

text-overflow: ellipsis; só funciona para texto de 1 linha.

texto original:

Ultrices natoque mus mattis, aliquá, cras em pelellita
tincidunt elit purus lectus, vel aliquet, elementum nunc
nunc rhoncus placerat urna! Sente-se! Ut penatibus turpis
mus tincidunt! Dapibus sed aenean, magna sagittis, lorem velit

saída desejada (2 linhas):

Ultrices natoque mus mattis, aliquá, cras em pelellita
tincidunt elit purus lectus, vel ut aliquet, elementum ...

Peter
fonte
1
Apenas uma observação: as reticências de transbordamento de texto não são suportadas no Firefox, consulte bugzilla.mozilla.org/show_bug.cgi?id=312156
Joril
8
Parece que alguém escapou por fazê-lo com apenas css mobify.com/dev/multiline-ellipsis-in-pure-css
Gaurav Shah
não funciona no IE10. Ele funciona em 11.
user2060451
@GauravShah Obrigado. Também funciona no IE10. A maioria das soluções aqui não é entre navegadores.
usar o seguinte comando

Respostas:

655

Existe uma maneira de fazer isso usando sintaxe não oficial de grampo de linha e , começando no Firefox 68, ele funciona em todos os principais 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 você se preocupe com os usuários do IE, não há necessidade de fazer line-heighte fazer max-heightfallbacks.

Evgeny
fonte
3
por exemplo, com determinado tamanho de fonte e altura da linha, é possível ver parte da próxima linha também com alinhamento de texto: justifique, as reticências não estão no final da última linha, mas sobrepõem o texto na posição; seria, se o texto foi alinhado à esquerda
Matus
3
aqui está o violino: jsfiddle.net/csYjC/1122 enquanto eu estava preparando-o, eu descobri, que parte da última linha é visível apenas quando há estofamento
Matus
Bem, ninguém disse que essa magia negra não-padrão, somente para webkit, funcionaria perfeitamente o tempo todo. Você pode usar o preenchimento em algum outro contêiner, talvez pai. Escrever texto na tag <p> faz todo o sentido: jsfiddle.net/csYjC/1129
Evgeny
2
Observe que, a partir deste comentário, -webkit-line-clamp não respeita a visibilidade: oculto. Isso me custou algumas horas de depuração. Aqui está um relatório de bug de suporte: bugs.webkit.org/show_bug.cgi?id=45399 .
21414 Kevin
3
Se você está tendo problemas com -webkit-box-orient: vertical;sendo escondido quando SCSS compilação tentar isso /* autoprefixer: ignore next */ -webkit-box-orient: vertical;
Salam
109

O que você pode fazer é o seguinte:

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

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

Erik Aigner
fonte
13
Está funcionando como texto-overflow: clip, como a sua não mostrando (...)
rishiAgar
Parece ser a melhor solução possível para mim também, mas como o @rishiAgar observou, não termina com reticências. Continua a funcionar como um clipe.
David Carrigan
Acredito que você precisará adicionar os atributos display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;para que as reticências apareçam. Mas isso só funcionará no Chrome. Para a solução que o trabalho no Firefox, bem como, veja aqui: stackoverflow.com/a/20595073/1884158 E aqui é um tutorial útil sobre o assunto: css-tricks.com/line-clampin
modulitos
34

Solução de trabalho entre navegadores

Esse problema vem nos atormentando há anos.

Para ajudar em todos os casos, eu expus a abordagem somente CSS, e uma abordagem jQuery, caso as advertências do css sejam um problema.

Aqui está uma solução que eu desenvolvi em CSS, que funciona em todas as circunstâncias, com algumas pequenas advertências.

O básico é simples, oculta o estouro da extensão e define a altura máxima com base na altura da linha, conforme sugerido por Eugene Xa.

Depois, há uma pseudo classe após a div que contém as reticências.

Ressalvas

Essa solução sempre colocará as reticências, independentemente da necessidade.

Se a última linha terminar com uma frase final, você terminará com quatro pontos ....

Você precisará ser feliz com o alinhamento de texto justificado.

As reticências estarão à direita do texto, que pode parecer desleixado.

Código + Snippet

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>

Abordagem jQuery

Na minha opinião, esta é a melhor solução, mas nem todos podem usar o JS. Basicamente, o jQuery verificará qualquer elemento .text e, se houver mais caracteres que o max predefinido, ele cortará o restante e adicionará reticências.

Não há advertências para essa abordagem, no entanto, este exemplo de código serve apenas para demonstrar a idéia básica - eu não usaria isso na produção sem aprimorá-la por duas razões:

1) Reescreverá o html interno dos elementos .text. se necessário ou não. 2) Não é necessário verificar se o html interno não possui elementos aninhados - portanto, você depende muito do autor para usar o .text corretamente.

Editado

Obrigado pela 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
fonte
3
Sua solução css não é tão boa, porque e se o texto não estiver excedente? também é show "..." ...
user5260143 26/12/16
Mas também a versão jQuery adiciona pontos se o texto é mais curto: jsfiddle.net/o82opadm/35
markzzz
@markzzz - obrigado por isso, não faço ideia de como eu perdi :-) Eu o revisei agora, mas não é algo que eu usaria na produção sem um pouco mais de trabalho. Mas pelo menos a idéia básica é apresentada.
Asimovwasright
1
Descobri que a solução somente CSS parece funcionar bem, mas somente se você usar apenas medidas de pixel. EMs e porcentagens me causaram problemas. E adicionei as reticências como um <a> estilizado para a posição: absoluto no canto inferior direito para quem deseja clicar no link e ler mais. No meu caso, eu sabia que o texto sempre transbordaria, portanto, o jQuery não era necessário. Obrigado pela útil solução CSS!
Mentalista,
30

Tanto quanto eu posso ver, isso seria possível apenas usando height: (some em value); overflow: hiddene, mesmo assim, não teria a fantasia ...no final.

Se isso não for uma opção, acho que é impossível sem algum pré-processamento no servidor (difícil porque o fluxo de texto é impossível de prever com segurança) ou jQuery (possível, mas provavelmente complicado).

Pekka 웃
fonte
16
Isso parece funcionar para qualquer tamanho de fonte .mytext {overflow: hidden; altura da linha: 1.2em; altura máxima: 2.4em; }
Peter
1
@Pedro yeah. Você pode percorrer cada um .mytextusando o jQuery, descobrir se ele possui mais conteúdo do que o visível e adicionar um ...manualmente. Dessa forma, você é compatível com clientes sem JS e os clientes com JS podem ter a decoração. Talvez valha uma pergunta separada para o jQuery Guru responder; pode ser possível fazer de forma relativamente fácil
Pekka
15

A solução desse segmento é usar o plug-in jquery dotdotdot . Não é uma solução CSS, mas oferece muitas opções para links "leia mais", redimensionamento dinâmico etc.

Martin Andersson
fonte
10

a seguinte aula CSS me ajudou a obter reticências em duas linhas.

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

Atualmente você não pode, mas no futuro poderá usá-lo text-overflow:ellipis-lastline. Atualmente, está disponível com o prefixo do fornecedor no Opera 10.60+: exemplo

sonhador_
fonte
5
Isso não funciona para cadeias de linhas múltiplas, pois requer também definir o espaço em branco: nowrap. Veja aqui .
Sebastian Noack
4

Eu tenho uma solução que funciona bem, mas em vez de uma elipse, ela usa um gradiente. Funciona quando você tem texto dinâmico, para não saber se será longo o suficiente para precisar de uma elipse. As vantagens são que você não precisa fazer nenhum cálculo de JavaScript e funciona para contêineres de largura variável, incluindo células da tabela e é cross-browser. Ele usa algumas divs extras, mas é muito fácil de implementar.

Marcação:

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

postagem no blog: http://salzerdesign.com/blog/?p=453

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

Miriam Salzer
fonte
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;
}
Todos
fonte
0

Eu realmente gosto de grampo de linha, mas ainda não há suporte para o firefox .. então eu vou com um cálculo matemático e apenas oculto o excesso

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

Agora, digamos que você deseja remover e adicionar esta classe via jQuery com um link, você precisará de um pixel extra para que a altura máxima seja de 63 px, isso ocorre porque você precisa verificar sempre se a altura é maior que 62px, mas no caso de 4 linhas, você receberá um falso verdadeiro, portanto, um pixel extra corrigirá isso e não criará problemas extras

vou colar um coffeescript para isso, apenas por exemplo, usa alguns links ocultos por padrão, com classes read-more e read-less, ele remove os que o excesso não precisa e remove o corpo classes -overflow

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
fonte
a propósito, não adicionar linha-braçadeira para isso, ele vai definir a altura para 62px (para este caso) e você não terá a comprabation jquery
Alexis
0

Se você quer se concentrar em cada um, letterpode fazer assim, refiro-me a esta pergunta

Se você quer se concentrar em cada um, wordpode fazer assim + espaço

Se você quer se concentrar em cada um, wordpode fazer assim + sem espaço

Nisharg Shah
fonte
-1

Exemplo de código básico: aprender a codificar é fácil. Verifique os comentários do 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
fonte
4
O OP está procurando uma solução de várias linhas. Isso funciona apenas em linhas de texto únicas.
Asimovwasright
-11

Eu estive procurando por isso, mas então percebo, caramba, meu site usa php !!! Por que não usar a função de recorte na entrada de texto e brincar com o comprimento máximo ....

Aqui está uma solução possível também para quem usa 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
fonte
18
Você não pode usar com segurança o processamento no servidor, porque não pode saber com antecedência quanto espaço o texto ocupará na página. Depende do tamanho da fonte, configurações de tamanho de texto do navegador, o nível de zoom do navegador, etc.
ermannob