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

с

overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

"..." будет отображаться в конце строки, если она переполнена. Однако это будет показано только в одной строке. Но я бы хотел, чтобы он отображался в нескольких строках.

Он может выглядеть так:

+--------------------+
|abcde feg hij   dkjd|
|dsji jdia js ajid  s|
|jdis ajid dheu d ...|/*Here it overflowed, so "..." is shown. */
+--------------------+

Ответ 1

Есть также несколько плагинов jquery, которые занимаются этой проблемой, но многие из них не обрабатывают несколько строк текста. Следующие работы:

Там также есть некоторые тесты предварительной обработки.

Ответ 2

Я взломал, пока мне не удалось добиться чего-то близкого к этому. Он содержит несколько предостережений:

  • Это не чистый CSS; вам нужно добавить несколько элементов HTML. Тем не менее, не требуется JavaScript.
  • Эллипсис выравнивается по правому краю на последней строке. Это означает, что если ваш текст не выровнен по правому краю или не оправдан, может быть заметный разрыв между последним видимым словом и многоточием (в зависимости от длины первого скрытого слова).
  • Пространство для многоточия всегда зарезервировано. Это означает, что если текст вставляется в поле почти точно, он может быть излишне усечен (последнее слово скрыто, хотя технически это не обязательно).
  • Ваш текст должен иметь фиксированный цвет фона, поскольку мы используем цветные прямоугольники, чтобы скрыть многоточие в тех случаях, когда это не нужно.

Следует также отметить, что текст будет разбит на границе слова, а не на границе символа. Это было преднамеренно (поскольку я считаю, что лучше для более длинных текстов), но поскольку он отличается от того, что делает text-overflow: ellipsis, я думал, что должен упомянуть об этом.

Если вы можете жить с этими оговорками, HTML выглядит так:

<div class="ellipsify">
    <div class="pre-dots"></div>
    <div class="dots">&hellip;</div>
    <!-- your text here -->
    <span class="hidedots1"></span>
    <div class="hidedots2"></div>
</div>

И это соответствующий CSS, используя пример окна шириной 150 пикселей с тремя строками текста на белом фоне. Предполагается, что у вас есть CSS reset или аналогичный, который при необходимости устанавливает поля и paddings.

/* the wrapper */
.ellipsify {
    font-size:12px;
    line-height:18px;
    height: 54px;       /* 3x line height */
    width: 150px;
    overflow: hidden;
    position: relative; /* so we're a positioning parent for the dot hiders */
    background: white;
}

/* Used to push down .dots. Can't use absolute positioning, since that
   would stop the floating. Can't use relative positioning, since that
   would cause floating in the wrong (namely: original) place. Can't 
   change height of #dots, since it would have the full width, and
   thus cause early wrapping on all lines. */
.pre-dots {
    float: right;
    height: 36px;  /* 2x line height (one less than visible lines) */
}

.dots {
    float: right; /* to make the text wrap around the dots */
    clear: right; /* to push us below (not next to) .pre-dots */
}

/* hides the dots if the text has *exactly* 3 lines */
.hidedots1 {
    background: white;
    width: 150px;
    height: 18px;       /* line height */
    position: absolute; /* otherwise, because of the width, it'll be wrapped */
}

/* hides the dots if the text has *less than* 3 lines */
.hidedots2 {
    background: white; 
    width: 150px;
    height: 54px;       /* 3x line height, to ensure hiding even if empty */
    position: absolute; /* ensures we're above the dots */
}

Результат выглядит следующим образом:

image of the rendered result with different text lengths

Чтобы прояснить, как это работает, здесь одно и то же изображение, за исключением того, что .hidedots1 подсвечивается красным цветом, а .hidedots2 - синим. Это прямоугольники, которые скрывают многоточие, когда нет невидимого текста:

the same image as above, except that the helper elements are highlighted in color

Протестировано в IE9, IE8 (эмуляция), Chrome, Firefox, Safari и Opera. Не работает в IE7.

Ответ 3

Вот недавняя статья css-tricks article, в которой говорится об этом.

Некоторые из решений в этой статье (которые здесь не упоминаются)

