63

I'm trying to get a nice fade-out effect at the bottom of a section of text as a 'read more' indicator.

I've been following a bit off this and other tutorials, and my code currently is as follows:

html

<section>
    <p>malesuada fames ac turpis egestas...leo.</p>                                                                  
    <p>malesuada fames ac turpis egestas...leo.</p>
    <div class="fadeout"></div>
</section>
<p>Stuff after</p>

css

.fadeout {
    position: relative; 
    bottom: 4em;
    height: 4em;
    background: -webkit-linear-gradient(
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 1) 100%
    ); 
} 

jsFiddle

The problem is, even when I position the transparent div over the body of text, the 4em's of space still exists between and 'Other Stuff.'

Any ideas?

5 Answers 5

116

Answer for 2020:

This effect can now be achieved with true alpha transparency, without the need to cover the bottom with an additional <div>. Simply use the CSS mask-image property with a linear gradient that fades from black to transparent. The browser should take care of the rest for you. Demo:

.container {
  -webkit-mask-image: linear-gradient(to bottom, black 50%, transparent 100%);
  mask-image: linear-gradient(to bottom, black 50%, transparent 100%);
  height:  150px;
  width: 300px;
  overflow-y: scroll;
}
body {
  background: #09f;
  transition: background 0.5s ease-out;
}
body:hover {
  background: #f90;
}
<div class="container">
  <p>Mouse in/out of this demo or scroll down to see that it's true alpha! <br/>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam sed nisl id lectus viverra faucibus. Cras sed est sit amet turpis placerat consequat. Vestibulum viverra accumsan nisl a dapibus. Quisque mollis porta dictum. Praesent dictum non nisl at rutrum. Nam sem orci, efficitur quis faucibus non, aliquam eget est. In nec finibus ex, quis tristique augue. Duis tristique turpis a nunc sodales tincidunt.</p>
  <p>Morbi vehicula nisi ut lacus ornare, ac tincidunt sapien pellentesque. Aliquam gravida id dolor eget volutpat. In hac habitasse platea dictumst. Aenean ac enim eros. Vivamus augue nunc, interdum vitae pellentesque nec, interdum non turpis. Quisque viverra eget nibh in varius. Vivamus vel euismod velit. Vivamus suscipit lorem et porttitor gravida. Donec non nulla nulla. Duis eget dui sed urna eleifend sagittis.</p>
</div>

The best part of this approach is that it's true transparency, instead of faking it by covering your text with a color that matches the background. This allows for scrolling and background images! I change the background color on hover to demonstrate that it's truly transparent.

Browser support is pretty solid, except for IE.

6
  • 1
    great answer. I need to fade bottom as well. So, is it possible to manipulate -webkit-mask-image: linear-gradient(to bottom, black 50%, transparent 100%); in such a way that I can add to top as well? Commented Jul 1, 2020 at 13:46
  • @VinaySharma You can add as many gradient stops as you want to the linear-gradient() attribute.
    – M -
    Commented Jul 1, 2020 at 17:02
  • Umm.. I tried linear-gradient(to bottom, black 50%, transparent 100%, to left, black 50%, transparent 100%, to right, black 50%, transparent 100%);and It didn’t work 😅 Commented Jul 1, 2020 at 17:14
  • 5
    Quick question, is there a way not to show the blurred when the user scrolled to the bottom? I mean it is difficult to read. Commented Sep 27, 2020 at 15:40
  • 1
    @SubhenduKundu just add padding at the bottom so the text can scroll past the transparent part.
    – M -
    Commented Sep 27, 2020 at 17:36
58

A relatively position element is not removed from the normal html flow, so if you move it around the initial space reserved for it still remains, however with absolute positioning this is not the case

.fadeout {
    position: absolute; 
    bottom: 0em;
    width:100%;
    height: 4em;
    background: -webkit-linear-gradient(
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 1) 100%
    ); 
    background-image: -moz-linear-gradient(
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 1) 100%
    );
    background-image: -o-linear-gradient(
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 1) 100%
    );
    background-image: linear-gradient(
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 1) 100%
    );
    background-image: -ms-linear-gradient(
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 1) 100%
    );
} 
section {position:relative}     

DEMO

3
  • 1
    is there a way to make it cross-browser?
    – dark_ruby
    Commented Feb 15, 2013 at 11:07
  • @ArtDeineka if you are talking about the linear gradient then see update.
    – Musa
    Commented Feb 15, 2013 at 15:02
  • Thumbs up on the cross-browser answer. Here's a DEMO on how I usually use it to have all block looking the same unless you reveal them by clicking on them.
    – s3c
    Commented Jan 22, 2020 at 9:47
12

Came to this late to the party, but this can also be done without the .fadeout div, using a ::before or ::after pseudo-element:

        section {
            position: relative;
        }

        section::after {
            content: '';
            position: absolute;
            bottom: 0;
            width: 100%;
            height: 15px;
            background: -webkit-linear-gradient(
                    rgba(255, 255, 255, 0) 0%,
                    rgba(255, 255, 255, 1) 100%
            );
            background-image: -moz-linear-gradient(
                    rgba(255, 255, 255, 0) 0%,
                    rgba(255, 255, 255, 1) 100%
            );
            background-image: -o-linear-gradient(
                    rgba(255, 255, 255, 0) 0%,
                    rgba(255, 255, 255, 1) 100%
            );
            background-image: linear-gradient(
                    rgba(255, 255, 255, 0) 0%,
                    rgba(255, 255, 255, 1) 100%
            );
            background-image: -ms-linear-gradient(
                    rgba(255, 255, 255, 0) 0%,
                    rgba(255, 255, 255, 1) 100%
            );
        }
0
8

Simple add .fade-out onto the element you want to "fade-out":

.fade-out {
  position: relative;
  max-height: 350px; // change the height
}
.fade-out:after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-image: linear-gradient( rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 1) 100% );
}
1
  • I think you need overflow:hidden on the .fade-out class.
    – Pointi
    Commented Dec 13, 2018 at 15:04
0

Just replace bottom: 4em with margin-top: -4em. Works perfect for me.

Not the answer you're looking for? Browse other questions tagged or ask your own question.