Text Fade Out / Read More Link

Published by Chris Coyier

Reader Rob Young sent in a cool effect seen on Newsweek.com:


Screenshot from here

The text fades out at the bottom and has a "More..." link. Text fade out is nothing new around here. I've had a demo up for that for ages, which uses a transparent PNG file placed overtop the text. But since this is a slightly different idea and the times-are-a-changin' and we can get a bit more progressive with this idea.

Let's assume these small boxes of text are used in a sidebar, so our HTML markup will be a div with class of sidebar-box. This div can contain any number of paragraph elements, the last of which will have a class name of read-more which contains a link button.

<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.</p>
  <p class="read-more"><a href="#" class="button">Read More</a></p>
</div>

The box will be limited in height by the appropriate property max-height with it's overflow set to hidden. We'll also use relative positioning as we will need that to use absolute positioning on the read-more paragraph, which is locked to the bottom of the box and uses CSS3 gradients to achieve the text fade out.

.sidebar-box {
  max-height: 120px;
  position: relative;
  overflow: hidden;
}
.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);
}

Which gives us:

The "Reveal" with jQuery

The simplest way to make this work would be to remove the max-height CSS from the sidebar box on a click. That would let it instantly expand down to the natural height of all contained paragraphs. Theoretically you could do this with CSS3 and :target, but that's temporary and would cause page jump-downs. We can make it more elegant by using JavaScript and the easy animations of jQuery.

var $el, $ps, $up, totalHeight;

$(".sidebar-box .button").click(function() {
      
  totalHeight = 0

  $el = $(this);
  $p  = $el.parent();
  $up = $p.parent();
  $ps = $up.find("p:not('.read-more')");
  
  // measure how tall inside should be by adding together heights of all inside paragraphs (except read-more paragraph)
  $ps.each(function() {
    totalHeight += $(this).outerHeight();
  });
        
  $up
    .css({
      // Set height to prevent instant jumpdown when max height is removed
      "height": $up.height(),
      "max-height": 9999
    })
    .animate({
      "height": totalHeight
    });
  
  // fade out read-more
  $p.fadeOut();
  
  // prevent jump-down
  return false;
    
});

So in Plain English, when a button is clicked inside of a sidebar-box, find all the related players involved (parent elements and such), measure a new ideal height, animate to that new height, and remove the button.

View Demo   Download Files

Quick note about Transparency & Gradients

I had some head-scratchers going on trying to figure out a weird problem using CSS3 gradients and fading from "transparent" to a regular hex color. It seemed like the color was multiplying onto the background. What is actually happening is that the word "transparent" is actually just mapped to "rgba(0, 0, 0, 0)" which means "fully transparent black." So when the gradient is built, the intermediary colors are mixed with not-quite-totally transparent black. To fix this, you'll need to use RGBa colors in both the start and fade to color, even if it's fully transparent. For example, for red to fade from red to transparent:

background-image: -webkit-gradient(
  linear,
  left top,
  left bottom,
  color-stop(0, rgba(255, 0, 0, 0)),
  color-stop(1, rgba(255, 0, 0, 100)));

And don't forget all the other gradient syntaxes. CSS3 Please! is a great resource for getting quick up-to-date CSS3 syntaxes.

Thanks to @foodgoesinmouth, @sebnitu, @maddesigns and others...