1) -webkit-line-clamp и 2) Поместите абсолютно позиционированный элемент в нижнее правое с выцветанием

Оба метода предполагают следующую разметку:

<div class="module"> /* Add line-clamp/fade class here*/
  <p>Text here</p>
</div>

с css

.module {
  width: 250px;
  overflow: hidden;
}

1) -webkit-line-clamp

строка-зажим FIDDLE (.. для максимум 3 строк)

.line-clamp {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;  
  max-height: 3.6em; /* I needed this to get it to work */
}

2) исчезают

Предположим, вы установили высоту линии в 1.2em. Если мы хотим разоблачить три строки текста, мы можем просто сделать высоту контейнера 3.6em (1.2em × 3). Скрытое переполнение скроет остальное.

Fade out FIDDLE

p
{
    margin:0;padding:0;
}
.module {
  width: 250px;
  overflow: hidden;
  border: 1px solid green;
  margin: 10px;
}

.fade {
  position: relative;
  height: 3.6em; /* exactly three lines */
}
.fade:after {
  content: "";
  text-align: right;
  position: absolute;
  bottom: 0;
  right: 0;
  width: 70%;
  height: 1.2em;
  background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%);
}

Решение № 3 - комбинация с использованием @поддерживает

Мы можем использовать @supports для применения webkit line-clamp в браузерах webkit и применять постепенное исчезновение в других браузерах.

@поддерживает линейный зажим с скрытой скрипкой fade

<div class="module line-clamp">
  <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
</div>

CSS

.module {
  width: 250px;
  overflow: hidden;
  border: 1px solid green;
  margin: 10px;
}

.line-clamp {
      position: relative;
      height: 3.6em; /* exactly three lines */
    }
.line-clamp:after {
      content: "";
      text-align: right;
      position: absolute;
      bottom: 0;
      right: 0;
      width: 70%;
      height: 1.2em;
      background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%);
 }

@supports (-webkit-line-clamp: 3) {
    .line-clamp {
        display: -webkit-box;
        -webkit-line-clamp: 3;
        -webkit-box-orient: vertical;  
        max-height:3.6em; /* I needed this to get it to work */
        height: auto;
    }
    .line-clamp:after {
        display: none;
    }
}

Ответ 4

В приведенной ниже ссылке представлено чистое решение HTML/CSS для этой проблемы.

Поддержка браузера - как указано в статье:

До сих пор мы тестировали Safari 5.0, IE 9 (должны быть в стандартном режиме), Opera 12 и Firefox 15.

Старые браузеры по-прежнему будут работать достаточно хорошо, так как мясо макета находится в нормальном положении, маржи и свойства заполнения. если ваш платформа старше (например, Firefox 3.6, IE 8), вы можете использовать этот метод, но переделать градиент как отдельное изображение PNG или фильтр DirectX.

http://www.mobify.com/dev/multiline-ellipsis-in-pure-css

css:

p { margin: 0; padding: 0; font-family: sans-serif;}

.ellipsis {
    overflow: hidden;
    height: 200px;
    line-height: 25px;
    margin: 20px;
    border: 5px solid #AAA; }

.ellipsis:before {
    content:"";
    float: left;
    width: 5px; height: 200px; }

.ellipsis > *:first-child {
    float: right;
    width: 100%;
    margin-left: -5px; }        

.ellipsis:after {
    content: "\02026";  

    box-sizing: content-box;
    -webkit-box-sizing: content-box;
    -moz-box-sizing: content-box;

    float: right; position: relative;
    top: -25px; left: 100%; 
    width: 3em; margin-left: -3em;
    padding-right: 5px;

    text-align: right;

    background: -webkit-gradient(linear, left top, right top,
        from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white));
    background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);           
    background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
    background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
    background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); }

html:

<div class="ellipsis">
    <div>
        <p>Call me Ishmael.  Some years ago &ndash; never mind how long precisely &ndash; having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world.  It is a way I have of driving off the spleen, and regulating the circulation.  Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people hats off &ndash; then, I account it high time to get to sea as soon as I can.</p>  
    </div>
</div>

fiddle

(изменить размер окна браузера для тестирования)

Ответ 5

