24

I am looking for a jQuery plugin to expand div elements so as to reveal their overflow (if any) on hover. Illustration:

enter image description here

The plugin should work on relatively positioned div's (which I guess implies that you create a copy of the div, set its positioning to absolute, then figure out where to place it).

Is there such a plugin already available out there?

Community
  • 1
  • 1
Max
  • 12,794
  • 30
  • 90
  • 142
  • What's the content? Images and/or text/more divs with unpredictable rendering? Is there a fixed aspect ratio? There's not enough information... – Jan Aug 21 '12 at 14:31

5 Answers5

28

You don't need a plugin. Just add proper css and use jQuery animate:

$div
.on('mouseenter', function(){
    $(this).animate({ margin: -10, width: "+=20", height: "+=20" });
})
.on('mouseleave', function(){
    $(this).animate({ margin: 0, width: "-=20", height: "-=20" });
})​

demo here

Dziad Borowy
  • 12,368
  • 4
  • 41
  • 53
  • 2
    This should be the prefered answer IMHO, for such a lean code. – Christian Bonato Jun 03 '14 at 20:25
  • @tborychowski awesome elegant timeless code! +1 upvote for this solution and i agree with the two comments (also upvoted those). Now I am trying to convert your solution from table to table-less (and even simpler, cleaner) html element version but I am stuck: http://jsfiddle.net/c15bpk30/ Can you please have a look and see what I have overlooked in this conversion? Thanks! – Sam Sep 15 '17 at 12:25
  • here is: http://jsfiddle.net/c15bpk30/1/ because you used custom html tags, they are not `display: block` by default. So you just need to set that on your `project` tag and it should work. Moreover, this should not need any js now, just pure css transitions :-) – Dziad Borowy Sep 15 '17 at 19:36
25

The images are missing here... but here is how I pulled this off a few years ago. The basic theory is that all of the images/div's whatever are absolute, inside of their own relative area. I then animate the left & top position both -negatively. This makes them protrude above the surrounding boxes and look like they are popping out. (Of course you also need to make sure the z-index of this one is higher than the ones around it).

jsFiddle DEMO

$(".img a img").hover(function() {
    $(this).closest(".img").css("z-index", 1);

    // this is where the popping out effect happens
    $(this).animate({ height: "200", width: "200", left: "-=55", top: "-=55" }, "fast");

}, function() {
    $(this).closest(".img").css("z-index", 0);
    $(this).animate({ height: "90", width: "90", left: "+=55", top: "+=55" }, "fast");
});​

The styles I have for these two things are:

.img { 
   position:relative; 
   z-index:0px;  
}

.img a img { 
   position:absolute;
   border:1px #1b346c solid; 
   background:#f1f1f1; 
   width:90px; 
   height:90px; 
}
Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
Mark Pieszak - Trilon.io
  • 61,391
  • 14
  • 82
  • 96
  • Very nice `mcpDESIGNS`. I have just added `.stop(true,true)` before animate as it cancels the animation of previous elements and improves the visual effect in my opinion: http://jsfiddle.net/tdsNF/2/ – Max Aug 21 '12 at 15:33
  • Ah yeah there's definitely some small improvements that could be made, did this about 2 years ago! Took me a while to figure out at the time, hope my sweat and tears were worth it :P haha – Mark Pieszak - Trilon.io Aug 21 '12 at 15:43
  • ... why are you effectively re-inventing the jQuery UI effect "scale"? – specializt Oct 10 '14 at 12:59
  • @specializt Scale wouldn't work in the manner needed for this demo to be done. – Mark Pieszak - Trilon.io Oct 14 '14 at 17:39
  • @MarkPieszak great answer! but is there any possibilty to make it by .on()? for dynamically created elements. thanks – jmeinlschmidt Apr 14 '16 at 18:21
  • Yes of course @the_ousek just do the dynamic on object syntax. `$(document).on({ 'mouseover': function () { }, 'mouseout': function () { } }, '.your-selector');` voila =) those 2 functions being basically what hover and the other is. This code is very old – Mark Pieszak - Trilon.io Apr 14 '16 at 18:24
  • @MarkPieszak thanks for answer, man! I did the same, as you wrote. but there was still a problem with first handler. the animation was launching again and again. found solution. use mouseenter instead of mouseover. may I post new answer with thanks to you? – jmeinlschmidt Apr 14 '16 at 18:35
  • Sure go for it and ahh yes thats the right one. I'm on a phone – Mark Pieszak - Trilon.io Apr 14 '16 at 18:37
