Есть текст произвольной длины, который нужно вывести внутри блока фиксированной высоты и ширины. При этом, если текст помещается не полностью, отображаться должен фрагмент текста, который полностью помещается в заданный блок, после чего устанавливается многоточие.
Такая задача является довольно распространенной, в то же время она есть не такой тривиальной, как кажется.
Вариант для однострочного текста на CSS
В этом случае можно использовать свойство text-overflow: ellipsis
. При этом контейнер должен иметь свойство overflow равное hidden или clip
.block {
width: 250px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Вариант для многострочного текста на CSS
Первый способ обрезать многострочный текст с использованием CSS свойств применить псевдо-элементы :before и :after. Для начала HTML-разметка
<div class="block">
<div>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p>
</div>
</div>
А теперь и сами свойства
.box {
overflow: hidden;
height: 200px;
width: 300px;
line-height: 25px;
}
.box:before {
content: "";
float: left;
width: 5px;
height: 200px;
}
.box > *:first-child {
float: right;
width: 100%;
margin-left: -5px;
}
.box:after {
content: "\02026";
box-sizing: content-box;
float: right;
position: relative;
top: -25px;
left: 100%;
width: 3em;
margin-left: -3em;
padding-right: 5px;
text-align: right;
background-size: 100% 100%;
background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
}
Еще один способ - использовать свойство column-width
с помощью которого задаем ширину колонки для многострочного текста. Правда, при использовании этого способа установить в конце многоточие неполучится.
HTML:
<div class="block">
<div class="block__inner">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
</div>
</div>
CSS:
.block {
overflow: hidden;
height: 200px;
width: 300px;
}
.block__inner {
-webkit-column-width: 150px;
-moz-column-width: 150px;
column-width: 150px;
height: 100%;
}
Третий способ решение для многострочного текста на CSS есть для браузеров Webkit. В нем нам прийдется использовать сразу несколько специфичных свойств с префиксом -webkit. Основным является -webkit-line-clamp
которое позволяет указать количество выводимых в блоке строк. Решение красивое но довольно ограниченное за счет своей работы в ограниченной группе браузеров
.block {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
Вариант для многострочного текста на JavaScript
Тут используется дополнительный невидимый блок, в который изначально помещается наш текст, после чего , удаляется по одному символу, пока высота этого блока не станет меньше либо равной высоте нужного блока. И в конце текст перемещается в исходный блок.
var block = document.querySelector('.block'),
text = block.innerHTML,
clone = document.createElement('div');
clone.style.position = 'absolute';
clone.style.visibility = 'hidden';
clone.style.width = block.clientWidth + 'px';
clone.innerHTML = text;
document.body.appendChild(clone);
var l = text.length - 1;
for (; l >= 0 && clone.clientHeight > block.clientHeight; --l) {
clone.innerHTML = text.substring(0, l) + '...';
}
block.innerHTML = clone.innerHTML;
Это же в виде плагина для jQuery:
(function($) {
var truncate = function(el) {
var text = el.text(),
height = el.height(),
clone = el.clone();
clone.css({
position: 'absolute',
visibility: 'hidden',
height: 'auto'
});
el.after(clone);
var l = text.length - 1;
for (; l >= 0 && clone.height() > height; --l) {
clone.text(text.substring(0, l) + '...');
}
el.text(clone.text());
clone.remove();
};
$.fn.truncateText = function() {
return this.each(function () {
truncate($(this));
});
};
}(jQuery));
Вызов:
$(function() {
$('.block').truncateText();
});
Как итог - желательно для обрезания произвольного текста использовать решения на CSS, поскольку они и быстрее, и стабильнее. Что касается решений на JavaScript, нужно помнить, что операции с DOM’ом: вставка элемента, удаление, изменение его содержимого — являются очень тяжелыми. Поэтому с такими хаками нельзя усердствовать.