In Part 1, Alex introduced our implementation of Catfish ads and demonstrated how we managed to have them appear at the bottom of the window, in all browsers, without jerky motion while scrolling.
If you missed it, go back and have a look through part 1. We found a handy way of working around Internet Explorer’s lack of support for fixed positioning of elements.
Now, we have a working Catfish ad. It’s attached to the bottom of the screen, and stays there when it is scrolled.
The problem is, it’s always there. The Catfish would be much more eye-catching if it ’slid’ into view, rather than appearing immediately. Catch your Website visitors by surprise!
Sliding The Catfish Into View
With a bit of DHTML jiggery-pokery, we can position the Catfish so that it’s just out of sight, with the top of it just below the bottom of our browser window. This is an ideal point from which to ’slide it in to view’ later.
Hint: it also gives us a chance to start pre-loading the images in the Catfish, so that when it bobs up, the images should be ready to go.
A negative bottom margin nicely tucks it away.
margin-bottom: -79px;
If using a negative margin for this purpose makes you feel a little unclean, don’t worry. When we slide the catfish into view we’ll remove that margin. So that we don’t get confronted with a gaping hole where the Catfish is going to go either, we’ll temporarily remove that blank space we added to the bottom of the body element.
/*
html {
padding:0 0 58px 0;
}
*/
Loading the document now, you’d be forgiven for thinking there is absolutely no Catfish. It’s there, but it’s just out of view. We’ve got to set up some timeouts to bring this out into the open.
I’ve created a new file called catfishdeploy.js which is quite similar to the code we use on sitepoint.com.
// Deploy the Catfish
// The Catfish should be located in an element of id 'catfish' and should be hidden
// out of view
function deploycatfish()
// initializing
{
catfish = document.getElementById('catfish');
catfishheight = 79; // total height of catfish in pixels
catfishoverlap = 21; // height of the 'overlap' portion only (semi-transparent)
catfishtimeout = setTimeout(startcatfish, 2000);
}
The last line of this function sets up a 2 second timeout, which will call startcatfish. The images in this Catfish take up about 10KB. That’s probably a little high, though it’ll suffice for demonstration purposes. Waiting for 2 seconds before showing the Catfish should give the images a bit of time to load, even on a modem connection.
In startcatfish we set up a catfishposition variable to hold the current Catfish position. setInterval can be used to shift the Catfish smoothly.
function startcatfish()
// starts the catfish sliding up
{
catfishposition = 0; // catfishposition is expressed in percentage points (out of 100)
catfishtimeout = setInterval(positioncatfish, 25);
}
Because the Catfish position is changed every 25 milliseconds or so (in the best case scenario), we don’t want to do anything too time-intensive when we change the position. We can sort out additional problems like adding space to the bottom of the html element to reserve space for the Catfish later — once it’s fully visible. For now, we’ll just alter the position of the Catfish by altering its bottom margin.
function positioncatfish()
{
catfishposition += 10;
catfish.style.marginBottom = '-' + (((100 - catfishposition) / 100) * catfishheight) + 'px';
if (catfishposition >= 100)
{
clearTimeout(catfishtimeout);
catfishtimeout = setTimeout(finishcatfish, 1);
}
}
Once the Catfish is in full view, we set a timeout to call finishcatfish. finishcatfish will tack on a bit of padding to the body element, in order to ‘reserve space’ for it. This ensures that visitors will be able to read the footer of your page without it being obscured by the Catfish. See Part 1 for information on how this was achieved.
function finishcatfish()
{
catfish.style.marginBottom = '0';
// jump the bottom of the document to give room for the catfish when scrolled right down
document.body.parentNode.style.paddingBottom = (catfishheight - catfishoverlap) +'px';
// here you could use AJAX (or similar) to log the popup hit for tracking purposes
}
The Result
Check out the result! The Catfish now sits out of sight for a little while, finally surprising us by loading when we least expect it. It looks pretty slick. It’s also very eye-catching, without being overly annoying (it doesn’t steal focus away from the rest of the page).
What Else Could We Do?
At SitePoint, we serve a range of different Catfish ads in rotation. The ads themselves are deployed via JavaScript, rather than appearing statically in our code. Information about how this can be achieved will be the subject of a future blog post!
Related posts:
- The Two Ways of Sizing Absolute Elements in CSS Most developers have used left, right, top and bottom properties...
- Geeks Just Wanna Have Fun = #songsincode Here's a little bit of coffee break fun for geeks...
- Styling the html and body Elements One of the most common ways to begin a...
- Photoshop Mobile Released Adobe have announced the release of Photoshop for iPhone and...
- Implementing Event Latency in JavaScript Craig provides some useful JavaScript code to slow down event...







