简体   繁体   中英

Expand div from parent div to center viewport

So I was able to expand the div from the center of viewport but now, I would like to expand the div starting for the "click me" box creating an effect/illusion that a box is coming from it growing all the way to the center viewport.

It should follow the click me box like let's say the click me box is at the top, when the user clicks on it it should be coming from the top as well then growing up to the center viewport.

Here's a jsFiddle and a sample code from the JSFiddle as well. (Note that the <p> are just to show content that will make the body have a scrollbar)

HTML

<div class="growme">test</div>
<p>adsadsad</p>
<p>adsadsad</p>
<p>adsadsad</p>
<div class="box"><h3>click me</h3></div>
<p>adsadsad</p>
<p>adsadsad</p>
<p>adsadsad</p>
<p>adsadsad</p>
<p>adsadsad</p>

CSS

.growme {
    background-color: #990000;
    height: 0;
    width: 0;
    position: fixed;
    filter: alpha(opacity=0);
    opacity: 0;
    top:0;
    left:0;
    bottom:0;
    right:0;
    margin:auto;
}
.box {
    margin: 0 auto;
    height: 200px;
    width: 300px;
    background-color: #999;
}

Jquery

$('.box').on('click', function () {
    $('body').css('overflow', 'hidden');
    $('.growme').animate({
        width: '100%',
        height: '100%',
        opacity: 1,
    }, 'normal');
});

$('.growme').on('click', function () {
    $(this).animate({
        width: 0,
        height: 0,
        opacity: 0,
    }, 'normal', function(){
        $('body').css('overflow', 'auto');
    });
});

In case you are wondering what the output would look like, I was able to find this site that does the same effect.

If what you want to do is make the .growme box grow from the center of the .box box, instead of from the center of the screen, what you need to do is to reset its position each time that you are going to open it.

How to do that? Calculate the position of the .box element within the viewport by using offset() (to obtain the position of .box within the document) and scrollTop() (to get the value of the scrollbars). In pseudocode, it would be something like this:

position = element_height + element_offset - window_scroll

