Add a read more link based on height of conatiner

Hi all,

Thanks to a css tricks article, I found a javascript/jquery function which shows hidden text based on a particular height. Works ok, though not quite what I’m after.

If anything, I just like the way they have coded it.
I created a codepen of this if anybody would like to check it out.

I’m hoping to build something similar.

My Pseudo

  1. Measure the height of .wrapper
  2. If wrapper exceeds 120px then hide the overflow and add a read more link below it.
  3. Click read more link and show hidden text

If height is no greater than 120px or javascript is off, then no read more link would ever show.

Sounds quite simply :upside_down:

Any ideas/help how I can achieve this?

<div class="wrapper">
  <p>Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum.</p>
</div>
<div class="wrapper">
  <ul>
    <li>Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus.</li>
    <li>Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum.</li>
  </ul>
</div>

Thanks,
Barry

HTML:

<div class="sidebar-box">
  <p>malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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.malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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.malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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

body {background:black;color:white;width:400px}
.sidebar-box {
  max-height: 120px;
  position: relative;
 
}
.sidebar-box .read-more { 
  position: absolute; 
  bottom: 0; 
  left: 0;
  width: 100%; 
  text-align: center; 
  margin: 0; padding: 30px 0; 
	
  /* "transparent" only works here because == rgba(0,0,0,0) */
  background-image: linear-gradient(to bottom, transparent, black);
}

JS

$(function(){
var height=$('p').height();
var a=$('<a>Load More</a>')
if(height>=120){
$('.sidebar-box').css('overflow','hidden');
$('body').append(a.on('click',function(){
$(this).detach();
$('.sidebar-box').css('overflow','visible');
}));
}
});

And a JSFiddle sample here

Thanks @liontas76

Been doing a bit of testing - latest fiddle
And changed from sidebar-box to wrapper, just for clarity.

Ok, looking good so far :slight_smile:

Just a couple of issues.
If I add a second .wrapper the load more link is only displayed on one instance.

Example, I could have:

<div class="wrapper">
  text here
</div>
<div class="wrapper">
  text here
</div>
<ul>
  <li class="wrapper"></li>
  <li class="wrapper"></li>
</ul>
<div class="wrapper">
  text here
</div>

I would also like to measure the height of .wrapper as each wrapper could have p, li’s or some other element, I can’t always rely on the p element being available.

latest code

$(function(){
  var height = $('.wrapper').height();
  var a = $('<a>Load More</a>');
	
  if(height>=120){
  $('.wrapper').css('overflow','hidden');
    $('body').append(a.on('click',function(){
      $(this).detach();
      $('.wrapper').css('overflow','visible');
    }));
  }
});

The idea is to simply add the wrapper class to any element and produce the read more based on the height.

Barry

That sounds like a ‘magic number’ that won’t work for everyone unless you have a specific use case for this? What if someone has zoomed their text or the text has wrapped to more lines in smaller viewports? Usually you would base a ‘read more’ link on the number of characters as that would make more sense.

Unless of course you have a specific case in mind where the height is relative to something else that you have going on. I just can’t think of a good reason to base this on height as such but I may be missing the bigger picture :slight_smile:

BTW your max-height is not enough height to show all the text in your first demo (and of course would be wrong if I had zoomed my text or had large fonts nor whatever) :slight_smile:

1 Like

HTML:

  <p>malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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.malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante.</p>
</div>

<div class="wrapper">
  <p>malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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.malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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.malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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>
<div class="wrapper">
  <p>malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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.malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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.malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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>

<div class="wrapper">
  <p>malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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.malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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.malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor 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>

JS

$(function(){
	
  $('.wrapper').each(function(){
   var height = $(this).height();
	 var a = $('<a>Load More</a>');
	
   if(height>=120){  
		$(this).css('overflow','hidden');

		$(this).after(a.on('click',function(){   
    $(this).prev().css({'overflow':'unset','max-height':$(this).prev().find('p').css('height')});
    $(this).detach();  
   
		}));
	}
  });
});

JSFiddle Here

1 Like

Arrrh, yes I think your right.
I didn’t see it like that, good point!

Nothing in particular.

I did see a few examples using character count maybe I’ll need to have a small rethink. The code you supply looks good, seen this around :nerd:
Albeit, not to happy mixing big snippets of html and javascript together.

I realised this as lots of text is overlapping.
Ideally, I’d like to keep the generic css out of the mix until the character count was met.

Back to the drawing board :neutral_face:
I’ll try and build something mixing the two with examples from previous posts.

Thanks.

1 Like

Thanks @liontas76

Just checked the latest updates, again, the p tag is causing a few issues if I don’t have any paragraphs. And as Paul has mentioned, the height could potentially cause issues with different screen sizes and suggests using the char counter.

I’ll post back once I have the working or updated example.

Cheers,
Barry

Hi @PaulOB

This might be useful for yourself. I’ve been reading about modular javascript which highlights good usage of caching and less searching the dom, in particular, what you can see below with your readless function.

A little cleaner, and faster :sunglasses:

From

$(".moreless").click(function(){
	var thisEl = $(this); 
        if(thisEl.hasClass("less")) {
        	thisEl.closest('.truncate-text').prev('.truncate-text').toggle();
    		thisEl.closest('.truncate-text').slideToggle();
        } else {
			thisEl.closest('.truncate-text').toggle();
			thisEl.closest('.truncate-text').next('.truncate-text').fadeToggle();
        }
	   	return false;
    });

To

$(".moreless").click(function(){

	var thisEl = $(this);
    var cT = thisEl.closest('.truncate-text');
    var tX = '.truncate-text';
        
      if(thisEl.hasClass("less")) {
          cT.prev(tX).toggle();
          cT.slideToggle();
        } else {
          cT.toggle();
          cT.next(tX).fadeToggle();
        }
	   	return false;
    });

Speak soon, Barry

1 Like

Cheers I’ll update my demo later :slight_smile:

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.