Version 1.3 - June 7, 2004
Version 1.2 - January 10, 2004
Version 1.1 - December 29, 2003
Version 1.0 - November 17, 2003

Vote for this script!

Cross-browser BlendTrans Filter JavaScript

Introduction

You've probably seen it somewhere, a cool looking fade in/out effect. It is done with some JavaScript and the filter CSS attribute which only works in the latest versions of MSIE.

But what if you want some more control? Or want to make it work in Mozilla? This script will do just that. If you want to, you can modify it to do even more.

What you can find here

You can use this script without having any knowledge about JavaScript, just copy the script, make the links and assign an ID attribute to an element the element that you want to make fade in/out.

However, if you want to know more about JavaScript and how it is done then you can find all the explanation you want here. If you find this page useful, or have any comments to it; leave a message on the bottom. If your comments make any sense I will update this page.

This page contains examples of:

Continuous blending list of images

All the examples on this page requires your visitors to click somewhere before the blending starts and then stops again, but if you want to let a number of images blend together, check out the blendimages.js demo page with a modified version of the script that does just that!

Show me what it does!


Hide - Show

Click on a link above to make the image disappear and re-appear by gradually fading in/out. It uses CSS transparency, in CSS you can set the transparency in different ways. To ensure that it works on most browsers we use all three.

How does it work? Let's take a look at the code:

<a href="javascript:opacity('digicam', 100, 0, 500)">Hide</a>

It's nothing more than a standard link that calls a JavaScript function named opacity with a few parameters.

With these parameters you can make an image semi-transparent, did you know, that you are not limited to images either? You can do the same thing with text, or any other tag in HTML, as long as it has got an ID attribute.

MSIE warning

This trick however doesn't work with MSIE all the time. For example, it won't work unless it has a specified width and/or height. Yes, that's weird. MSIE sucks. Normal browsers like Mozilla will do it right.


This <div> has a can be made transparent in MSIE, it has a specified width of 300px.
0% - 50% - 100%

This <div> has no specified width, transparency doesn't work in MSIE.
0% - 50% - 100%

Mozilla warning

No browser is perfect, Mozilla (latest version at the time of writing is 1.6) has a few bugs too.

The first bug is rather obvious, when fading in there is a flickering just before the transition finishes. This is because the semi-transparant image is converted to a fully visible one. You can prevent this from happening bij making the image only 99% visible (-moz-opacity: 0.99).

Update - June 7, 2004: The flickering bug seems to be fixed in Mozilla Suite 1.7! This version also supports opacity: without the -moz- prefix. This means that newer versions of FireFox will also soon be upgraded.

Also, when you have an onmouseover event attached to an tag that is not fully visible (anything lower than -moz-opacity: 1.0) it won't work on certain tags like <table> or <td>.

onmouseover

If you are only using the onmouseover on a single cell you can place a <div> with the onmouseover attribute inside of it.

If you need to do it on an entire table there is another trick. Mozilla enables you to apply a style to any element once the mouse "hovers" over it using #ElementId:hover, in MSIE this only works with links like this: a:hover.

JavaScript fun

OK, here is the real work being done. This JavaScript has two separate functions. The first one, opacity() is called first, it sets the timer and speed.

Then the if() looks whether opacStart is larger then opacEnd, if so, the Opacity will go backwards, else, it will go forward.

setTimeOut() will cause a short delay before calling changeOpac() so that we can actually see the fading effect.

The function changeOpac() does nothing more than setting the 3 different opacity styles for the appropriate element. Notice that you can't use dashes (-) in style names in JavaScript, instead you must use a CAPITAL letter. In this example you can see changing -moz-opacity changing into MozOpacity, the same thing applies to all styles that contain dashes.

function opacity(id, opacStart, opacEnd, millisec) {
    
//speed for each frame
    
var speed = Math.round(millisec / 100);
    var
timer = 0;

    
//determine the direction for the blending, if start and end are the same nothing happens
    
if(opacStart > opacEnd) {
        for(
i = opacStart; i >= opacEnd; i--) {
            
setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
            
timer++;
        }
    } else if(
opacStart < opacEnd) {
        for(
i = opacStart; i <= opacEnd; i++)
            {
            
setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
            
timer++;
        }
    }
}