Once you have that, it is really simple:

  1. Update the CSS for .growme so the box is initially in the horizontal center:

     .growme { background-color: #990000; height: 0; width: 0; position: fixed; opacity: 0; top:0; left:50%; margin:0; } 
  2. Get the target position for .growme (with the formula above):

     100 + $(this).offset().top - $(window).scrollTop() 
  3. Place .growme in the target position.

     $(".growme").css({ top: (100 + $(this).offset().top - $(window).scrollTop()) + "px"}); 
  4. Animate .growme so it goes to the top-left corner and its width and height occupy 100%.

     $('.growme').animate({ width: '100%', height: '100%', left:0, top:0, opacity: 1, }, 'normal'); 

And that should do the trick (for the shrinking process, you'd need to calculate the target top for the animation, see the code below). Here is the code (I commented the overflow:hidden part to avoid the resize of the viewport when the scrollbars disappear):

 $('.box').on('click', function () { // set the .growme div at the center of the .box div $(".growme").css({ top: (100 + $(this).offset().top - $(window).scrollTop()) + "px"}); //$('body').css('overflow', 'hidden'); $('.growme').animate({ width: '100%', height: '100%', left:0, top:0, opacity: 1, }, 'normal'); }); $('.growme').on('click', function () { // calculate the target goal for the top position var goal = (100 + $(".box").offset().top - $(window).scrollTop()) + "px"; $(this).animate({ width: 0, height: 0, left:"50%", top: goal, opacity: 0, }, 'normal', function(){ //$('body').css('overflow', 'auto'); }); }); 
 .growme { background-color: #990000; height: 0; width: 0; position: fixed; opacity: 0; top:0; left:50%; margin:0; } .box { margin: 0 auto; height: 200px; width: 300px; background-color: #999; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div class="growme">test</div> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <div class="box"><h3>click me</h3></div> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> 

This solution works perfectly to start growing the .growme div from the center of the .box ... But there's a catch: the growth is not proportional to the .box div, but to the viewport proportion, that may not be the same as the .box (3x2).

One possible solution for this is to set .growme so it "mimics" the position and size of .box . It will still not grow proportionally to its size, but it will almost look like it:

 $('.box').on('click', function () { $(".growme").css({ top: ($(this).offset().top - $(window).scrollTop()) + "px", left: "calc(50% - 150px)", width:300, height:200, zIndex:2 }); //$('body').css('overflow', 'hidden'); $('.growme').animate({ width: '100%', height: '100%', left:0, top:0, opacity: 1, }, 'normal'); }); $('.growme').on('click', function () { var goaltop = ($(".box").offset().top - $(window).scrollTop()) + "px"; var goalleft = window.innerWidth/2 - 150; $(this).animate({ width: 300, height: 200, left:goalleft, top: goaltop, opacity: 0, }, 'normal', function(){ //$('body').css('overflow', 'auto'); $(this).css("z-index",-1) }); }); 
 .growme { background-color: #990000; height: 0; width: 0; position: fixed; opacity: 0; top:50%; left:50%; margin:0; z-index:-1; } .box { margin: 0 auto; height: 200px; width: 300px; background-color: #999; z-index:1; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div class="growme">test</div> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <div class="box"><h3>click me</h3></div> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> 

If you still want to make it grow proportionally, you could check this question and the selected answer , but notice that it would require additional calculations in your case (to determine if the viewport is in portrait/landscape mode and perform the effect accordingly).

Well in theory it should work by using the CSS transition and changing the box's width and height, then centring it and making the div fixed to keep it in the middle of the page... here is my try tho it's not perfect

have a look at the jsFiddle

 $('.box').on('click', function () { $('body').toggleClass('nooverflow'); $(this).toggleClass('grow'); }); 
 .nooverflow {overflow:hidden;} .box { margin: 0 auto; height: 200px; width: 300px; position:absolute; left:0; right:0; background-color: #999; transition:0.3s; } .box.grow { width:100%; height:100%; background:red; top:50%; transform: translateY(-50%); position:fixed; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <div class="box"><h3>click me</h3></div> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> <p>adsadsad</p> 

Some points to consider:

  • no smooth transition from position:absolute to position:fixed
  • box has absolute positioning, make sure that doesn't break your layout, you might want to add a placeholder div for space preservation
  • add cross-browser where necessary (transition, transform, opacity etc)

Edit: I just noticed that when the box is above the fold, the transition is better, but when it is below the fold (viewport height) the box goes to the center instantly then grows

I've managed to accomplish what you wanted to do, however I must note that there may be a trade off involving the positioning of the box itself. In my solution, the box has a fixed position as default and therefore may succumb to some positioning difficulties.

In retrospect of this, here is the code that I have implemented which shows an initial box with a set width and height expanding outward into the entire page on click and back to it's default size and location upon a second click.

Here is the HTML code that I have written.

<body>
    <div id="box"></div>
</body>

Here is the CSS code that I have written.

#box {
    position: fixed;
    width: 300px;
    height: 200px;
    left: 50%;
    margin-left: -150px;
    background-color: #999;
}

Here is the JavaScript code that I have written, it does most of the hard work so I've commented it liberally.

// On document loaded
$(document).ready(function () {
  // Box starts not expanded
  var expanded = false;
  // On box click
  $('#box').on('click', function () {
    // If the box is not expanded
    if (!expanded) {
      // Animate the box
      $(this).animate({
        // Remove horizontal centering
        // This gives appearance of outward expansion
        left: '0',
        // Quotes on 'margin-left' for name errors
        'margin-left': '0',
        // Expand box to full page size
        width: '100%',
        height: '100%'
      });
      // Box is now expanded
      expanded = true;
    }
    // If the box is expanded
    else {
      // Change box to default position
      // Animate the box
      $(this).animate({
        // Restore horizontal centering
        // This gives appearance of inward shrinking
        left: '50%',
        // Quotes on 'margin-left' for name errors
        'margin-left': '-150px',
        // Expand box to normal size
        width: '300px',
        height: '200px'
      });
      // Box is now not expanded
      expanded = false;
    }
  });
});

And here is a JSFiddle I have created to show it working in action.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM