Ogranicz długość tekstu do n linii za pomocą CSS

515

Czy można ograniczyć długość tekstu do linii „n” za pomocą CSS (lub wyciąć go, gdy zostanie przepełniony w pionie).

text-overflow: ellipsis; działa tylko dla 1 wiersza tekstu.

oryginalny tekst:

Ultrices natoque mus mattis, aliquam, cras in 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

pożądany wynik (2 linie):

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

Peter
źródło
1
Tylko uwaga: wielokropek przepełnienia tekstu nie jest obsługiwany w przeglądarce Firefox, zobacz bugzilla.mozilla.org/show_bug.cgi?id=312156
Joril
8
wydaje się, że ktoś uciekł, robiąc to tylko z css mobify.com/dev/multiline-ellipsis-in-pure-css
Gaurav Shah
nie działa na IE10. Działa na 11
2060451
@GauravShah Dziękuję. Działa również na IE10. Większość rozwiązań tutaj nie jest obsługiwana w różnych przeglądarkach.
user2060451

Odpowiedzi:

654

Można to zrobić za pomocą nieoficjalnej składni zaciskania linii , a od Firefox 68 działa we wszystkich głównych przeglądarkach.

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>

O ile nie dbasz o użytkowników IE, nie musisz tego robić line-heighti mieć max-heightawarie.

Evgeny
źródło
3
na przykład, przy pewnym rozmiarze czcionki do wysokości linii, możesz zobaczyć część następnego wiersza również z wyrównaniem tekstu: uzasadnij, elipsa nie znajduje się na końcu ostatniego wiersza, ale nakłada się na tekst w miejscu, to byłoby, gdyby tekst był wyrównany do lewej
Matus
3
oto skrzypce: jsfiddle.net/csYjC/1122 podczas przygotowywania, dowiedziałem się, że część ostatniej linii jest widoczna tylko wtedy, gdy jest padding
Matus
Cóż, nikt nie powiedział, że ta niestandardowa czarna magia tylko dla webkitów będzie działała idealnie przez cały czas. Możesz użyć paddingu na innym pojemniku, być może nadrzędnym. Wripping text w tagu <p> ma sens: jsfiddle.net/csYjC/1129
Evgeny
2
Zauważ, że od tego komentarza -webkit-line-clamp nie respektuje widoczności: ukryty. Kosztowało mnie to kilka godzin debugowania. Oto pomocniczy raport o błędach: bugs.webkit.org/show_bug.cgi?id=45399 .
Kevin
3
Jeśli masz problemy z -webkit-box-orient: vertical;ukryciem się podczas kompilacji scss, spróbuj tego /* autoprefixer: ignore next */ -webkit-box-orient: vertical;
Salam
109

Co możesz zrobić, to:

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

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

Erik Aigner
źródło
13
Działa
Wydaje się też, że jest to najlepsze możliwe rozwiązanie dla mnie, ale jak zauważył @rishiAgar, nie kończy się na elipsie. Nadal działa jak klip.
David Carrigan
Wierzę, że będziesz musiał dodać atrybuty, display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;aby pojawiła się elipsa. Ale to będzie działać tylko w Chrome. Aby zapoznać się z rozwiązaniem działającym również w Firefoksie, spójrz tutaj: stackoverflow.com/a/20595073/1884158 A oto przydatny samouczek na ten temat: css-tricks.com/line-clampin
modulitos
34

Działające rozwiązanie dla różnych przeglądarek

Ten problem trapi nas wszystkich od lat.

Aby pomóc we wszystkich przypadkach, opracowałem podejście CSS i podejście jQuery na wypadek problemów z css.

Oto rozwiązanie CSS , które wymyśliłem, które działa w każdych okolicznościach, z kilkoma drobnymi zastrzeżeniami.

Podstawy są proste, ukrywa przepełnienie rozpiętości i ustawia maksymalną wysokość na podstawie wysokości linii, jak zasugerował Eugene Xa.

Potem jest pseudoklasa po div zawierającym, który ładnie umieszcza elipsę.

Ostrzeżenia

To rozwiązanie zawsze umieszcza wielokropek, niezależnie od tego, czy jest to potrzebne.

Jeśli ostatni wiersz kończy się końcowym zdaniem, skończysz z czterema kropkami ....

Musisz być zadowolony z uzasadnionego wyrównania tekstu.

Elipsa będzie po prawej stronie tekstu, który może wyglądać niechlujnie.

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

Podejście jQuery

Moim zdaniem jest to najlepsze rozwiązanie, ale nie każdy może korzystać z JS. Zasadniczo jQuery sprawdzi dowolny element .text, a jeśli będzie więcej znaków niż wstępnie ustawiony max var, odetnie resztę i doda elipsę.

Nie ma żadnych zastrzeżeń do tego podejścia, jednak ten przykład kodu ma jedynie na celu zademonstrowanie podstawowej idei - nie użyłbym tego w produkcji bez ulepszenia go z dwóch powodów:

1) Przepisze wewnętrzny html elementów .text. czy to potrzebne czy nie. 2) Nie sprawdza się, czy wewnętrzny html nie ma zagnieżdżonych elementów - więc w dużym stopniu polegasz na autorze, aby poprawnie używał .text.

Edytowane

Dzięki za złapanie @markzzz