После просмотра спецификации W3 для переполнения текста, я не думаю, что это возможно, используя только CSS. Ellipsis является свойством new-ish, поэтому он, вероятно, пока не получил много использования или обратной связи.

Однако этот парень, похоже, задал аналогичный (или идентичный) вопрос, и кто-то смог придумать хорошее решение jQuery. Вы можете демо-версию решения здесь: http://jsfiddle.net/MPkSF/

Если javascript не является вариантом, я думаю, вам может быть не повезло...

Ответ 6

Просто хочу добавить к этому вопросу ради полноты.

  • Opera имеет нестандартную поддержку для этого - o-эллипсис-lastline.
  • dotdotdot - отличный плагин jQuery, который я могу порекомендовать.

Ответ 7

Отличный вопрос... Я хочу, чтобы был ответ, но это самое близкое, которое вы можете получить с помощью CSS в наши дни. Отсутствие эллипса, но все еще довольно полезное.

overflow: hidden;
line-height: 1.2em;
height: 3.6em;      // 3 lines * line-height

Ответ 8

Вот самое близкое решение, которое я мог бы использовать только css.

HTML

<div class="ellipsis"> <span>...</span>
Hello this is Mr_Green from Stackoverflow. I love CSS. I live in CSS and I will never leave working on CSS even my work is on other technologies.</div>

CSS

div {
    height: 3em;
    line-height: 1.5em;
    width: 80%;
    border: 1px solid green;
    overflow: hidden;
    position: relative;
}
div:after {
    content:". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  . . . . . . . . . . . . . . . . . . . . . . . . . . . .";
    background-color: white;
    color: white;
    display: inline;
    position: relative;
    box-shadow: 8px 1px 1px white;
    z-index: 1;
}
span {
    position: absolute;
    bottom: 0px;
    right: 0px;
    background-color: white;
}

Working Fiddle (изменить размер окна для проверки)

Ссылка на мой блог для объяснения

Обновлено Fiddle

Надеюсь, теперь у какого-то эксперта по CSS будет идея о том, как сделать его идеальным.:)

Ответ 9

Я нашел это css (scss) решение, которое работает достаточно хорошо. В браузерах webkit он показывает многоточие, а в других браузерах он просто обрезает текст. Это нормально для моего предполагаемого использования.

$font-size: 26px;
$line-height: 1.4;
$lines-to-show: 3;

h2 {
  display: block; /* Fallback for non-webkit */
  display: -webkit-box;
  max-width: 400px;
  height: $font-size*$line-height*$lines-to-show; /* Fallback for non-webkit */
  margin: 0 auto;
  font-size: $font-size;
  line-height: $line-height;
  -webkit-line-clamp: $lines-to-show;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

Пример создателем: http://codepen.io/martinwolf/pen/qlFdp

Ответ 10

В вашем случае должно быть эффективно и достаточно следующее.

  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;

Ответ 11

Бит поздно для этой вечеринки, но я придумал, что я думаю, это уникальное решение. Вместо того, чтобы пытаться вставить свой собственный эллипсис с помощью CSS-обмана или js, я подумал, что попытаюсь свернуть только с одной строкой. Поэтому я дублирую текст для каждой "строки" и просто использую отрицательный текст-отступ, чтобы убедиться, что одна строка начинается с последней остановки. FIDDLE

CSS

#wrapper{
    font-size: 20pt;
    line-height: 22pt;
    width: 100%;
    overflow: hidden;
    padding: 0;
    margin: 0;
}

.text-block-line{
    height: 22pt;
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    white-space: nowrap;
    width: auto;
}
.text-block-line:last-child{
    text-overflow: ellipsis;
}

/*the follwing is suboptimal but neccesary I think. I'd probably just make a sass mixin that I can feed a max number of lines to and have them avialable. Number of lines will need to be controlled by server or client template which is no worse than doing a character count clip server side now. */
.line2{
    text-indent: -100%;
}
.line3{
    text-indent: -200%;
}
.line4{
    text-indent: -300%;
}

HTML:

<p id="wrapper" class="redraw">
    <span class="text-block-line line1">This text is repeated for every line that you want to be displayed in your element. This example has a max of 4 lines before the ellipsis occurs. Try scaling the preview window width to see the effect.</span>
    <span class="text-block-line line2">This text is repeated for every line that you want to be displayed in your element. This example has a max of 4 lines before the ellipsis occurs. Try scaling the preview window width to see the effect.</span>
    <span class="text-block-line line3">This text is repeated for every line that you want to be displayed in your element. This example has a max of 4 lines before the ellipsis occurs. Try scaling the preview window width to see the effect.</span>
    <span class="text-block-line line4">This text is repeated for every line that you want to be displayed in your element. This example has a max of 4 lines before the ellipsis occurs. Try scaling the preview window width to see the effect.</span>
</p>

Подробнее в скрипке. Существует проблема с перепланировкой браузера, в которой я использую перерисовку JS, и поэтому так проверяйте ее, но это основная концепция. Любые мысли/предложения очень ценятся.

Ответ 12

спасибо @balpha и @Kevin, я совмещаю два метода вместе.

нет необходимости в этом методе.

вы можете использовать background-image и градиент, необходимый для скрытия точек.

the innerHTML of .ellipsis-placeholder не требуется, я использую .ellipsis-placeholder, чтобы поддерживать ту же ширину и высоту с помощью .ellipsis-more. Вместо этого вы можете использовать display: inline-block.

.ellipsis {
    overflow: hidden;
    position: relative;
}
.ellipsis-more-top {/*push down .ellipsis-more*/
    content: "";
    float: left;
    width: 5px;
}
.ellipsis-text-container {
    float: right;
    width: 100%;
    margin-left: -5px;
}
.ellipsis-more-container {
    float: right;
    position: relative;
    left: 100%;
    width: 5px;
    margin-left: -5px;
    border-right: solid 5px transparent;
    white-space: nowrap;
}
.ellipsis-placeholder {/*keep text around ,keep it transparent ,keep same width and height as .ellipsis-more*/
    float: right;
    clear: right;
    color: transparent;
}
.ellipsis-placeholder-top {/*push down .ellipsis-placeholder*/
    float: right;
    width: 0;
}
.ellipsis-more {/*ellipsis things here*/
    float: right;
}
.ellipsis-height {/*the total height*/
    height: 3.6em;
}
.ellipsis-line-height {/*the line-height*/
    line-height: 1.2;
}
.ellipsis-margin-top {/*one line height*/
    margin-top: -1.2em;
}
.ellipsis-text {
    word-break: break-all;
}
<div class="ellipsis ellipsis-height ellipsis-line-height">
    <div class="ellipsis-more-top ellipsis-height"></div>
    <div class="ellipsis-text-container">
        <div class="ellipsis-placeholder-top ellipsis-height ellipsis-margin-top"></div>
        <div class="ellipsis-placeholder">
           <span>...</span><span>more</span>
        </div>
        <span class="ellipsis-text">text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text </span>
    </div>
    <div class="ellipsis-more-container ellipsis-margin-top">
        <div class="ellipsis-more">
            <span>...</span><span>more</span>
        </div>
    </div>
</div>

Ответ 13

Здесь много ответов, но мне нужен был тот, который был:

  • Только CSS
  • Будущее (становится более совместимым со временем)
  • Не сломать слова друг от друга (только разрывы на пробелах)

Предостережение заключается в том, что он не обеспечивает многоточие для браузеров, которые не поддерживают правило -webkit-line-clamp (в настоящее время IE, Edge, Firefox), но оно использует градиент для вытеснения их текста.

.clampMe {
  position: relative;
  height: 2.4em; 
  overflow: hidden;
}

.clampMe:after {
  content: "";
  text-align: right;
  position: absolute;
  bottom: 0;
  right: 0;
  width: 50%;
  height: 1.2em; /* Just use multiples of the line-height */
  background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 80%);
}

/* Now add in code for the browsers that support -webkit-line-clamp and overwrite the non-supportive stuff */
@supports (-webkit-line-clamp: 2) {
  .clampMe {
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
  }
  
  .clampMe:after {
    display: none;
  }
}
<p class="clampMe">There a lot more text in here than what you'll ever see. Pellentesque habitant testalotish morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>

