Is it possible to limit a text length to \"n\" lines using CSS (or cut it when overflows vertically).
text-overflow: ellipsis;
only works for 1 line tex
.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;
}
I've been looking around for this, but then I realize, damn my website uses php!!! Why not use the trim function on the text input and play with the max length....
Here is a possible solution too for those using 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;
?>
I have a solution which works well but instead an ellipsis it uses a gradient. It works when you have dynamic text so you don't know if it will be long enough to need an ellipse. The advantages are that you don't have to do any JavaScript calculations and it works for variable width containers including table cells and is cross-browser. It uses a couple of extra divs, but it's very easy to implement.
Markup:
<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%);
}
blog post: http://salzerdesign.com/blog/?p=453
example page: http://salzerdesign.com/test/fade.html
If you want to focus on each letter
you can do like that, I refer to this question
function truncate(source, size) {
return source.length > size ? source.slice(0, size - 1) + "…" : source;
}
var text = truncate('Truncate text to fit in 3 lines', 14);
console.log(text);
If you want to focus on each word
you can do like that + space
const truncate = (title, limit = 14) => { // 14 IS DEFAULT ARGUMENT
const newTitle = [];
if (title.length > limit) {
title.split(' ').reduce((acc, cur) => {
if (acc + cur.length <= limit) {
newTitle.push(cur);
}
return acc + cur.length;
}, 0);
return newTitle.join(' ') + '...'
}
return title;
}
var text = truncate('Truncate text to fit in 3 lines', 14);
console.log(text);
If you want to focus on each word
you can do like that + without space
const truncate = (title, limit = 14) => { // 14 IS DEFAULT ARGUMENT
const newTitle = [];
if (title.length > limit) {
Array.prototype.slice.call(title).reduce((acc, cur) => {
if (acc + cur.length <= limit) {
newTitle.push(cur);
}
return acc + cur.length;
}, 0);
return newTitle.join('') + '...'
}
return title;
}
var text = truncate('Truncate text to fit in 3 lines', 14);
console.log(text);
Working Cross-browser Solution
This problem has been plaguing us all for years.
To help in all cases, I have laid out the CSS only approach, and a jQuery approach in case the css caveats are a problem.
Here's a CSS only solution I came up with that works in all circumstances, with a few minor caveats.
The basics are simple, it hides the overflow of the span, and sets the max height based on the line height as suggested by Eugene Xa.
Then there is a pseudo class after the containing div that places the ellipsis nicely.
Caveats
This solution will always place the ellipsis, regardless if there is need for it.
If the last line ends with an ending sentence, you will end up with four dots....
You will need to be happy with justified text alignment.
The ellipsis will be to the right of the text, which can look sloppy.
Code + Snippet
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 Approach
In my opinion this is the best solution, but not everyone can use JS. Basically, the jQuery will check any .text element, and if there are more chars than the preset max var, it will cut the rest off and add an ellipsis.
There are no caveats to this approach, however this code example is meant only to demonstrate the basic idea - I wouldn't use this in production without improving on it for a two reasons:
1) It will rewrite the inner html of .text elems. whether needed or not. 2) It does no test to check that the inner html has no nested elems - so you are relying a lot on the author to use the .text correctly.
Thanks for the catch @markzzz
Code & Snippet
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 -->
Basic Example Code, learning to code is easy. Check Style CSS comments.
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>