Remling
Remling

Reputation: 211

Prevent content jumping on position change to fixed

I am trying to make a menu with a transform 3d effect. The problem is that when you scroll down a bit before you open the menu, then open the menu, it will always jump to the top of the page instead of staying where you currently are.

Just scroll down a bit and click anywhere on the page to open the menu, you will see what I mean.

How can I prevent this from happening?

$(function() {
  $("div#container").click(function() {
    if ($("body").hasClass("animate")) {
      $("body").removeClass("animate");
      setTimeout(function() {
        $("body").removeClass("modalview");
      }, 600);
    } else {
      $("body").addClass("animate").addClass("modalview");
    }
  });
});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

div#container {
  height: 100%;
  width: 100vw;
  position: relative;
  z-index: 101;
  transition: all .6s ease-in-out;
}

div#container content {
  height: 100%;
  width: 100%;
  display: block;
}

.box {
  width: 100vw;
  height: 100vh;
}

.box:nth-child(1) {
  background: #2ecc71;
}

.box:nth-child(2) {
  background: #e74c3c;
}

.box:nth-child(3) {
  background: #3498db;
}

div#nav {
  position: fixed;
  top: 0;
  left: 0;
  padding: 5%;
  z-index: 100;
  width: 100%;
  height: 100%;
}

div#wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  left: 0px;
}

body.modalview div#wrapper {
  position: fixed;
  -webkit-perspective: 1500px;
  perspective: 1500px;
}

body.animate div#container {
  -webkit-transform: translateZ(0px) translateX(10%) rotateY(-50deg);
  transform: translateZ(0) translateX(10%) rotateY(-50deg);
}

body.modalview div#container {
  position: absolute;
  overflow: hidden;
  cursor: pointer;
  height: 100%;
  width: 100%;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

body.modalview div#container background {
  overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="wrapper">
  <div id="container">
    <content>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </content>
  </div>
  <div id="nav">
    <div id="nav-inner">
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
    </div>
  </div>
</div>

It's a bit tricky to explain so here is a Codepen link

here is the site i got the idea from: https://www.badruttspalace.com, i tried to rebuild it but i didnt quite manage to do it

Upvotes: 2

Views: 2866

Answers (2)

Pete
Pete

Reputation: 58432

I have changed this so that the content is now 100vh and handles the scrolling, this way you can animate the container and you shouldn't affect the position of the scroll.

I have also disabled the pointer events to prevent scrolling when the animation has happened.

$(function() {
  $("div#container").click(function() {
    if ($("body").hasClass("animate")) {
      $("body").removeClass("animate");
      setTimeout(function() {
        $("body").removeClass("modalview");
      }, 600);
    } else {
      $("body").addClass("animate").addClass("modalview");
    }
  });
});
body,
html {
  overflow:hidden;
}
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

div#container {
    height: 100%;   
    width: 100%;
    position: relative;
    z-index: 101;
    transition: all .6s ease-in-out;
}

div#container content {
    height: 100vh;
    width: 100%;
    display: block;
    overflow: auto;
}

.box {
    width: 100%;
    height: 100vh;
}

.box:nth-child(1) {
    background: #2ecc71;
}

.box:nth-child(2) {
    background: #e74c3c;
}

.box:nth-child(3) {
    background: #3498db;
}

div#nav {
    position: fixed;
    top: 0;
    left: 0;
    padding: 5%;
    z-index: 100;
    width: 100%;
    height: 100%;
}
#wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  left:0px;
}

body.modalview div#wrapper {
   position:fixed;
    -webkit-perspective: 1500px;
    perspective: 1500px;
}

body.animate div#container {
    -webkit-transform: translateZ(0px) translateX(10%) rotateY(-50deg);
    transform: translateZ(0) translateX(10%) rotateY(-50deg);
}

body.modalview div#container {
    position: absolute;
    overflow: hidden;
    cursor: pointer;
    height: 100%;
    width: 100%;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
}

body.modalview content {
  pointer-events: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="wrapper">
  <div id="container">
    <content>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </content>
  </div>
  <div id="nav">
    <div id="nav-inner">
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
      <div>Lorem Ipsum</div>
    </div>
  </div>
</div>

Updated codepen

Upvotes: 1

arieljuod
arieljuod

Reputation: 15838

If you remove this

body.modalview div#container {
  overflow: hidden;
}

It does not move the scroll to the top, not sure if that's the desired behavior.

Upvotes: 0

Related Questions