user1904273
user1904273

Reputation: 4764

javascript/css: Make image expand up and to left on rollover effect

I want to let users expand thumbnail to see large profile pic on mouseover. However, the rollover effect I have currently expands the table row to the size of the expanded image rather than showing the image over the surrounding text. Can anyone suggest a way to expand images on rollover without moving text around, in other words showing larger image on top of other html rather than pushing it out of way. I have tried z-index and this does not seem to work.

Here is a jsfiddle that demonstrates the problem:

http://jsfiddle.net/gLr9Q/

Here is same code as in js fiddle:

<script language="JavaScript">
  <!-- hide from non JavaScript Browsers
  image = new Array()
  image[0]= new Image(24,24)
  image[0].src = "http://womeninbiznetwork.com/wp-content/uploads/2011/07/logo-google.thumbnail.gif"
  image[1] = new Image(48,48)
  image[1].src = "https://www.google.com/intl/en_ALL/images/logos/images_logo_lg.gif"
</script>
<tr><td colspan=2>
<p align="center"> 
<a href="contactdetail.php"
  onmouseover="newPic()"
  onmouseout="oldPic()">
<img src="http://womeninbiznetwork.com/wp-content/uploads/2011/07/logo-google.thumbnail.gif"
  name="pic" 
class="rollover"  
    border=0>
</a> 
</p></td></tr>
<tr><td>Here is text</td></tr>

js

function newPic(){
    document.pic.style.left="-24px";
    document.pic.style.top="-24px";
     document.pic.src = image[1].src;
    return true;
  }

  function oldPic(){
    document.pic.src = image[0].src; 
    return true;
  }

css:

#rollover {
  display: block;
  z-index:99;
  padding: 4px;
  position:relative;
  text-align:left;
  width:48px;
  background-color:#E8E8E8;
  opacity:1.0;
  filter:alpha(opacity=100); 
}

Upvotes: 1

Views: 2562

Answers (4)

Olaf Dietsche
Olaf Dietsche

Reputation: 74018

Stolen from CSSplay - magnify, you can do this without Javascript

HTML:

<tr>
    <td colspan=2>
        <p align="center">  <a class="rollover" href="contactdetail.php">
            <img src="http://womeninbiznetwork.com/wp-content/uploads/2011/07/logo-google.thumbnail.gif" name="pic" border="0"/>
            <span><img src="http://www.google.com/intl/en_ALL/images/logos/images_logo_lg.gif"/></span>
</a> 
        </p>
    </td>
</tr>
<tr>
    <td>Here is text</td>
</tr>

CSS:

a.rollover {
    display: block;
    position: relative;
}
a.rollover span {
    position: absolute;
    left: -10000px;
}
a.rollover:hover span {
    position: absolute;
    left: 200px;
}

JSFiddle

Update:

I don't know, if this is what you have in mind, but you can position the larger image anywhere you want

CSS:

a.rollover:hover span {
    position: absolute;
    left: 120px;
    top: -20px;
}

JSFiddle

If you want to hide the lower image on hover, you can try adding opacity: 0

<img class="thumbnail" src="...">

and

a.rollover:hover .thumbnail {
    opacity: 0;
}

JSFiddle

Although, I don't know if this works on every browser.

Upvotes: 1

Paul S.
Paul S.

Reputation: 66324

A way to do this is to clone all the <img> nodes you want, put them inside <div>s and then use CSS's :hover to do the rest of the work for you. example fiddle.
My code will work for as many <img>s as you like, anywhere in the document and does not require fixed sizes of parent nodes.
You may need to modify your CSS or the class names I've chosen if other styles aren't as you expected due to the changes to HTML structure by the JavaScript (see "Resulting HTML" below).

// JavaScript
window.onload = function () { // when document has loaded, consider `window.addEventListener('load', /* code */, false);` in real world usage
    var elm = document.querySelectorAll('img.rollover'), // get all <img>s with class "rollover"
        i = elm.length, d;
    while (--i >= 0) { // put each one and a clone into a <div> where it was
        d = elm[i].parentNode.insertBefore(document.createElement('div'), elm[i]);
        d.className = 'rollover';
        elm[i].className = (' '+elm[i].className+' ') // set class'
                            .replace(/ rollover /g, ' ')
                            .slice(1, -1);
        d.appendChild(elm[i]);
        d.appendChild(elm[i].cloneNode()).className += ' rollover_big'; // I did clone here to save needing an extra variable
        elm[i].className += ' rollover_small';
    }
};

/* CSS */
div.rollover {position: relative; display: block;} /* relative to allow for abs. positioning of big image */
div.rollover img.rollover_small {width: 24px;}
div.rollover img.rollover_big { /* position over small image*/
    width: 48px;
    display: none;
    position: absolute;
    top: 0px;
}

div.rollover:hover img.rollover_small {visibility: hidden;} /* visibility to hold space*/
div.rollover:hover img.rollover_big {display: block;} /* show bigger node*/

<!-- HTML -->
<table>
    <tr>
        <td colspan=2><a href="contactdetail.php"><img src="http://womeninbiznetwork.com/wp-content/uploads/2011/07/logo-google.thumbnail.gif" class="rollover"/></a></td>
    </tr>
    <tr>
        <td>Here is text</td>
    </tr>
    <!-- etc. -->
</table>

<!-- Resulting HTML after load event -->
<table>
    <tr>
        <td colspan=2><a href="contactdetail.php">
            <div class="rollover">
                <img src="http://womeninbiznetwork.com/wp-content/uploads/2011/07/logo-google.thumbnail.gif" class="rollover_small"/>
                <img src="http://womeninbiznetwork.com/wp-content/uploads/2011/07/logo-google.thumbnail.gif" class="rollover_big"/>
            </div>
        </a></td>
    </tr>
    <tr>
        <td>Here is text</td>
    </tr>
    <!-- etc. -->
</table>

Upvotes: 1

Onur Yıldırım
Onur Yıldırım

Reputation: 33644

You don't need javascript for this. See the working demo on jsFiddle.
Do it with CSS:

td.imgCell {
    height: 40px; /* a value greater than image height + paddings */
    text-align: center;
}

img.rollover {
    display: inline-block;
    position: relative;
    padding: 4px;
    width: 24px;
    height: 24px;
    background-color:#E8E8E8;
    border: 0px none;
}

img.rollover:hover {
    position: absolute;
    width: 48px;
    height: 48px;
    margin-top: -24px;
    margin-left: -24px;
    z-index: 99;
}

Here is the modified HTML:

<table>
    <tr>
        <td class="imgCell">
            <a href="contactdetail.php">
                <img class="rollover" src="http://womeninbiznetwork.com/wp-content/uploads/2011/07/logo-google.thumbnail.gif" />
            </a> 
        </td>
    </tr>
    <tr>
        <td>Here is text</td>
    </tr>
</table>

Notice that a class for the container td is also declared and set: <td class="imgCell">

Key points:

  • The container <td> should have a fixed height.
  • The image should have absolute position when hovered.

Other Corrections / Suggestions:

  • You don't need the colspan attribute there in your HTML. The colspan attribute defines the number of columns a cell should span. You don't have to do that since you have a single <td> in each row (<tr>).
  • You don't really need the wrapping <p> tag around your anchor tag. But it's not wrong.

If you insist on using that JS code;

  • You should also include //--> right before the </script> tag since you have <!-- hide from non JavaScript Browsers in the begining.
  • You should add semicolons at the end of each javascript statement. You have none.
  • You should declare the image variable with a var, or otherwise it will be in the global scope.
  • You should initialize the array with [] instead of new Array() as tools like jsLint suggest.

Upvotes: 1

JacobEvelyn
JacobEvelyn

Reputation: 3971

You can add something like this:

#Text {
    position:absolute;
    top:48px;
}

where your text is in a block element with ID Text. Updated fiddle.

Upvotes: 1

Related Questions