Kod i fragment

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
źródło
3
Twoje rozwiązanie css nie jest tak dobre, bo co z przypadkiem, że tekst nie jest przepełniony? pokazuje także „...” ...
user5260143,
Ale także wersja jQuery dodaje kropki, jeśli tekst jest krótszy: jsfiddle.net/o82opadm/35
markzzz
@markzzz - dziękuję za to, nie mam pojęcia, jak mi tego brakowało :-) Poprawiłem go teraz, ale nie byłoby to coś, co wykorzystałbym w produkcji bez odrobiny pracy. Ale przedstawiona jest przynajmniej podstawowa idea.
asimovwasright
1
Odkryłem, że rozwiązanie tylko CSS wydaje się działać dobrze, ale tylko jeśli używasz tylko pomiarów pikseli. EM i procenty wpędziły mnie w kłopoty. I dodałem elipsę jako styl <a> do pozycji: absolut w prawym dolnym rogu dla tych, którzy chcą kliknąć link i przeczytać więcej. W moim przypadku wiedziałem, że tekst zawsze się przepełni, więc jQuery nie było konieczne. Dzięki za przydatne rozwiązanie CSS!
Mentalista
30

O ile widzę, byłoby to możliwe tylko przy użyciu, height: (some em value); overflow: hiddena nawet wtedy nie byłoby to fantazyjne ...na końcu.

Jeśli nie jest to opcja, myślę, że jest to niemożliwe bez wstępnego przetwarzania po stronie serwera (trudne, ponieważ przepływu tekstu nie można wiarygodnie przewidzieć) lub jQuery (możliwe, ale prawdopodobnie skomplikowane).

Pekka 웃
źródło
16
Wydaje się, że działa to dla dowolnego rozmiaru czcionki .mytext {overflow: hidden; wysokość linii: 1,2 em; maksymalna wysokość: 2,4 em; }
Peter
1
@Pedro tak. Możesz być w stanie uruchomić każdy .mytextz nich za pomocą jQuery, dowiedzieć się, czy ma więcej treści niż jest widoczne, i dodać ...ręcznie. W ten sposób jesteś kompatybilny z klientami bez JS, a klienci z JS mogą mieć dekorację. Może warto osobne pytanie dla guru jQuery; być może uda się to zrobić stosunkowo łatwo
Pekka
15

Rozwiązaniem tego wątku jest użycie wtyczki jquery dotdotdot . Nie jest to rozwiązanie CSS, ale daje wiele opcji linków „czytaj więcej”, dynamicznej zmiany rozmiaru itp.

Martin Andersson
źródło
10

następujące zajęcia CSS pomogły mi w uzyskaniu dwóch liniowych elips.

  .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
źródło
5

Obecnie nie możesz, ale w przyszłości będziesz mógł z niego korzystać text-overflow:ellipis-lastline. Obecnie jest dostępny z prefiksem dostawcy w Operze 10.60+: przykład

marzyciel_
źródło
5
To nie działa w przypadku ciągów wielowierszowych, ponieważ wymaga również ustawienia białych znaków: nowrap. Zobacz tutaj .
Sebastian Noack,
4

Mam rozwiązanie, które działa dobrze, ale zamiast elipsy używa gradientu. Działa, gdy masz dynamiczny tekst, więc nie wiesz, czy będzie on wystarczająco długi, aby potrzebować elipsy. Zaletą jest to, że nie trzeba wykonywać żadnych obliczeń JavaScript i działa to w przypadku kontenerów o zmiennej szerokości, w tym komórek tabeli, i działa w różnych przeglądarkach. Używa kilku dodatkowych div, ale jest bardzo łatwa do wdrożenia.

Narzut:

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

post na blogu: http://salzerdesign.com/blog/?p=453

przykładowa strona: http://salzerdesign.com/test/fade.html

Miriam Salzer
źródło
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
źródło
0

Naprawdę lubię line-clamp, ale nie mam jeszcze wsparcia dla firefoxa .. więc wybieram obliczenia matematyczne i po prostu ukrywam przepełnienie

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

powiedzmy teraz, że chcesz usunąć i dodać tę klasę za pomocą jQuery z linkiem, będziesz musiał mieć dodatkowy piksel, więc maksymalna wysokość będzie wynosić 63 piksele, ponieważ musisz za każdym razem sprawdzać, czy wysokość jest większa niż 62px, ale w przypadku 4 linii otrzymasz fałszywą prawdę, więc dodatkowy piksel to naprawi i nie spowoduje żadnych dodatkowych problemów

wkleję dla tego przykładowy skrypt coffeescript, używa kilku domyślnie ukrytych linków, z klasami więcej-do-odczytu i mniej-do-odczytu, usunie te, których przepełnienie nie jest potrzebne i usunie ciało klasy przelewu

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
źródło
tak przy okazji, nie dodawaj do tego cęgów, ustawi wysokość na 62px (w tym przypadku) i nie będziesz mieć obliczeń jquery
Alexis
0

Jeśli chcesz skupić się na każdym z nich, lettermożesz to zrobić, odsyłam do tego pytania

Jeśli chcesz skupić się na każdym z nich word, możesz zrobić w ten sposób + spację

Jeśli chcesz skupić się na każdym z nich, wordmożesz to zrobić + bez spacji

rev Nisharg Shah
źródło
-1

Podstawowy przykładowy kod, nauka kodowania jest łatwa. Sprawdź komentarze CSS stylu.

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
źródło
4
OP szuka rozwiązania wieloliniowego. Działa to tylko w przypadku pojedynczych wierszy tekstu.
asimovwasright
-11

Rozglądałem się za tym, ale potem zdaję sobie sprawę, cholera, moja witryna używa php !!! Dlaczego nie skorzystać z funkcji przycinania podczas wprowadzania tekstu i grać z maksymalną długością ....

Oto możliwe rozwiązanie również dla osób korzystających z 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
źródło
18
Nie można bezpiecznie korzystać z przetwarzania po stronie serwera, ponieważ nie można z góry wiedzieć, ile miejsca zajmie tekst na stronie. Zależy to od rozmiaru czcionki, ustawień rozmiaru tekstu przeglądarki, poziomu powiększenia przeglądarki itp.
ermannob