//change the opacity for different browsers
function changeOpac(opacity, id) {
    var
object = document.getElementById(id).style;
    
object.opacity = (opacity / 100);
    
object.MozOpacity = (opacity / 100);
    
object.KhtmlOpacity = (opacity / 100);
    
object.filter = "alpha(opacity=" + opacity + ")";
}

Fade in/out with only one link

There is more that can be done! What about a single link to hide and show an element?


hide/show

<a href="javascript:shiftOpacity('digicam2', 1000)">show/hide</a>

It's easy! With only a tiny bit of JavaScript! We'll make another function named shiftOpacity(). It only requires two parameters:

This function does nothing more than checking whether the element is transparent and then calls the function opacity() to do the transition. This is what it looks like:

function shiftOpacity(id, millisec) {
    
//if an element is invisible, make it visible, else make it ivisible
    
if(document.getElementById(id).style.opacity == 0) {
        
opacity(id, 0, 100, millisec);
    } else {
        
opacity(id, 100, 0, millisec);
    }
}

Fading one image into another

I love this effect, it's perfect for websites with photo galleries. And now you don't even need MSIE anymore! Here is an example, click on a text link to make the image fade into another.

If you use this script directly on your page you will notice that the first time you click on the link the images don't really fade all that good, that's because they need to be downloaded first. This can be fixed by preloading them first. There are various ways of doing this, but it basically means you have to put the image somewhere on the page and make it invisible (it can be done by CSS or Javascript). Once you have done that the image is stored in the browsers cache and doesn't need to be downloaded anymore. On this page it has been done with an <div> that has it's CSS display: property set to none.

Is that cool or what? It does require some extra HTML & CSS. Here it is:

<div style="background-image: url(media/texts/photos_about/02aft.jpg); background-repeat: no-repeat; width: 200px; height: 150px;" id="blenddiv">

    <img src="media/texts/photos_about/02aft.jpg" style="width: 200px; height: 150px; border: 0 none; filter: alpha(opacity=0); -moz-opacity: 0; opacity: 0;" id="blendimage" alt="" />

</div>

This piece of code creates a <div> with a single background image. Inside of it is the same image, it's 100% transparent so that you can't see it. Both the image and <div> have an id.

<a href="javascript:blendimage('blenddiv','blendimage', 'media/texts/photos_about/03aft.jpg',200)">Image 1</a>

Then there is the code for calling the JavaScript function blendimage(). There are 4 parameters this time

And then, of course there is the JavaScript:

function blendimage(divid, imageid, imagefile, millisec) {
    var
speed = Math.round(millisec / 100);
    var
timer = 0;
    
    
//set the current image as background
    
document.getElementById(divid).style.backgroundImage = "url(" + document.getElementById(imageid).src + ")";
    
    
//make image transparent
    
changeOpac(0, imageid);
    
    
//make new image
    
document.getElementById(imageid).src = imagefile;

    
//fade in image
    
for(i = 0; i <= 100; i++) {
        
setTimeout("changeOpac(" + i + ",'" + imageid + "')",(timer * speed));
        
timer++;
    }
}

When a link is clicked, first the speed and timer are set. The old image, that is 100% visible is set as the <div>'s background.

To prevent a flickering the image is made 0% visible again, then it's replaced by the new image.

The for loop runs and makes the new image fade in from 0% to 100% visible.

Getting the opacity, smooth fading: no matter when you click!

When working with multiple opacities you might notice that you cannot always know the starting opacity when writing the page. To get arround this I created the function currentOpac(), it simply retrieves the current opacity of an element and then fades from that. Try clicking on any percentage, the image will seamlessly fade to it.

opacity DEMO image
0% - 20% - 40% - 60% - 80% - 100%

Each link calls the function currentOpac() like this:

<a href="javascript:currentOpac('digicam3', 60, 300)">fade to 60%</a>

The arguments are are used for the following:

This is what the JavaScript code looks like:

function currentOpac(id, opacEnd, millisec) {
    
//standard opacity is 100
    
var currentOpac = 100;
    
    
//if the element has an opacity set, get it
    
if(document.getElementById(id).style.opacity < 100) {
        
currentOpac = document.getElementById(id).style.opacity * 100;
    }

    
//call for the function that changes the opacity
    
opacity(id, currentOpac, opacEnd, millisec)
}

