Thursday, July 8, 2010

Cross-browser Mouse Coordinates

Embarassing as it is, it took me days (weeks?) to get a javascript tooltip working. The concept was sound, it should have been easy, but I was swamped by problems like the div flickering, appearing way below the mouse, and the positioning just not working across browsers. The first problem was solved by simply making the tooltip appear a few pixels above and to the left of the mouse pointer, because I discovered displaying it with the same coordinates of the mouse will trigger onmouseover and onmouseout in an infinite loop.

The last two problems involve browser compatibility, which I solved with this bit of (javascript) code:

function getX(event) //left position
{
if(!event.pageX)
{
return event.clientX;
}
else
{
return event.pageX - (document.body.scrollLeft || document.documentElement.scrollLeft);
}
}

function getY(event) //top position
{
if(event.pageY)
{
return event.pageY - (document.body.scrollTop || document.documentElement.scrollTop);
}
else
{
return event.clientY;
}
}


What these functions do is simply get the position of the mouse (in pixels) relative to the user's window, however much the page is scrolled*. Pretty basic, I know, but I thought it might benefit somebody out there.

* Not tested extensively, but it works in Firefox, IE, Opera, and Chrome.
** I got lots of help from this compatibility table.

Tuesday, July 6, 2010

Opaque Content on Translucent Backgrounds

Sure, image backgrounds aren't recommended unless you know what you're doing, but what if you wanted a semi-transparent div that dimmed the image background a bit, but kept its content opaque? You use CSS' filter/opacity property, of course. But it turns out that sticking an opacity 1 div inside a transparent div doesn't work. I had that same problem some time ago.

At the time I found that people either recommend to use translucent PNG images or positioning tricks, both of which I didn't feel like using. So after a while of messing around with my code I came up with this fairly easy solution.




What I did there is place an empty div inside the div I want to have a translucent/semi-transparent background. It's like adding a screen or a pane of frosted glass behind the div. To make it clearer let's have a look at the html code:

<div class="content">
This text is opaque
<div class="screen"></div>
</div>


Now for the css that turns that 'screen' transparent.

.content
{
position:relative;
background:transparent;
}

.screen
{
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
z-index:-1;
background-color:white;
opacity:0.5;
filter:alpha(opacity=50);
}

What we did there is first make the content div completely without a background (background:transparent) so we can slip the 'screen' under it. We also have to set its position to something other than static.

Then, we take the screen div and absolute position it, so it doesn't touch the positions of other stuff inside our content div, and place it at the top-left. We 'spread' it to the content's full size with width and height set to 100%, and to be sure it stays under everything we set z-index to -1. Finally we give it a color background (don't worry, this'll be transparent) and set opacity to 50%.

And there we have it! It's a bit clunky, but it works.

Suggestions for improvement? Complaints? Just post a comment. :)