1

thanks to @MarkPieszak. For dynamically created elements use

$(document).on({
  mouseenter: function () {
    $(this).animate({ height: "200", width: "200", left: "-=55", top: "-=55" }, "fast");
  },
  mouseleave: function () {
    $(this).animate({ height: "90", width: "90", left: "+=55", top: "+=55" }, "fast");
  }    
}, '.img a img');

.hover() does work only on static elements. more here

Community
  • 1
  • 1
jmeinlschmidt
  • 1,446
  • 2
  • 14
  • 33
0

You can actually do this entirely with css, this is a snipet from a website of mine, im entirly too lazy to edit it, but you get the idea:

<ul class="hover">
  <li style="margin-top:40px;"">
   <a href=""><img src="images/Home/Home.jpg" alt="home" style="width:130px; height:100px;"/>
   <img src="images/Home/Home.jpg" alt="home" class="preview" style="width:180px; height:150px;"/></a>
  </li>
  <li style="margin-left:55px; margin-top:-20px;">
   <a href=""><img src="images/About/About.jpg" alt="About The Author" style="width:200px; height:200px;"/>
   <img src="images/About/About.jpg" alt="About The Author" class="preview" style="width:250px; height:250px;"/></a>
  </li>
</ul>

css:

/* begin hover */

.hover{
cursor: default;
list-style: none;
}

.hover a .preview{
display: none;
}

.hover a:hover .preview{
display: block;
position: absolute;
top: -33px;
left: -45px;
z-index: 1;
}

.hover img{
background: white;
border-color: black;
border-style: solid;
border-width: 4px;
color: inherit;
padding: 2px;
vertical-align: top;
-moz-border-radius: 15px;
border-radius: 15px;
}

.hover li{
background: black;
border-color: black;
border-style: solid;
border-width: 1px;
color: inherit;
display: block;
float: left;
margin: 3px;
padding: 5px;
position: relative;
}

.hover .preview{
border-color:black;
border-width:8px;
border-stle:solid;
}

li{
-moz-border-radius: 15px;
border-radius: 15px;
}

there are some not needed styles in there but again, you get the idea. basically youre just showing one image on top of the original, on hover

Nick
  • 171
  • 10
0

If it is text, it is a little more complicated...

I use it like this:

$('.floating').mouseenter(function(){
  const $this = $(this);
  const dimension = $this.data('dimension');
  const ratioEnlarged = 2;

  const tempElement = $this.clone();
  tempElement.appendTo('body');
  tempElement.css({
    width: dimension.width,
    height: dimension.height
  });

  if(tempElement.is(':offscreen')){
    // Change this to animate if you want it animated.
    $this.css({
      'margin-left': -dimension.width * ratioEnlarged/2,
      'margin-top': -dimension.height * ratioEnlarged/4,
      'font-size': ratioEnlarged + 'em',
      width: dimension.width * ratioEnlarged,
      height: dimension.height * ratioEnlarged
    });
  } else {
    $this.css({
      'margin-left': -dimension.width * ratioEnlarged/4,
      'margin-top': -dimension.height * ratioEnlarged/4,
      'font-size': ratioEnlarged + 'em',
      width: dimension.width * ratioEnlarged,
      height: dimension.height * ratioEnlarged
    });
  }

  tempElement.remove();
});

$('.floating').mouseleave(function(event) {
  const $this = $(this);
  const dimension = $this.data('dimension');

  if(!$this.hasClass('context-menu-active')){
    $this.css({
      margin: 0,
      'font-size': '1em',
      width: dimension.width,
      height: dimension.height
    });
  }
});
Polv
  • 1,918
  • 1
  • 20
  • 31