Способы обрезания многострочного текста по высоте
HTML&CSS

Способы обрезания многострочного текста по высоте

Допустим у нас есть текст произвольной длины, который должен выводиться внутри блока фиксированной высоты и ширины. Мы хотим, чтобы отображался такой фрагмент текста, который полностью помещается в заданный блок, и многоточие, если текст помещается не полностью. Это довольно распространенная задача, пример подобных блоков показан на рисунке ниже.

Пример обрезания многострочного текста по высоте

В то же время эта задача не является такой тривиальной, как кажется. Давайте рассмотрим возможные варианты ее решения.

Решение на CSS для однострочного текста

Для однострочного текста есть красивое и простое решение на CSS. В этом случае можно использовать свойство text-overflow: ellipsis . При этом контейнер должен иметь свойство overflow равное hidden или clip. Пример:


.box {
    width: 250px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

Решения на CSS для многострочного текста

Один из способов обрезки многострочного текста на CSS использует псевдо-элементы :before и :after.

HTML:


<div class="box">
    <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>

CSS:


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

Другое решение на CSS использует свойство column-width . Оно задает ширину колонки для многостраничного текста. Вы уже, наверное, догадались, как мы будем его использовать? Правильно, мы зададим ширину колонки, равную ширине блока, а текст, который не помещается в блок, будет во второй, скрытой колонке:

HTML:


<div class="box">
    <div class="box__in">
        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:


.box {
    overflow: hidden;
    height: 200px;
    width: 300px;
}

.box__in {
    -webkit-column-width: 150px;
    -moz-column-width: 150px;
    column-width: 150px;
    height: 100%;
}

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

Интересное решение для многострочного текста на CSS есть для браузеров Webkit. Для этого нужно использовать сразу несколько специфичных свойств с префиксом -webkit:


.box {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

Свойство -webkit-line-clamp ограничивает количество строк, выводимых в блоке. Работает красиво и элегантно, но из-за своей специфичности в реальном проекте, конечно, такой прием не может использоваться.

Решения на JavaScript

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


var box = document.querySelector('.box'),
    text = box.innerHTML,
    clone = document.createElement('div');

clone.style.position = 'absolute';
clone.style.visibility = 'hidden';
clone.style.width = box.clientWidth + 'px';
clone.innerHTML = text;
document.body.appendChild(clone);

var l = text.length - 1;
for (; l >= 0 && clone.clientHeight > box.clientHeight; --l) {
    clone.innerHTML = text.substring(0, l) + '...';
}

box.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));

Теперь вызов функции обрезки текста сведется к вызову метода truncateText:


$(function() {
    $('.box').truncateText();
});

Что касается решений на JavaScript, нужно помнить, что операции с DOM’ом: вставка элемента, удаление, изменение его содержимого — являются очень тяжелыми. Поэтому с такими хаками нельзя усердствовать.

Заключение

Мы привели несколько решений для обрезания произвольного текста как на CSS, так и на JavaScript. Если поддержка браузеров позволяет, лучше выбрать решение на CSS — оно будет быстрее, стабильнее, меньше. Если нет — можно использовать JavaScript, но важно помнить о производительности и применять функцию обрезки текста только действительно в нужных местах.

Рассылка
Подпишитесь на рассылку и получайте дайджест новостей и статей.
Никакого спама!
Подписаться