I am working on a way to display posts in a way that if the text of the post has more than three lines, only the first three lines are displayed and the rest is toggled via a Show More/Show Less div. I am using liquid for the loop over the posts, a css class for truncating and jquery for toggeling the truncate class
My problem now is that I would like to give the Show More/Show Less div the display:none property if we have less than three lines, but I don't know how.
Here is the code excerpt:
html:
<div class="posts">
{% for post in site.posts %}
<div class="post-teaser">
{% if post.thumbnail %}
<div class="post-img">
<img src="{{ site.baseurl }}/{{ post.thumbnail }}">
</div>
{% endif %}
<span>
<header>
<h1>
{{ post.title }}
</h1>
<p class="meta">
{{ post.date | date: "%B %-d, %Y" }}
</p>
</header>
<div id="{{post.path}}" class="excerpt truncate">
{{ post.content | strip_html | escape }}
</div>
<div class="txtcol"><a>Show More</a></div>
</span>
</div>
{% endfor %}
CSS:
/* styles for '...' */
.truncate {
/* hide text if it more than N lines */
overflow: hidden;
/* for set '...' in absolute position */
position: relative;
/* use this value to count block height */
line-height: 1.2em;
/* max-height = line-height (1.2) * lines max number (3) */
max-height: 3.6em;
/* fix problem when last visible word doesn't adjoin right side */
text-align: justify;
/* place for '...' */
margin-right: -1em;
padding-right: 1em;
}
/* create the ... */
.truncate:before {
/* points in the end */
content: '...';
/* absolute position */
position: absolute;
/* set position to right bottom corner of block */
right: 0;
bottom: 0;
}
/* hide ... if we have text, which is less than or equal to max lines
*/
.truncate:after {
/* points in the end */
content: '';
/* absolute position */
position: absolute;
/* set position to right bottom corner of text */
right: 0;
/* set width and height */
width: 1em;
height: 1em;
margin-top: 0.2em;
/* bg color = bg color under block */
background: white;
}
from here: /
And jquery:
<script src=".3.1/jquery.min.js">
</script>
<script>
$(document).ready(function(){
$(".txtcol").click(function(){
if($(this).prev().hasClass("truncate")) {
$(this).children('a').text("Show Less");
} else {
$(this).children('a').text("Show More");
}
$(this).prev().toggleClass("truncate");
});
});
</script>
I would prefer a CSS solution, if possible.
EDIT: here is a snippet: /
In the second post, the show more/show less should not appear (on most devices).
EDIT 2: Here is my try to implement it, but somehow the line
$(this).next().css("display", "none;");
does not work. /+
EDIT 3: It was a typo; it now works: /
I am working on a way to display posts in a way that if the text of the post has more than three lines, only the first three lines are displayed and the rest is toggled via a Show More/Show Less div. I am using liquid for the loop over the posts, a css class for truncating and jquery for toggeling the truncate class
My problem now is that I would like to give the Show More/Show Less div the display:none property if we have less than three lines, but I don't know how.
Here is the code excerpt:
html:
<div class="posts">
{% for post in site.posts %}
<div class="post-teaser">
{% if post.thumbnail %}
<div class="post-img">
<img src="{{ site.baseurl }}/{{ post.thumbnail }}">
</div>
{% endif %}
<span>
<header>
<h1>
{{ post.title }}
</h1>
<p class="meta">
{{ post.date | date: "%B %-d, %Y" }}
</p>
</header>
<div id="{{post.path}}" class="excerpt truncate">
{{ post.content | strip_html | escape }}
</div>
<div class="txtcol"><a>Show More</a></div>
</span>
</div>
{% endfor %}
CSS:
/* styles for '...' */
.truncate {
/* hide text if it more than N lines */
overflow: hidden;
/* for set '...' in absolute position */
position: relative;
/* use this value to count block height */
line-height: 1.2em;
/* max-height = line-height (1.2) * lines max number (3) */
max-height: 3.6em;
/* fix problem when last visible word doesn't adjoin right side */
text-align: justify;
/* place for '...' */
margin-right: -1em;
padding-right: 1em;
}
/* create the ... */
.truncate:before {
/* points in the end */
content: '...';
/* absolute position */
position: absolute;
/* set position to right bottom corner of block */
right: 0;
bottom: 0;
}
/* hide ... if we have text, which is less than or equal to max lines
*/
.truncate:after {
/* points in the end */
content: '';
/* absolute position */
position: absolute;
/* set position to right bottom corner of text */
right: 0;
/* set width and height */
width: 1em;
height: 1em;
margin-top: 0.2em;
/* bg color = bg color under block */
background: white;
}
from here: http://hackingui./front-end/a-pure-css-solution-for-multiline-text-truncation/
And jquery:
<script src="https://ajax.googleapis./ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<script>
$(document).ready(function(){
$(".txtcol").click(function(){
if($(this).prev().hasClass("truncate")) {
$(this).children('a').text("Show Less");
} else {
$(this).children('a').text("Show More");
}
$(this).prev().toggleClass("truncate");
});
});
</script>
I would prefer a CSS solution, if possible.
EDIT: here is a snippet: https://jsfiddle/6349q51r/4/
In the second post, the show more/show less should not appear (on most devices).
EDIT 2: Here is my try to implement it, but somehow the line
$(this).next().css("display", "none;");
does not work. https://jsfiddle/6349q51r/29/+
EDIT 3: It was a typo; it now works: https://jsfiddle/6349q51r/36/
Share Improve this question edited Sep 14, 2018 at 18:59 ge0rg asked Sep 13, 2018 at 15:32 ge0rgge0rg 731 silver badge12 bronze badges 4- 3 It would really help if you create a snippet of your situation! – Thomas van Broekhoven Commented Sep 13, 2018 at 15:35
- to further thomas' ment, it would also be very beneficial if you could use the rendered html rather than what looks like liquid – Pete Commented Sep 13, 2018 at 15:47
- you can use regular expression to keep count of how many lines there is in the dom and then toggle the class to display or show the toggle link. – Jose CC Commented Sep 13, 2018 at 15:48
- This answer might help: stackoverflow./questions/8720931/… – Kent Brewster Commented Sep 14, 2018 at 18:17
2 Answers
Reset to default 5You can check for the height of the data with scrollHeight of the data. if scrollHeight is greater than height then show the Show More/Less div.
I have created one snippet for you.. see the js and css.
$(document).ready(function(){
$(".content").each(function(){
if($(this).height() < $(this)[0].scrollHeight){
$(this).parent().find(".txtcol").show();
$(this).toggleClass("truncate");
}
});
$(".txtcol").click(function(){
if($(this).prev().hasClass("truncate")) {
$(this).parent().find(".content").css("max-height", $(this).parent().find(".content")[0].scrollHeight);
$(this).children('a').text("Show Less");
} else {
$(this).parent().find(".content").css("max-height", "3.6em");
$(this).children('a').text("Show More");
}
$(this).prev().toggleClass("truncate");
});
});
.content {
width:100px;
overflow: hidden;
white-space:normal;
text-overflow: ellipsis;
line-height: 1.2em;
/* max-height = line-height (1.2) * lines max number (3) */
max-height: 3.6em;
/* fix problem when last visible word doesn't adjoin right side */
text-align: justify;
}
.txtcol{
display:none;
color:blue;
cursor:pointer;
}
.maincontent{
display:inline-block;
vertical-align:top;
border: 1px solid gray;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="maincontent">
<div class="content">
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
</div>
<div class="txtcol"><a>Show More</a></div>
</div>
<div class="maincontent">
<div class="content">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been Lorem Ipsum has been Lorem Ipsum has been Lorem Ipsum has been
</div>
<div class="txtcol"><a>Show More</a></div>
</div>
<div class="maincontent">
<div class="content">
Lorem Ipsum is simply
</div>
<div class="txtcol"><a>Show More</a></div>
</div>
You can test it on jsfiddle with small amount of text..
https://jsfiddle/nimittshah/rdjyucpz/
Thanks,
$(document).ready(function(){
$(".content").each(function(){
if($(this).height() < $(this)[0].scrollHeight){
$(this).parent().find(".txtcol").show();
$(this).toggleClass("truncate");
}
});
$(".txtcol").click(function(){
if($(this).prev().hasClass("truncate")) {
$(this).parent().find(".content").css("max-height", $(this).parent().find(".content")[0].scrollHeight);
$(this).children('a').text("Show Less");
} else {
$(this).parent().find(".content").css("max-height", "3.6em");
$(this).children('a').text("Show More");
}
$(this).prev().toggleClass("truncate");
});
});
.content {
width:100px;
overflow: hidden;
white-space:normal;
text-overflow: ellipsis;
line-height: 1.2em;
/* max-height = line-height (1.2) * lines max number (3) */
max-height: 3.6em;
/* fix problem when last visible word doesn't adjoin right side */
text-align: justify;
}
.txtcol{
display:none;
color:blue;
cursor:pointer;
}
.maincontent{
display:inline-block;
vertical-align:top;
border: 1px solid gray;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="maincontent">
<div class="content">
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
</div>
<div class="txtcol"><a>Show More</a></div>
</div>
<div class="maincontent">
<div class="content">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been Lorem Ipsum has been Lorem Ipsum has been Lorem Ipsum has been
</div>
<div class="txtcol"><a>Show More</a></div>
</div>
<div class="maincontent">
<div class="content">
Lorem Ipsum is simply
</div>
<div class="txtcol"><a>Show More</a></div>
</div>