Reputation: 9850
I have a div and it contains a paragraph that is populated dynamically. Sometimes the paragraph is 20 lines, and sometimes it is 3.
I want to set a height limit upon which if the div is larger than this (due to there being more lines in the paragraph) it will shrink it down to only show 3 lines of text and then have a "View More" button that will expand and/or collapse the div upon request to show the remaining lines in the paragraph.
<div class="hero-unit">
<h1>Product Description</h1>
<p>{{paragraph}}</p>
</div>
Any tips on how I can do this as easily as possible?
Upvotes: 4
Views: 28135
Reputation: 4382
If you're available to use bootstrap, take a look at bootstrap.javascript.collapse and you'll find and easy fast solution like the one I've wroten: http://getbootstrap.com/javascript/#collapse
<div class="collapse" id="collapseExample">
<div class="hero-unit collapse" id="collapseHeroeUnit">
<h1>Product Description</h1>
<p>{{paragraph}}</p>
</div>
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
Expand the div
</button>
Upvotes: 0
Reputation: 1355
Here is the solution that uses pure javascript, html and css.
Problem with many answers is that even if the text is less than the limit, it is given the maximum height. Thus the element containing text will always have the fixed height, even when not required.
This code does not use the maximum height parameter when not necessary i.e. if the text is not exceeding the limit then it renders text with default height and not the fixed height. The text is applied the maximum height only when text exceeds the limit. Similarly, the "show more" is displayed only when required.
Here is the demo
HTML
<div class="hero-unit">
<h1>Product Description</h1>
<div id='tagList'>this is really long text; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ; this is really long text ;
</div>
<div id="toggleExpandBtn" style = "text-align:right">More</a>
</div>
Javascript
window.onload = function(){
var tagList = document.getElementById('tagList')
var style = window.getComputedStyle(tagList)
var lineheight = parseInt(style.getPropertyValue('line-height'));
var height = parseInt(style.getPropertyValue('height'));
tagList.style.height = 'auto';
if (height < lineheight*3) {
document.getElementById('toggleExpandBtn').style.display = 'none';
}
else{
tagList.style.height = lineheight*3 + 'px';
document.getElementById('toggleExpandBtn').style.display = 'inline';
}
}
document.getElementById('toggleExpandBtn').addEventListener('click',function(){
var tagList = document.getElementById('tagList')
var style = window.getComputedStyle(tagList)
var lineheight = parseInt(style.getPropertyValue('line-height'));
var height = parseInt(style.getPropertyValue('height'));
if (height == lineheight*3) {
tagList.style.height = 'auto';
document.getElementById('toggleExpandBtn').textContent = 'Less';
} else {
tagList.style.height = lineheight*3 + 'px';
document.getElementById('toggleExpandBtn').textContent = 'More';
}
});
CSS
#tagList {
line-height: 18px;
overflow: hidden;
}
Upvotes: 0
Reputation: 61143
$('.hero-unit').each(function () {
var ht = $(this).height();
if (ht > '200') {
var button = $('<span class="btn">Show all</button>');
$(this).children('p').css('height', '50px');
$(this).append(button);
}
});
$('.btn').on('click', function () {
$(this).hide();
$(this).prev('p').css('height', 'auto');
});
Upvotes: 0
Reputation: 10154
If you want exactly 3 lines, notice that this means that the height should be 3*line-height
. You could then do this:
HTML
<div class="hero-unit">
<h1>Product Description</h1>
<p>...</p>
<a>More</a>
</div>
CSS
p {
line-height: 18px;
height: 54px;
overflow: hidden;
}
overflow: hidden
will hide content that exceed the container boundaries.
jQuery
We then toggle the height constraint.
$('a').click(function() {
var p = $('a').prev('p')
var lineheight = parseInt(p.css('line-height'))
if (parseInt(p.css('height')) == lineheight*3) {
p.css('height','auto');
$(this).text('Less')
} else {
p.css('height',lineheight*3+'px');
$(this).text('More')
}
});
See demo.
Upvotes: 5
Reputation: 65391
You can do this with some simple Javascript (no jQuery needed) and some CSS classes. To simplify design, assume a set min and max height.
Script:
document.getElementById( 'slide' ).addEventListener( 'click', function() {
var body = document.getElementById( 'slide-body' );
if( body.className == 'expanded' ) {
body.className = '';
document.getElementById( 'more' ).textContent = 'more...';
} else {
body.className = 'expanded';
document.getElementById( 'more' ).textContent = 'less...';
};
} );
HTML:
<div id="slide">
<div id="slide-body">
A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph. A really long paragraph.
</div>
<div id="more">more...</div>
</div>
CSS:
#slide {
border: 1px solid black;
}
#slide-body{
height: 55px;
overflow: hidden;
transition: height 500ms ease;
-moz-transition: height 500ms ease;
-ms-transition: height 500ms ease;
-o-transition: height 500ms ease;
-webkit-transition: height 500ms ease;
}
.expanded {
height: 150px !important;
}
#more {
cursor: pointer;
text-align: right;
}
Upvotes: 4
Reputation: 167250
The simple solution would be having a fixed height.
<div class="hero-unit">
<h1>Product Description</h1>
<p>{{paragraph}}</p>
</div>
As you are sure that there will be at least one <h1>
(ps: it is not a good idea to have multiple <h1>
tags) and <p>
, we can be sure of the height would be roughly about, say 100px
.
The first simple way would be setting a fixed height:
.hero-unit {height: 100px; overflow: hidden;}
This would abruptly cut the contents. If you need something better, you can go ahead with placing an image, which fades from transparent to white. Say, something like this:
.hero-unit {height: 100px; overflow: hidden; position: relative;}
.hero-unit img.fade {position: absolute; bottom: 0;}
So, this technique will not cut the contents abruptly, but will give a smooth fade effect.
The final one would be using plugins. You can choose either you show the full content and give a scrollbar, or showing it after some user interactions. If you prefer the first one, go for jScrollPane. Or, if you prefer the latter, go for either dotdotdot, or the below script might help:
var p = $('.hero-unit p');
var divh = $('.hero-unit').height();
while ($(p).outerHeight() > divh) {
$(p).text(function (index, text) {
return text.replace(/\W*\s(\S)*$/, '...');
});
}
Upvotes: 0
Reputation: 741
Personally I find the best method is to set a max-height and overflow:auto;. This way it keeps it small enough to just fit the three lines, or easily expand to a set height to have proper accommodation for the rest of the paragraph. Hope this helps.
Upvotes: 0
Reputation: 1220
You might want to try something along the lines of what adnbutton.com did to view the code. I think that's what you want to do. If you only want to do this when there is more than 3 lines, you'd have to do this with jQuery or the like.
Upvotes: 0