I want a
Try this handy tool, it'll generate alpha colours for you, you're basically trying to use an rgba value, but of course gotta be aware that this will only be supported by newer browsers...
http://www.colorzilla.com/gradient-editor/
This is what it came up with for a black to 100% alpha gradient: background: url(IMAGE_URL) linear-gradient(to bottom, rgba(0,0,0,1) 0%,rgba(255,255,255,0) 100%);
It is possible, without specifing an height for the container.
Check this working demo, and try to add/remove contents from #contents
HTML
<div id="container">
<div id="contents">
Some contents goes here
</div>
<div id="gradient">
</div>
</div>
CSS
#container {
position:relative;
}
#contents {
background:red;
}
#gradient {
position:absolute;
z-index:2;
right:0; bottom:0; left:0;
height:200px; /* adjust it to your needs */
background: url(data:image/svg+xml;base64,alotofcodehere);
background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 70%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0)), color-stop(70%,rgba(255,255,255,1)));
background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 70%);
background: -o-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 70%);
background: -ms-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 70%);
background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 70%);
}
This will work almost in any browser which supports opacity (including IE9), and here's the IE8 "rgba" fallback (untested):
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#ffffff',GradientType=0 );
To generate your own gradient, visit Colorzilla.
The first stop (0%) must have opacity 0 ( rgba(255,255,255,0);
), then around 70% - do some tests to find what's good for you - add another stop with opacity 1 ( rgba(255,255,255,1);
).
You've to know the background of the page/container to make it work obviously...
If you are ok with using JavaScript for this, then you could do it using a canvas
element
The idea is that your element with the text and the canvas
element are one on top of the other. You keep the text in your element (in order to allow text selection, which isn't possible with canvas
text), but make it completely transparent (with rgba(0,0,0,0)
, in order to have the text visible in IE8 and older - that's because you have no RGBa
support and no canvas
support in IE8 and older).
You then read the text inside your element and write it on the canvas with the same font properties so that each letter you write on the canvas is over the corresponding letter in the element with the text.
The canvas
element does not support multi-line text, so you'll have to break the text into words and then keep adding words on a test line which you then measure. If the width taken by the test line is bigger than the maximum allowed width you can have for a line (you get that maximum allowed width by reading the computed width of the element with the text), then you write it on the canvas without the last word added, you reset the test line to be that last word, and you increase the y coordinate at which to write the next line by one line height (which you also get from the computed styles of your element with the text). With each line that you write, you also decrease the opacity of the text with an appropriate step (this step being inversely proportional to the average number of characters per line).
What you cannot do easily in this case is to justify text. It can be done, but it gets a bit more complicated, meaning that you would have to compute how wide should each step be and write the text word by word rather than line by line.
Also, keep in mind that if your text container changes width as you resize the window, then you'll have to clear the canvas and redraw the text on it on each resize.
OK, the code:
HTML:
<article>
<h1>Interacting Spiral Galaxies NGC 2207/ IC 2163</h1>
<em class='timestamp'>February 4, 2004 09:00 AM</em>
<section class='article-content' id='art-cntnt'>
<canvas id='c' class='c'></canvas>In the direction of the <!--and so on-->
</section>
</article>
CSS:
html {
background: url(moving.jpg) 0 0;
background-size: 200%;
font: 100%/1.3 Verdana, sans-serif;
animation: ani 4s infinite linear;
}
article {
width: 50em; /* tweak this ;) */
padding: .5em;
margin: 0 auto;
}
.article-content {
position: relative;
color: rgba(0,0,0,0);
/* add slash at the end to check they superimpose *
color: rgba(255,0,0,.5);/**/
}
.c {
position: absolute;
z-index: -1;
top: 0; left: 0;
}
@keyframes ani { to { background-position: 100% 0; } }
JavaScript:
var wrapText = function(ctxt, s, x, y, maxWidth, lineHeight) {
var words = s.split(' '), line = '',
testLine, metrics, testWidth, alpha = 1,
step = .8*maxWidth/ctxt.measureText(s).width;
for(var n = 0; n < words.length; n++) {
testLine = line + words[n] + ' ';
metrics = ctxt.measureText(testLine);
testWidth = metrics.width;
if(testWidth > maxWidth) {
ctxt.fillStyle = 'rgba(0,0,0,'+alpha+')';
alpha -= step;
ctxt.fillText(line, x, y);
line = words[n] + ' ';
y += lineHeight;
}
else line = testLine;
}
ctxt.fillStyle = 'rgba(0,0,0,'+alpha+')';
alpha -= step;
ctxt.fillText(line, x, y);
return y + lineHeight;
}
window.onload = function() {
var c = document.getElementById('c'),
ac = document.getElementById('art-cntnt'),
/* use currentStyle for IE9 */
styles = window.getComputedStyle(ac),
ctxt = c.getContext('2d'),
w = parseInt(styles.width.split('px')[0], 10),
h = parseInt(styles.height.split('px')[0], 10),
maxWidth = w,
lineHeight = parseInt(styles.lineHeight.split('px')[0], 10),
x = 0,
y = parseInt(styles.fontSize.split('px')[0], 10),
text = ac.innerHTML.split('</canvas>')[1];
c.width = w;
c.height = h;
ctxt.font = '1em Verdana, sans-serif';
wrapText(ctxt, text, x, y, maxWidth, lineHeight);
};
There have been improvements in the browser world towards this ability using masks, however, as far as I can see none of it is completely standardised across browsers (in a nice way) yet. So whatever you implement it gets messy. For further information on recent enhancements, the following is a good post:
https://css-tricks.com/clipping-masking-css/
Chrome seems to win out in terms of support and speed, with Safari not far behind. Sadly Firefox does not support much of the linked to page, save for anything that relies on SVG. Luckily it is the SVG examples that show fading and seem to work across Chrome, Safari and Firefox (at least the latest versions of).
So perhaps the best route for now is to implement an SVG mask — based on a rectangle with a gradient applied — and assign it using mask: url(#maskid);
. However, I tend to find these solutions get confused by SVG viewBox
and dimensional sizing issues — and can go very odd when not applied to "media" elements — so will hold off on giving a water tight example for now.
The only way to currently achieve this is to layer a gradient fading to the background colour "on top" of the element you want to fade using position absolute. So using the gradients from the other answers above, but apply this to a floating element on top of the text.
This gets the best effect when you have a solid background colour, but it is doable with background images as well, as long as the background is fixed in position.
css
.container {
position: relative;
overflow: hidden;
height: 50px; /* some fixed height that you need you content to fix to */
}
.fadeout {
position: absolute;
width: 100%;
height: 1em;
/* you can use a premade png fade out or a dynamic gradient here*/
background: ...;
}
markup
<div class="container">
<p>
This is my long text that goes on for paragraphs and paragraphs,
far longer than the container....
</p>
<div class="fadeout"></div>
</div>
After spotting Carson Myers further comments around this question I'm making a guess that the following could work. When I stated above that the background has to be fixed - I mean that it had to be fixed in terms of background-attachment
. So if the background has been implemented in this way you can use the following 'hack' to get things to work. Bear in mind that floating absolute layers on top of content can cause usability problems.. and having many transparent layers can slow older browsers down:
jsfiddle
http://jsfiddle.net/kthPT/30
The code below is an example with an outer layer set to scroll it's content (to represent the outer page or body), and with inner "news" areas that have a limited height and fade out the rest of their content. Both uses of background: url('...')
need to filled out with the same background image path. Because the background image is 'fixed' in both locations in all the modern browsers I've tested it calculates the background to the same position. So the floating layers on top have the same graphics as the layer below.
The resulting markup is a little horrible bulky, so you could feasibly convert this to be generated by javascript on browsers that supported opacity - and possibly using any "height" of fade out. The current version supports only 20px of fade.
css
.outer {
background: url('...') repeat fixed;
height: 200px;
overflow: auto;
}
.news {
position: relative;
width: 300px;
height: 100px;
overflow: hidden;
}
.news .fadeout {
position: absolute;
bottom: 0;
width: 100%;
}
.news .fadeout .fadeline {
height: 2px;
background: url('...') repeat fixed;
}
/* a good idea to add vendor prefixed versions of opacity here */
.news .fadeout .o09 { opacity: 0.9; }
.news .fadeout .o08 { opacity: 0.8; }
.news .fadeout .o07 { opacity: 0.7; }
.news .fadeout .o06 { opacity: 0.6; }
.news .fadeout .o05 { opacity: 0.5; }
.news .fadeout .o04 { opacity: 0.4; }
.news .fadeout .o03 { opacity: 0.3; }
.news .fadeout .o02 { opacity: 0.2; }
.news .fadeout .o01 { opacity: 0.1; }
markup
<div class="outer">
<div class="news">
<h4>News</h4>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut
suscipit dui ac lacus convallis dapibus. In cursus arcu at
arcu mollis vestibulum. Morbi ac quam sed nisl vulputate
aliquam in ac velit. Curabitur ac feugiat justo. Fusce
imperdiet, arcu non dignissim vulputate, leo odio ultricies
mauris, in consectetur risus odio malesuada sapien.
Nam sagittis convallis dictum. Duis eget lectus
</p>
<div class="fadeout">
<div class="fadeline o01"></div>
<div class="fadeline o02"></div>
<div class="fadeline o03"></div>
<div class="fadeline o04"></div>
<div class="fadeline o05"></div>
<div class="fadeline o06"></div>
<div class="fadeline o07"></div>
<div class="fadeline o08"></div>
<div class="fadeline o09"></div>
<div class="fadeline o10"></div>
<div class="fadeline o10"></div>
<div class="fadeline o10"></div>
<div class="fadeline o10"></div>
</div>
</div>
<div class="news">
<h4>News</h4>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut
suscipit dui ac lacus convallis dapibus. In cursus arcu at
arcu mollis vestibulum. Morbi ac quam sed nisl vulputate
aliquam in ac velit. Curabitur ac feugiat justo. Fusce
imperdiet, arcu non dignissim vulputate, leo odio ultricies
mauris, in consectetur risus odio malesuada sapien.
Nam sagittis convallis dictum. Duis eget lectus
</p>
<div class="fadeout">
<div class="fadeline o01"></div>
<div class="fadeline o02"></div>
<div class="fadeline o03"></div>
<div class="fadeline o04"></div>
<div class="fadeline o05"></div>
<div class="fadeline o06"></div>
<div class="fadeline o07"></div>
<div class="fadeline o08"></div>
<div class="fadeline o09"></div>
<div class="fadeline o10"></div>
<div class="fadeline o10"></div>
<div class="fadeline o10"></div>
<div class="fadeline o10"></div>
</div>
</div>
<div class="news">
<h4>News</h4>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut
suscipit dui ac lacus convallis dapibus. In cursus arcu at
arcu mollis vestibulum. Morbi ac quam sed nisl vulputate
aliquam in ac velit. Curabitur ac feugiat justo. Fusce
imperdiet, arcu non dignissim vulputate, leo odio ultricies
mauris, in consectetur risus odio malesuada sapien.
Nam sagittis convallis dictum. Duis eget lectus
</p>
<div class="fadeout">
<div class="fadeline o01"></div>
<div class="fadeline o02"></div>
<div class="fadeline o03"></div>
<div class="fadeline o04"></div>
<div class="fadeline o05"></div>
<div class="fadeline o06"></div>
<div class="fadeline o07"></div>
<div class="fadeline o08"></div>
<div class="fadeline o09"></div>
<div class="fadeline o10"></div>
<div class="fadeline o10"></div>
<div class="fadeline o10"></div>
<div class="fadeline o10"></div>
</div>
</div>
</div>
Is this what you are looking for?
Take a look at my jsfiddle.
I'm not sure what you want because your description is not satisfactory. Can you make a jsfiddle of what the problem is?
There is currently no elegant one-line CSS solution that would allow you to do this across all browsers. You can either use the non-standard -webkit-mask-image
property (demo) or an SVG mask (demo). The most complete cross-browser solution that I've seen so far is from Christian Schaefer's tutorial, "CSS Masks – How To Use Masking In CSS Now".