So here’s a question – why put the finish code in finishcatfish() instead of in the positioncatfish end condition?
October 21st, 2005 at 1:19 am
Good question. I found that the browser delays rendering the changes until after the positioncatfish function returns. So I set a timeout to allow the browser to render the changes I made in the last positioncatfish, before I do the more time-intensive work of finishcatfish. This prevents a ‘jerk’ at the end of its motion.
October 21st, 2005 at 1:22 am
Good write up, and nice to see that it degrades gracefully when Javascript is disabled.
October 21st, 2005 at 5:41 am
I’m getting a javascript error in IE6 on this slideme example. Line 11, char 2, object does not support this property or method.
October 21st, 2005 at 7:03 am
Doesnt work for me either – IE6
October 21st, 2005 at 7:39 am
yup, I can confirm the IE bug (v6.2, Win XP SP2).
October 21st, 2005 at 7:53 am
You can fix the IE bug by changing this in catfishdeploy.js
change:
function deploycatfish() // initializing { catfish = document.getElementById('catfish'); catfishheight = 79; // total height of catfish in pixels catfishoverlap = 21; // height of the 'overlap' portion only (semi-transparent) catfishtimeout = setTimeout(startcatfish, 2000); }to:
function deploycatfish() // initializing { var catfish = document.getElementById('catfish'); catfishheight = 79; // total height of catfish in pixels catfishoverlap = 21; // height of the 'overlap' portion only (semi-transparent) catfishtimeout = setTimeout(startcatfish, 2000); }October 21st, 2005 at 8:36 am
eh , that broke the code i mozilla, instead add (in catfishdeploy.js)
var catfish;
Your code should look like this:
var catfish; function deploycatfish() // initializing { catfish = document.getElementById(’catfish’); catfishheight = 79; // total height of catfish in pixels catfishoverlap = 21; // height of the ‘overlap’ portion only (semi-transparent) catfishtimeout = setTimeout(startcatfish, 2000); }October 21st, 2005 at 10:11 am
Again… THANK YOU!!!
Please confirm the bugs – lets us know if all is good!
Look forward to the NEXT part… :)
October 21st, 2005 at 1:25 pm
I like the concept allot but i would have thought you could use the javascript library from http://script.aculo.us/ . Makes for really nice fade in/scroll up/down with only a few lines of code.
October 21st, 2005 at 6:12 pm
Dude… This just so rocks!! I am definitely looking forward to the nexy installment. However, I must agree we need to verify the IE bugs and bug fixes.
I am wondering though if something like this is also one of the fixes in IE7 but I guess we won’tknow that until a publicly available beta is released.
But like I said, all in all that was a dandy write up!
October 22nd, 2005 at 9:00 am
One other question though, Why isn’t part1 and part 2 of this article printer-firendly like almost all of the other articles on Sitepoint?
October 22nd, 2005 at 9:05 am
[...] The Catfish—Part 2 [...]
October 23rd, 2005 at 7:37 am
Thanks Pers, that was a LMB (last minute bug). It’s fixed now.
Thomas
October 23rd, 2005 at 9:54 pm
I hate your catfish ad. it is distracting to the user. poor usability in my book.
October 23rd, 2005 at 10:34 pm
Ah well, dare I say… plenty more fish in the sea.
Sojan80, basically just because it’s a blog post (or series of), rather than an article. We debated on where it should go, and it just came down to our blog format being the easiest way to get it online quickly — blogs are allowed to be a little bit raw, where articles need a bit more polish. We’re pretty pushed for time at the moment.
October 24th, 2005 at 3:12 am
Has anyone done any accessibility testing on this?
October 29th, 2005 at 12:20 pm
I’m finding that IE5 won’t scroll with the mouse wheel (MS Trackball Optical) when using this technique. Has anyone else seen this, and if so, is there a fix?
November 1st, 2005 at 3:46 pm
omnicity, to my knowledge it should be perfectly accessible — certainly more accessible than standard popups.
If JavaScript is absent it won’t show, but that has no impact on the rest of the page. If it does render, then it will just appear as content that renders with the footer.
Either way, we’re deliberately putting information that non-critical to the operation of the site in it. I’d be less confident putting navigation or other critical information in it. I certainly wouldn’t be injecting the nav via the DOM.
November 2nd, 2005 at 2:33 am
How can you make the “Catfish” a link?
November 18th, 2005 at 2:02 pm
I am also having an issue. see here
November 26th, 2005 at 2:00 pm
Anyone have an idea why the catfish doesn’t work when your using base href?
http://www.sitepoint.com/forums/showthread.php?t=331077
December 30th, 2005 at 9:43 pm
Any chance of another blog continuing with Part III: Banner Rotations/Page-Specific Catfish?
February 23rd, 2006 at 9:36 pm
Hi,
Thanks very much for sharing your code. As soon as I saw these ads on sitepoint I had to know how it was done. Thanks again.
I wonder if you could shed some more light on the problem MatthewHSE reported some time ago. I am also seeing a lag on the ability to scroll horizontally on content heavy pages. No doubt this is due to the IEHack, and I notice that it will clear up as soon as the page is fully loaded. Hardly noticeable for broadband users, but when testing our sites on 56k it can be frustrating for users to have to wait before they can scroll down to fully view content.
Has anyone found a workaround for this, or is it out of the question?
Thanks again.
March 30th, 2006 at 7:23 pm
bellybub, thanks for your comment. I was beginning to think I was alone in noticing that problem! That said, however, I’m not actually sure we’re seeing the same thing. The error I noticed was that the scroll wheel simply doesn’t work in IE5 when the Catfish is used, even if the page is fully loaded. The only way to scroll down is by using the scrollbar buttons.
I suppose it could be something funny with my mouse or perhaps my standalone install of IE5. Nobody else seems to have noticed…
March 30th, 2006 at 8:02 pm
Ahh, does sound like a different issue Matthew, the problem I see results in no scrollbars at all until content is fully loaded, and so using the scrollbar OR mousewheel is not an option for the user until it magically reappears after load is completed. The issue does not affect mozilla which will happily scroll as soon as content loading begins.
Sorry to get your hopes up mate!
P.S. Why on earth are you still using IE5? :p
March 30th, 2006 at 8:12 pm
Any kind souls or Thomas can help me look into this.
http://www2.smbedge.com/mock/catfish/
Runs fine on Firefox, crash on IE ver 6.0.2900.2180
Any one had similar experience in such bugs?
April 11th, 2006 at 10:31 am
Incase anyone would like to see the catfish in action on a non-test site: http://www.wvgazette.com/
I’ve had a couple complaints that the page freezes, no scroll, but as I read the simular situation, perhaps the issue isn’t browser but connection speed. The complaintents never mentioned if they waited for the site to fully load. It is a bit content heavy.
Anyway to fix this?
May 6th, 2006 at 1:28 am
Thank you for the very clear article!
I should note that if you want to use the addLoadEvent() function with the Catfish (or with anything else), you have to add all your load events through that function instead of through the <body onload=”…”> attribute. In Firefox 1.5.0.3 and IE 6.0.2900 for WinXP, it seems that once the page is loaded, the body attribute overwrites the load events added by addLoadEvent.
May 13th, 2006 at 1:30 am
guys, I’m intersted in a function that would hide the catfish div instead of removing it from the DOM. Has anyone done that yet? if so, could you share that with the rest of us. Thanks.
http://www.sitepoint.com/forums/showthread.php?t=413640
August 20th, 2006 at 4:51 am
Check out the result! is broken… any chance of fixing the 404?
October 17th, 2006 at 1:05 am
http://www.sitepoint.com/blogs/?p=1250
This page has a problem loading in Firefox – must “stop” it immediately on loading it in order to scroll it or click on anything. Also, as the previous poster noted, the link to the finished example at the end of the main article is broken – I get a Forbidden error.
October 21st, 2006 at 9:56 pm
the final result example link “Check out the result!” is not working
btw anyone working on this ? any forum thread discussing on the development ?
Hasn’t been exposed to php in the past the tutorial seen profounding to me
November 25th, 2006 at 4:16 am
Hello,
I am unable to see the final result the page comes up with a 403 Error:
Forbidden
You don’t have permission to access /examples/catfish-part2/slideme.php on this server.
Apache/2.0.46 (Red Hat) Server at http://www.sitepoint.com Port 80
Also I was unable to get catfish to work unless I added this code to my catfishdeploy.js page:
/* Stack up window.onload events using this function from Simon Willison – http://www.sitepoint.com/blog-post-view.php?id=171578 */
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != ‘function’) {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
function destroycatfish()
{
var catfish = document.getElementById(’catfish’);
document.body.removeChild(catfish); /* clip catfish off the tree */
document.getElementsByTagName(’html’)[0].style.padding= ‘0′; /* reset the padding at the bottom */
return false;
}
function closeme()
{
var closelink = document.getElementById(’closeme’);
closelink.onclick = destroycatfish;
}
addLoadEvent(function() {
closeme();
});
—————————-
Here’s my testing page:
http://www.kennethking.com/_private/catfish/part2/index.php
Thanks for all your help,
Kenenth
December 13th, 2006 at 8:21 am
I can’t get this to work in IE without a lot of page flickering. Anyone else have problems like that?
April 14th, 2007 at 7:17 am
is it possible to have the link disable to users who have clicked on “close me”, and only to reappear again when unique, new ip, cookie/etc.
June 23rd, 2007 at 3:37 pm
Stupid questions, but where am I doing this:
margin-bottom: -79px;
and this:
/*
2 html {
3 padding:0 0 58px 0;
4 }
5 */
In the linked css file?
I did that, it hide it but it doesn’t come into view…
Any suggestions?
July 6th, 2007 at 9:42 am
a neat little ad. good job guys.
August 27th, 2007 at 7:40 pm
Hi, Can the catfish ad be served through a ad engine such as openad’s or must be hardcoded to the site..?
September 24th, 2007 at 5:14 pm
It’s unlikely that it would be supported by default but it’s just CSS, HTML and JS, so making OpenAds use catfish units shouldn’t be super difficult.
Ours are served by a custom system, so I can’t give you a definitive answer on OpenAds, though I know other sites are now using the Catfish on a larger scale than we are.
September 24th, 2007 at 6:28 pm
“At SitePoint, we serve a range of different Catfish ads in rotation. The ads themselves are deployed via JavaScript, rather than appearing statically in our code. Information about how this can be achieved will be the subject of a future blog post!”
Please, Where that post?
October 29th, 2007 at 3:54 pm
Hi
Iam not able to hide the catfish div on pageload its visible..can u pls help me
April 28th, 2008 at 9:55 pm
hy!
i´ve the same problem like Sharathbabu.
On pageload the catfish is visible.
can anybody help us?
tanks a lot!!
May 2nd, 2008 at 12:09 am
I am having some display problems in IE. No matter how I tweak the IEhack.css file I can’t get it to work. I either have a scrollbar above the #catfish and a double scroll on the right. I’ve been able to prevent that from happening but then the image get’s stuck in the middle of the page and doesn’t scroll at all. I’m not having this problem in ff or chrome or IE6…
December 18th, 2008 at 2:07 pm
Is it me only or is everyone else who read this post waiting for Part 3 where you describe how to rotate different banners with javascript? Please take some time to post this information and don’t leave us clueless and waiting…
February 27th, 2009 at 12:59 pm