Как реализовать троеточие при большом размере текста в нескольких блоках
У меня есть множество карточек, в каждом из них должно быть описание, но оно не должно быть больше 3 строчек, иначе выглядит не очень, а описание набирает пользователь (уменьшить описание - не вариант), какие бы я решения не находил - все они работают с 1 блоком, а у меня множество блоков с одинаковым классом, дак ещё и динамически блоки будут добавляться.

вот картинка блоков (блок описания(стрелочки)), а также это решение должно быть кроссбраузерным
Ответы (5 шт):
Как вариант:
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
Но работает только в webkit браузерах. Если кроссбраузерно, то только через JS.
Вариант при помощи CSS
Ограничивает текст заданным числом строк. Если текст превышает указанное число строк, то текст обрезается и в конце добавляется многоточие.
Пример:
body {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}
.card-des {
display: block;
min-width: 150px;
width: calc((100% - 15px) / 3);
background: gray;
padding: .5em;
box-sizing: border-box;
/* Что нужно добавить */
display: -webkit-box;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
.card-des:not(:last-child) {
margin-right: 5px;
}
<div class="card-des">Травка зеленеет,<br>
Солнышко блестит;<br>
Ласточка с весною<br>
В сени к нам летит.<br>
С нею солнце краше<br>
И весна милей…<br>
Прощебечь с дороги<br>
Нам привет скорей!<br>
Дам тебе я зерен,<br>
А ты песню спой,<br>
Что из стран далеких<br>
Принесла с собой…</div>
<div class="card-des">Короткий текст</div>
<div class="card-des">Ну длинный текст. Без отступов, в отличие от стиха. Ну или дажекогдатупомногобукавводномслове, ы</div>
Перед тем как добавить текст на страницу
Перед тем как вывести ограничить текст по длине, если текст более An символов, то ограничить его до Bn символов
Допустим вариант на JS
let card = [
{des: `Травка зеленеет,<br>Солнышко блестит;<br>Ласточка с весною<br>В сени к нам летит.<br>С нею солнце краше<br>И весна милей…<br>Прощебечь с дороги<br>Нам привет скорей!<br>Дам тебе я зерен,<br>А ты песню спой,<br>Что из стран далеких<br>Принесла с собой…`},
{des: `Короткий текст`},
{des: `Ну длинный текст. Без отступов, в отличие от стиха. Ну или дажекогдатупомногобукавводномслове, ы`}
],
maxLength = 100; // Максимум 100 слов.
card.forEach(function(e,i) {
let des = e.des;
des = des.length >= maxLength-3 ? des.slice(0, maxLength-3)+'...' : des;
document.body.innerHTML += `<div class="card-des">${des}</div>`;
});
body {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}
.card-des {
display: block;
min-width: 150px;
width: calc((100% - 15px) / 3);
background: gray;
padding: .5em;
box-sizing: border-box;
/* Что нужно добавить */
word-break: break-word;
}
.card-des:not(:last-child) {
margin-right: 5px;
}
Для IE11 работать будет, ниже не знаю:
// Подсчет высоты символа
const charTop = (node) => {
// FIXME для IE_11 это будет document.createRange()
const r = new Range()
return (s, e) => {
r.setStart(node, s)
r.setEnd(node, e)
return r.getBoundingClientRect().top
}
}
// Обрезка простого блока с "нормальным" текстовым Node #text
function lineClamp(element, lines) {
const top = charTop(element.firstChild)
const length = element.firstChild.data.length
// Стартовый top строки
let sTop = top(0, 1)
// Проходим по строкам
let i = 1
for (; i < length;) {
let cTop = top(i, ++i)
// Определение перехода на другую строку
if (cTop - 1 < sTop) {
continue
}
if (--lines) {
sTop = cTop
} else {
// Перескочили на 4 строку
// Тут надо отойти на 3 символа назад, но лучше на 4 :)
element.firstChild.data = element.firstChild.data.substring(0, i - 4) + '...'
return
}
}
}
// Запихиваем все блоки
document.querySelectorAll('div').forEach((e) => lineClamp(e, 3))
div {
width: 150px;
background-color: aliceblue;
display: block;
float: left;
margin: 10px;
}
<div>Описание на нескольких строках. У меня есть множество карточек, в каждом из них должно быть описание, но оно не должно быть больше 3 строчек, иначе выглядит не очень.</div>
<div>Очень короткий текст.</div>
<div>Несколько строк. Какие бы я решения не находил - все они работают с 1 блоком, а у меня множество блоков с одинаковым классом, дак ещё и динамически блоки будут добавляться.</div>
Вот только здесь не учтен "переезд" слова на следующую строку, поэтому строка может быть неполная. Но при желании можно добавить расчет ширины символов.
.text {
display: inline-block; position: relative; overflow: hidden; margin: 10px; width: 250px;
font-size: 16px; line-height: 1.2em; max-height: calc(1.2em * 3);
}
.text::after {content: "..."; position: absolute; right: 0; top: 2.3em;}
<span class="text">У меня есть множество карточек, в каждом из них должно быть описание, но оно не должно быть больше 3 строчек, иначе выглядит не очень, а описание набирает пользователь (уменьшить описание - не вариант), какие бы я решения не находил - все они работают с 1 блоком, а у меня множество блоков с одинаковым классом, дак ещё и динамически блоки будут добавляться.</span>
<span class="text">Солнышко блестит; Ласточка с весною В сени к нам летит. С нею солнце краше И весна милей Нам привет скорей! Дам тебе я зерен, А ты песню спой, Что из стран далеких Принесла с собой</span>
С использованием javascript обрезаем строку split потом соединяем join и пристыковываем точки padEnd
document.querySelectorAll("p").forEach(function(el) {
el.innerHTML = el.innerHTML.split('', 10).join('').padEnd(14, '.');
})
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Velit adipisci nemo ad animi sint blanditiis commodi ea modi perferendis tempora? Lorem ipsum, dolor sit amet consectetur adipisicing elit. Neque suscipit harum delectus ipsam saepe illo minus</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Velit adipisci nemo ad animi sint blanditiis commodi ea modi perferendis tempora? Lorem ipsum, dolor sit amet consectetur adipisicing elit. Neque suscipit harum delectus ipsam saepe illo minus</p>
<p>Далеко-далеко за словесными горами в стране гласных и согласных живут рыбные тексты. Гор жизни великий переписали имеет рукописи необходимыми напоивший текст рукопись обеспечивает они свой пустился текстами инициал лучше подзаголовок, рыбными ему маленький</p>
Пример с переносом строки
document.querySelectorAll("p").forEach((el) => {
el.innerHTML = el.innerHTML.split('', 50).join('').padEnd(55, '.');
})
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@1,100&display=swap');
* {
font-family: 'Roboto', sans-serif;
margin: 0;
box-sizng: border-box;
}
p {
font-size: 2.5vw;
max-width: 100%;
background: rgba(0, 0, 0, 0.2);
margin-left: 1vw;
width: 20vw;
padding: 4px;
}
.item {
display: flex;
padding: 1vh;
}
<div class='item'>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam ut voluptates eaque blanditiis explicabo dolorum provident nulla earum sequi dolore.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Delectus inventore asperiores debitis architecto eligendi!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus quo error distinctio excepturi laborum, ullam dolores sint, molestias, cumque placeat illum exercitationem voluptates? Fugiat omnis a error architecto cupiditate asperiores libero consectetur
dolorum harum tenetur, pariatur consequatur accusamus voluptatibus aliquid obcaecati dolorem molestias at rem atque eum voluptates. A temporibus laboriosam amet accusamus repellat beatae nesciunt doloribus? Deleniti, ipsam in eveniet similique a repellat
soluta nihil recusandae quod natus praesentium molestiae ullam obcaecati nam error repellendus? Accusantium hic eveniet minima quisquam architecto facilis quaerat magni. Sapiente, reprehenderit! Fugit incidunt corporis quia, sunt odit inventore magni
eligendi quod non beatae illo.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Iure dolor alias nemo consequatur. Neque ea fugiat, odio facere mollitia provident, eius voluptatum sapiente, fuga fugit necessitatibus alias rerum exercitationem recusandae!</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloremque, praesentium!</p>
</div>