Download the script


Des Des on the web
March 17, 2004 @ 10:48 AM

I wanted to use an image transition for my photo gallery and while revealTrans and blendTrans filters were available for IE and no equivalent filter was available for
Mozilla/Netscape until I came across your site. And found your code which was an affective use of setting the opacity in CSS. I used the following code with your code to ensure only one pass of the transition occurred if the user repeatedly retriggered it.

var fade_started=0;
function fadeTransStart(id1, id2, t1)
{
if(fade_started==0)
{
fadeTrans(id1, id2, t1);
}
}
function fadeTrans(id1, id2, t1)
{
if(fade_started==0)
{
fade_started=1;
opacity(id1,100,0,t1);
setTimeout("fadeTrans('"+id1+"', '"+id2+"', "+t1+")",t1);
}
else
{
document.getElementById(id1).src = document.getElementById(id2).src;
opacity(id1, 0, 100, t1);
setTimeout("fadeTransComplete()",t1);
}
}
function fadeTransComplete()
{
fade_started=0;
}

if you use 2 image elements with id1 and id2 one shown and one hidden you can load the next image into the hidden image element while the user is viewing the shown image you solve the problem with preloading.

Have a look at http:/www.bluegroper.com/valiant.htm

Cheers
Des

kotb kotb on the web
July 4, 2004 @ 12:15 AM

Im french, hard to understand...But ! It seems you did a really good work like a professionnal. Thanks to help webmaster community !

Igor Murashkin
July 19, 2004 @ 3:41 AM

I must say this is a very clean script, I've been writing PHP for years but I only recently started to delve into JavaScript. Anyways, I must say it's written very well, and because of the tidiness it's been very easy to explain to my friend who does the web designing portion of website creationsSmile. Keep up the good work!

August 4, 2004 @ 12:14 AM

It's a great script!.... but (there is always a but ehWink ) ......do you know of any way to make these effects work in Opera browser? If you do could you please give me a clue.... please? TIA

September 7, 2004 @ 5:57 AM

How can you make your script fade in and out constantly? If you want an example of this visit thesmartass.info
in internet explorer

cyrano
November 1, 2004 @ 6:43 PM

Is it possible to do the same effects with other object than images? I'd like to know how to make that effect with sub-menu of a dynamic menu for example. Somebody can help me?

November 26, 2004 @ 1:51 PM

Very nice! ..Smile .. But is there a "cross platform" script (like this) that works with "Opera" also?Eek!

November 28, 2004 @ 1:05 PM

Thanks for the excellent tutorial... i used your code here in combination with some other code to generate an expandable cross platform slide show with cross fade... here's the code if you are interested...
Thanks for your good work!

function call:
<script language="JavaScript">RunSlideShow("divid","imageid","images/1.jpg;images/2.jpg;images/3.jpg;images/4.jpg;",3);</script>

functions:
//www.cryer.co.uk © 2004 and www.brainerror.net ver 1.3 © June 7,2004
//were reference for the following Javascript slide show code
function changeOpac(opacity, id)
{
var object = document.getElementById(id).style;
object.opacity = (opacity / 100);
object.MozOpacity = (opacity / 100);
object.KhtmlOpacity = (opacity / 100);
object.filter = "alpha(opacity=" + opacity + ")";
}

function blendimage(divid, imageid, imagefile, millisec)
{
var speed = Math.round(millisec / 10);
var timer = 0;

//set the current image as background
document.getElementById(divid).style.backgroundImage = "url(" + document.getElementById(imageid).src + ")";

//make image transparent
changeOpac(0, imageid);

//make new image
document.getElementById(imageid).src = imagefile;

//fade in image
for(i = 0; i <= 100; i++)
{
setTimeout("changeOpac(" + i + ",'" + imageid + "')",(timer * speed));
timer++;
}
}

var slideCache = new Array();
function RunSlideShow(divid,imageid,imageFiles,displaySecs)
{
var imageSeparator = imageFiles.indexOf(";");
var nextImage = imageFiles.substring(0,imageSeparator);

changeOpac(0, imageid);
blendimage(divid,imageid,nextImage,100);

var futureImages= imageFiles.substring(imageSeparator+1,imageFiles.length)+ ';' + nextImage;
setTimeout("RunSlideShow('"+divid+"','"+imageid+"','"+futureImages+"',"+displaySecs+")",displaySecs*1000);

// Cache the next image to improve performance.
imageSeparator = futureImages.indexOf(";");
nextImage = futureImages.substring(0,imageSeparator);
if (slideCache[nextImage] == null)
{
slideCache[nextImage] = new Image;
slideCache[nextImage].src = nextImage;
}
}

March 10, 2005 @ 2:34 PM

This is great stuff. But one always wants more! Is it possible to create a slide show where specific image file names are not specified, but rather every image in a specified directory is displayed, one at a time?

ponchy ponchy on the web
March 30, 2005 @ 3:10 AM

thks man giving i ll use ur script right now... thx!!!

Wanderer
April 12, 2005 @ 10:36 AM

Very cool script. Clean and simple...Love

Jakob Stoeck Jakob Stoeck on the web
April 16, 2005 @ 7:58 PM

That's nice. Didn't know that something like this works across the major browser.

It works not just for images like someone mentioned here before. I use it to fade in <h1>'s. Unfortunately the browser first displays them fully, then nothing and then begins to fade them in, but you can avoid this if you set h1 to opacity:0 in your Stylesheet.

Here's the code I use:

--the main file--
<body onload="opacity('heading', 0, 100, 500)">
...
<h1 id="heading">...</h1>

--the stylesheet--
h1 { /* avoids flickering at the beginning */
filter: alpha(opacity=0);
-moz-opacity: 0;
opacity: 0;
}

One Downside is, if there's no JS-Support, you can't see the <h1>, well.. nobody's perfect.

P.S.: You don't need -khtml-opacity: 0.5; for Safari on OS X. It uses opacity: 0.5.

Jakob Jakob on the web
April 16, 2005 @ 8:10 PM

Ha! Just solved the problem from above, where when there's no JS, there's no visible header:

Just enter
<noscript><style type="text/css">h1 {
filter: alpha(opacity=100);
-moz-opacity: 100;
opacity: 100;
}
</style></noscript>

in your file and everything is cool.
Of course there is a snag to it: It doesn't validate because <style> is a don't do in <noscript> tags.. well .. who cares?

zblofu
April 19, 2005 @ 2:28 AM

Hi-- Thanks for all the work on this cool script. Very Cool!

Is it possible to combine the functions of this script with one that changes inline images?

to combine it with something like:
<script>
function changeImage(filename)
{
document.mainimage.src = filename;
}

</script>

<body>
<a href="java script:changeImage('myimage.jpg')">

<body>

What I am thinking is having a gallery where the user clicks thumbnails and the full size inline images fades in, is this possible?

thanks

April 20, 2005 @ 5:16 AM

Excellent script and works fine in this form when clicking a link to fade the image. I wonder if there is any way to make images fade-in when the body loads?Smile

May 2, 2005 @ 10:32 PM

What if I want to get rid of the space, when the img is hidden? I tried to set the style to:

document.getElementById(id).style.display = "none";

However the image disappears and doesnt really show the effect then.

Can you suggest a solution?

Thanks

May 8, 2005 @ 4:13 PM

How would you get this script to work on a table background image? because the id relates the the entire table cell not just the background image and therefore everything gets hidden.

also how could it be set to work on a timer, not a button.

Thanks for your time.
Mark

Fred
May 8, 2005 @ 11:03 PM

hey!

just wanted to say thanks for the script, used it for the menu for my portfolio. i have an image in one frame and a menu in another. the idea is that another image fades in when one onmouseovers a menu item and fades back to the previous one on onmouseout. works like a charm.

only thing, found that in mozilla the previous image likes to give off a short flash just before the fading is complete. don't know if firefox is slower in changing between the bgimage and the front image, but thought you might wanna know.

thanks again for a great script!

June 2, 2005 @ 7:06 AM

To make this a fully accessible/standards compliant script one needs to set up a function that hides all elements of a certain name...that way if the user has no java script, the items arent hidden from view and the content is accessible.

I suck at java script so i have no idea how to do this...but this would make it a "safe" crossbrowser, accessible script.

