Imran Bughio Imran Bughio - 4 months ago 14
CSS Question

input field inside popup is jumping when focused

I have a poup with input fields inside. When I use iPhone or iPad to click on any input field the layout jumps... you can see this effect in this link: https://jsbin.com/zebixifami/1

Try to tap the input fields at the bottom of the popup you will see the jerk, This jerk is much more prominent in actuall product.

Here is the editor bin url: https://jsbin.com/zebixifami/edit?html,css,output

Here is a link to the video showing this issue: https://www.youtube.com/watch?v=LvmAl-HQI8Y&feature=youtu.be

HTML:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
</div>
<div class="popup">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
</div>

</body>
</html>


CSS:

.popup {
position: fixed;
top: 50%;
left: 5%;
width: 90%;
-moz-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
-o-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
max-height: 90%;
background: #fff;
overflow: auto
}

input {
width: 90%;
margin-left: 5%;
display: block;
margin-bottom: 20px;
margin-top: 20px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}

body {
background: #000;
oveflow: hidden;
}

Answer

It turns out this is a webkit bug & there is not much we can do about it.

However I did found a work around that I find acceptable. I ended up keeping popup as a normal document flow div without absolute or fixed position while jumping between layout and popup in a way that users gets the same feel as if he is inside a popup, below is the step by step instruction of what I did:

  • When popup is triggered, save the current scroll position of layout jQuery('body').scrollTop().
  • Animate entire page out opacity: 0 (The entire layout is in one div and popup is outside of it).
  • Set layout height to 0 with overflow hidden.
  • Animate in the popup (the popup will be position static or relative)
  • Depnding on where the user is we have to jump to top of the page before revealing popup.
  • Now when closing the popup do the opposite.
  • Animate out the popup
  • Set layout height to auto
  • Scroll the layout back to previous position that we saved earlier.
  • Now we can animate layout back to opacity: 1.

This kind of step by step transition will make the users feel it's a popup but we are simply hiding layout and showing another div which resembles a popup.

Doing this means our popup is no longer position fixed & the bug wont trigger.

Demo: JSBIN & Editor

Below is the code:

<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.0.0.js"></script>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<div class="wrapper">
  <section>
    <h1>A</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <a href="#" class="js-popup-open">Click me.</a>
  </section>
  <section>
    <h1>B</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <a href="#" class="js-popup-open">Click me.</a>
  </section>
  <section>
    <h1>C</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <a href="#" class="js-popup-open">Click me.</a>
  </section>
  <section>
    <h1>D</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et ea officiis ipsam sunt, nam quam sint omnis, quisquam cum. Dignissimos pariatur porro quis sunt optio laborum, sint vero fugit unde?</p>
    <a href="#" class="js-popup-open">Click me.</a>
  </section>
</div>
<div class="popup-wrap"></div>
<div class="popup">
  <a href="#" class="js-popup-close">Close</a>
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
</div>

</body>
</html>

CSS:

body{
  background: #000;
  padding: 0;
  margin: 0;
}
.wrapper{
  background: #fff;
  margin: 0;
  padding: 20px;
}

.popup {
  position: relative;
  top: -5%;
  opacity: 0;
  left: 5%;
  width: 90%;
  max-height: 90%;
  background: #fff;
  overflow: auto;
  display: none;

  -webkit-transition: all 0.35s ease-in-out;
  -moz-transition:  all 0.35s ease-in-out;
  -o-transition:    all 0.35s ease-in-out;
  -ms-transition:   all 0.35s ease-in-out;
  transition:     all 0.35s ease-in-out;
}
input {
  width: 90%;
  margin-left: 5%;
  display: block;
  margin-bottom: 20px;
  margin-top: 20px;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
.popup-wrap{
  position: absolute;
  background: rgba(0,0,0,0.75);
  top: 0;
  left: 0;
}
.popup-on body {
  oveflow: hidden;
}
.popup-on .popup{
  display: block;
}
.popup-on .wrapper{
  overflow: hidden;
}
.popup-animate .popup{
  top: 5%;
  opacity: 1;
}

JS:

$(document).ready(function(){

  var currentScrollPosition = 0;

  // Open Popup
  $('.js-popup-open').click(function(e){
    e.preventDefault();

    // Save current popup location.
    currentScrollPosition = jQuery('body').scrollTop();

    // Fadeout layout
    $('.wrapper').animate({ 
      opacity: 0
    }, 350, function () {
      // Hide layout
      $('.wrapper').css('height', 0);

      // Show Popup
      $('body').addClass('popup-on');

      // Scroll layout to top so popup is not shown half way through.
      jQuery('html, body').animate({
        scrollTop: 0
      }, 0);

      // Animate Popup
      setTimeout(function(){
        $('body').addClass('popup-animate');
      }, 10); /* this set timeout let transition be applied even when display property was changed from display none to blcok */

    });
  });

  // Close Poup
  $('.js-popup-close').click(function(e){
    e.preventDefault();

    // Animate out the poup
    $('body').removeClass('popup-animate');

    // Wait while popup is animting to fade.
    setTimeout(function(){

      // Hide the popup
      $('body').removeClass('popup-on');

      // scroll to previous position.
      jQuery('html, body').animate({
        scrollTop: currentScrollPosition
      }, 0);

      // Layout back to normal height.
      $('.wrapper').css('height', 'auto');

      setTimeout(function(){
        $('.wrapper').animate({ 
          opacity: 1
        }, 350);
      }, 10);

    }, 360);
  });
});
Comments