Ограничить длину текста до n строк, используя CSS

516

Можно ли ограничить длину текста до «n» строк с помощью CSS (или обрезать ее при переполнении по вертикали).

text-overflow: ellipsis; работает только для 1 строки текста.

Оригинальный текст:

Ultrices natoque mus mattis, aliquam, авария в pellentesque tincidunt
elit purus lectus, vel ut aliquet, elementum nunc
nunc rhoncus placerat urna! Сиди есть сед! Ut penatibus turpis
mus tincidunt! Dapibus sed aenean, magna sagittis, лорем велит

желаемый вывод (2 строки):

Ultrices natoque mus mattis, aliquam, авария в pellentesque
tincidunt elit purus lectus, vel ut aliquet, elementum ...

Peter
источник
1
Просто к сведению: текст переполнения многоточие не поддерживается в Firefox, см bugzilla.mozilla.org/show_bug.cgi?id=312156
Joril
8
кажется, кто-то сбежал, сделав это только css mobify.com/dev/multiline-ellipsis-in-pure-css
Гаурав Шах
не работает на IE10. Работает 11.
user2060451
@GauravShah Спасибо. Он работает и на IE10. Большинство решений здесь не являются кросс-браузерными.
user2060451

Ответы:

656

Есть способ сделать это, используя неофициальный синтаксис захвата строк , и начиная с Firefox 68, он работает во всех основных браузерах.

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>

Если вы не заботитесь о пользователях IE, нет необходимости делать line-heightи max-heightзапасные варианты.

Евгений
источник
3
например, с определенным размером шрифта до высоты строки, вы можете увидеть часть следующей строки также с text-align: justify, многоточие не в конце последней строки, но перекрывает текст в позиции, это было бы, если бы текст был выровнен по левому краю
Matus
3
вот скрипка: jsfiddle.net/csYjC/1122, пока я готовил ее, я обнаружил, что часть последней строки видна только при заполнении
Матус
Ну, никто не сказал, что эта нестандартная черная магия, предназначенная только для веб-комплектов, будет работать идеально все время. Вы можете использовать padding в другом, возможно, родительском контейнере. Перенос текста в теге <p> имеет смысл: jsfiddle.net/csYjC/1129
Евгений
2
Обратите внимание, что на момент этого комментария -webkit-line-зажим не учитывает видимость: скрыто. Это стоило мне несколько часов отладки. Вот вспомогательный отчет об ошибках: bugs.webkit.org/show_bug.cgi?id=45399 .
Кевин
3
Если у вас возникли проблемы с -webkit-box-orient: vertical;скрытностью при компиляции scss, попробуйте это /* autoprefixer: ignore next */ -webkit-box-orient: vertical;
Salam
110

Что вы можете сделать, это следующее:

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

Erik Aigner
источник
13
Работает как переполнение текста: клип, так как он не отображается (...)
rishiAgar
Кажется, это лучшее из возможных решений и для меня, но, как заметил @rishiAgar, не заканчивается многоточием. Продолжает функционировать как клип.
Дэвид Кэрриган
Я полагаю, вам придется добавить атрибуты, display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;чтобы сделать многоточие. Но это будет работать только в Chrome. Для решения, которое также работает в Firefox, посмотрите здесь: stackoverflow.com/a/20595073/1884158 А вот полезное руководство по этому вопросу: css-tricks.com/line-clampin
modulitos
34

Рабочее кросс-браузерное решение

Эта проблема преследует нас всех в течение многих лет.

Чтобы помочь во всех случаях, я изложил подход, основанный только на CSS, и подход jQuery на случай, если cssats является проблемой.

Вот единственное CSS- решение, которое я придумала, которое работает при любых обстоятельствах, с небольшими оговорками.

Основы просты: он скрывает переполнение пролета и устанавливает максимальную высоту на основе высоты линии, как это предложил Евгений Ха.

Затем есть псевдокласс после содержащего элемента div, который красиво размещает многоточие.

Предостережения

Это решение всегда помещает многоточие, независимо от того, есть ли в этом необходимость.

Если последняя строка заканчивается конечным предложением, вы получите четыре точки ....

Вам нужно быть довольным обоснованным выравниванием текста.

Многоточие будет справа от текста, которое может выглядеть неряшливо.

Код + Фрагмент

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>

Подход jQuery

На мой взгляд, это лучшее решение, но не каждый может использовать JS. По сути, jQuery проверит любой элемент .text, и если число символов превышает заданное значение max var, оно обрежет все остальные и добавит многоточие.

В этом подходе нет предостережений, однако этот пример кода предназначен только для демонстрации основной идеи - я бы не стал использовать это в производстве, не улучшив его по двум причинам:

1) Он перепишет внутренний html .text elems. нужен ли или нет. 2) Не проверяется, что внутренний html не имеет вложенных элементов - поэтому вы очень полагаетесь на автора, чтобы правильно использовать .text.

Edited

Спасибо за улов @markzzz

Код и фрагмент

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
источник
3
Ваше решение CSS не так хорошо, потому что как насчет того, что текст не переполнен? это также шоу "..." ...
user5260143
Но также версия jQuery добавляет точки, если текст короче: jsfiddle.net/o82opadm/35
markzzz
@markzzz - спасибо за это, не знаю, как я пропустил это :-) Я пересмотрел это сейчас, но это не то, что я бы использовал в производстве без дополнительной работы. Но, по крайней мере, основная идея изложена.
Азимов был прав
1
Я обнаружил, что решение только для CSS, кажется, работает хорошо, но только если вы используете только пиксельные измерения. ЭМ и проценты доставили мне неприятности. И я добавил многоточие в виде <a> стиля для позиции: абсолютный в правом нижнем углу для тех, кто хочет нажать на ссылку и прочитать больше. В моем случае я знал, что текст всегда будет переполнен, поэтому jQuery не был необходим. Спасибо за полезное решение CSS!
Менталист
30

Насколько я вижу, это было бы возможно только при использовании, height: (some em value); overflow: hiddenи даже тогда это не имело бы смысла ...в конце.

Если это не вариант, я думаю, что это невозможно без некоторой предварительной обработки на стороне сервера (сложно, потому что поток текста невозможно предсказать надежно) или jQuery (возможно, но, вероятно, сложно).

оборота Пекка 웃
источник
16
Кажется, это работает для любого размера шрифта .mytext {overflow: hidden; высота линии: 1.2em; максимальная высота: 2,4em; }
Питер
1
@ Педро да. Возможно, вам удастся запустить каждое из них .mytextс помощью jQuery, выяснить, содержит ли оно больше контента, чем видно, и добавить его ...вручную. Таким образом, вы совместимы с клиентами без JS, и клиенты с JS могут иметь оформление. Возможно, стоит ответить на отдельный вопрос для гуру jQuery; может быть возможно сделать относительно легко
Пекка
15

Решение этой темы - использовать плагин jquery dotdotdot . Не CSS-решение, но оно дает вам множество опций для ссылок «читать дальше», динамического изменения размера и т. Д.

Мартин Андерссон
источник
10

Следующий класс CSS помог мне в получении двухстрочного многоточия.

  .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

В настоящее время вы не можете, но в будущем вы сможете использовать text-overflow:ellipis-lastline. В настоящее время он доступен с префиксом вендора в Opera 10.60+: пример

dreamer_
источник
5
Это не работает для многострочных строк, так как требует также установки white-scace: nowrap. Смотрите здесь .
Себастьян Ноак
4

У меня есть решение, которое работает хорошо, но вместо многоточия оно использует градиент. Это работает, когда у вас есть динамический текст, поэтому вы не знаете, будет ли он достаточно длинным, чтобы нуждаться в эллипсе. Преимущества в том, что вам не нужно выполнять какие-либо вычисления JavaScript, он работает для контейнеров переменной ширины, включая ячейки таблицы, и является кросс-браузерным. Он использует пару дополнительных элементов div, но его очень легко реализовать.

Разметка:

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

Сообщение блога: http://salzerdesign.com/blog/?p=453

пример страницы: http://salzerdesign.com/test/fade.html

Miriam Salzer
источник
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

Мне очень нравится line-зажим, но пока нет поддержки Firefox .. поэтому я иду с математическим кальком и просто скрываю переполнение

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

Теперь предположим, что вы хотите удалить и добавить этот класс через jQuery со ссылкой, вам понадобится дополнительный пиксель, чтобы максимальная высота составляла 63 пикселя, это потому, что вам нужно каждый раз проверять, если высота больше, чем 62px, но в случае 4 строк вы получите ложное значение true, поэтому дополнительный пиксель исправит это и не создаст никаких дополнительных проблем

я вставлю coffeescript для этого просто в качестве примера, использую пару ссылок, которые по умолчанию скрыты, с классами read-more и read-less, он удалит те, которые переполнению не нужны, и удалит тело классы переполнения

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()
Алексис
источник
кстати, не добавляйте к этому линейный зажим, он установит высоту в 62 пикселя (для этого случая), и у вас не будет компрабации jquery
Alexis
0

Если вы хотите сосредоточиться на каждом, что letterвы можете сделать так, я обращаюсь к этому вопросу

Если вы хотите сосредоточиться на каждом, wordвы можете сделать так + пробел

Если вы хотите сосредоточиться на каждом из них, wordвы можете сделать это + без пробела

оборота Нишарг Шах
источник
-1

Базовый пример кода, научиться писать легко. Проверьте стиль 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
источник
4
ОП ищет многоканальное решение. Это работает только для отдельных строк текста.
Азимов был прав
-11

Я искал вокруг этого, но потом я понимаю, черт возьми, мой сайт использует php! Почему бы не использовать функцию обрезки при вводе текста и играть с максимальной длиной ....

Вот возможное решение для тех, кто использует 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
источник
18
Вы не можете безопасно использовать обработку на стороне сервера, потому что не можете заранее знать, сколько места займет текст на странице. Это зависит от размера шрифта, настроек размера текста в браузере, уровня масштабирования браузера и т. Д.
ermannob