Ответ 14

Решение javascript будет лучше

  • получить количество строк текста
  • переключить is-ellipsis класс, если изменить размер окна или изменить элит.

getRowRects

Element.getClientRects() работает как this

введите описание изображения здесь

каждый прямоугольник в той же строке имеет то же значение top, поэтому выясните прямоугольники с различным значением top, например this

введите описание изображения здесь

function getRowRects(element) {
    var rects = [],
        clientRects = element.getClientRects(),
        len = clientRects.length,
        clientRect, top, rectsLen, rect, i;

    for(i=0; i<len; i++) {
        has = false;
        rectsLen = rects.length;
        clientRect = clientRects[i];
        top = clientRect.top;
        while(rectsLen--) {
            rect = rects[rectsLen];
            if (rect.top == top) {
                has = true;
                break;
            }
        }
        if(has) {
            rect.right = rect.right > clientRect.right ? rect.right : clientRect.right;
            rect.width = rect.right - rect.left;
        }
        else {
            rects.push({
                top: clientRect.top,
                right: clientRect.right,
                bottom: clientRect.bottom,
                left: clientRect.left,
                width: clientRect.width,
                height: clientRect.height
            });
        }
    }
    return rects;
}

float ...more

как this

введите описание изображения здесь

изменить размер окна или изменить элемент

как this

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

Ответ 16

базовая база чистого css на -webkit-line-clamp:

@-webkit-keyframes ellipsis {/*for test*/
    0% { width: 622px }
    50% { width: 311px }
    100% { width: 622px }
}
.ellipsis {
    max-height: 40px;/* h*n */
    overflow: hidden;
    background: #eee;

    -webkit-animation: ellipsis ease 5s infinite;/*for test*/
    /**
    overflow: visible;
    /**/
}
.ellipsis .content {
    position: relative;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-box-pack: center;
    font-size: 50px;/* w */
    line-height: 20px;/* line-height h */
    color: transparent;
    -webkit-line-clamp: 2;/* max row number n */
    vertical-align: top;
}
.ellipsis .text {
    display: inline;
    vertical-align: top;
    font-size: 14px;
    color: #000;
}
.ellipsis .overlay {
    position: absolute;
    top: 0;
    left: 50%;
    width: 100%;
    height: 100%;
    overflow: hidden;

    /**
    overflow: visible;
    left: 0;
    background: rgba(0,0,0,.5);
    /**/
}
.ellipsis .overlay:before {
    content: "";
    display: block;
    float: left;
    width: 50%;
    height: 100%;

    /**
    background: lightgreen;
    /**/
}
.ellipsis .placeholder {
    float: left;
    width: 50%;
    height: 40px;/* h*n */

    /**
    background: lightblue;
    /**/
}
.ellipsis .more {
    position: relative;
    top: -20px;/* -h */
    left: -50px;/* -w */
    float: left;
    color: #000;
    width: 50px;/* width of the .more w */
    height: 20px;/* h */
    font-size: 14px;

    /**
    top: 0;
    left: 0;
    background: orange;
    /**/
}
<div class='ellipsis'>
    <div class='content'>
        <div class='text'>text text text text text text text text text text text text text text text text text text text text text </div>
        <div class='overlay'>
            <div class='placeholder'></div>
            <div class='more'>...more</div>
        </div>
    </div>
</div>

Ответ 17

Я ответил на это очень подробно с помощью простого решения CSS. Работает надежно. Как упомянуто в этом ответе, этого гораздо легче достичь с помощью Javascript, но если это не обсуждается, это работает.

Ответ 18

Я нашел трюк javascript, но вы должны использовать длину строки. Допустим, вы хотите 3 строки ширины 250 пикселей, вы можете рассчитать длину на строку i.e.

//get the total character length.
//Haha this might vary if you have a text with lots of "i" vs "w"
var totalLength = (width / yourFontSize) * yourNumberOfLines

//then ellipsify
function shorten(text, totalLength) {
    var ret = text;
    if (ret.length > totalLength) {
        ret = ret.substr(0, totalLength-3) + "...";
    }
    return ret;
}