June 2, 2005 @ 7:43 PM

Good News!

I Added a fuynction that works to set initial elements to a certain opacity, so that if someone has java script disabled...they can still access the site without fades etc.

It is set up so that whatever tag you assign a class of hide i.e.

<div class="hide"></div>

It will set the opacity variables to a given number, in this case xero.

Now it is truly accessible!

onload = function hide() {
var e, i = 0;
while (e = document.getElementsByTagName ('*')[i++]) {

if (/bhideb/.test (e.className)) {
e.style.opacity = 0;
e.style.MozOpacity = 0;
e.style.KhtmlOpacity = 0;
e.style.filter = "alpha(0)";
}
}
}

jsKid (@ forums.devshed.com/f115/s.html)
June 16, 2005 @ 7:48 PM

Well... I found your script through a link provided on a forum; I can't say anything else other than "Great Job!"

The best fade script I've "ever" seen--honestly, putting java script.internet.com and others to shame (sorry dynamicdrive.com and dhtml.com, etc)

...

thejman
August 13, 2005 @ 6:36 PM

Hey dude, i noticed in Firefox that your fades flicker (when fading in) at the end. You can fix this by doing the following (saw this on a blog):

div.style.opacity = opacity/101;

Don't use opacity/100! For some reason if you go from 99 to 100 in firefox you flicker. You want it to get to .999999 but not 1.0.

And BTW dude... awesome site!

SU SU on the web
November 21, 2005 @ 6:56 AM

Great script. And while I agree that most of Scriptaculous is overkill, the event queue is extremely valuable. <a href="http://couloir.org/js_slideshow/">Here's a slideshow</a> I put together using Prototype and Scriptaculous. It may be a bit buggy on IE/Windows -- haven't had a chance to test it there this weekend.

rdc
February 12, 2006 @ 7:16 PM

Awesome script. Thanks for making it public!

February 16, 2006 @ 9:38 AM

This script works great!Grin

Still I found an error in IE6. After crossfading images there seems to be some number of pixels which still are transparent. (The pixels are pixels from the first image before crossfading)

The problem is solved when clicking the same link to crossfade again. Is there a solution?
FireFox and K-Meleon are working correctly.

I understand it is not easy to recreate the problem. Is it possible to releod the image after crossfading? Or maybe to reset the Alpha?

Thanks!

February 16, 2006 @ 4:24 PM

The problem could be reproduced when the next color is used: #02050A

For example: Just take an image and draw (using PhotoShop) lines using the color #02050A. Run the script using the new drawn image.

You'll see the problem.

Rui
February 20, 2006 @ 2:45 PM

Thanks for the excellent script!
I grabbed Shom's code and tried to make a slideshow but the transitions look really, really bad where the images have different sizes.

So, I tried to make some adjustments so that divid *and* imageid alpha are changed at the same time. Here's the code I've changed:

function changeOpac(opacity, id, id2)
{
var object = document.getElementById(id).style;
object.opacity = (opacity / 101);
object.MozOpacity = (opacity / 101);
object.KhtmlOpacity = (opacity / 100);
object.filter = "alpha(opacity=" + opacity + ")";

if (id2) {
opacity2=opacity

object = document.getElementById(id2).style;
object.opacity = (opacity2 / 101);
object.MozOpacity = (opacity2 / 101);
object.KhtmlOpacity = (opacity2 / 100);
object.filter = "alpha(opacity=" + opacity2 + ")";
}
}

in blendimage:
//fade in image
for(i = 0; i <= 100; i++)
{
setTimeout("changeOpac(" + i + ",'" + imageid + "','" + divid + "')",(timer * speed));
timer++;
}
}

Unfortunately, this doesn't work... maybe a <img> src doesn't support alpha? Anyone?

Rui
February 20, 2006 @ 2:49 PM

Ops... in the last comment
opacity2=opacity
should be:
opacity2=100-opacity
Still doesn't work, though :-|

February 25, 2006 @ 3:09 AM

Love this script, Just trying to use it to fade in a div(not just an image),So it's like show/hide of layers but with this cool fade effect.
Is this possible? Anyone doing it?

Comments are disabled until furter notice because of huge amounts of spam being placed here.