Open a long page with some text and one button in the middle of page using Android Chrome browser. Scroll the page to show the button, the Android Chrome address bar will hide, Click the button to open a modal box that has text input control. After the modal box shown you click on the text input control to set focus on input control. The modal box will move up and down in the first time. The problem happens only in the first time, you need to refresh the page and scroll the page to hide Chrome address bar to show the problem again. It only happens in Android Chrome but it works fine in IOS.
Example (you need to use an android): http://demo.clubclouds.com/sandbox/modal.html
Bootstrap 3.3.5
Android OS 4.4, 5.0, 5.1
Chrome 44
Samsung S6, S5, S4, S3
The modal box will move up and down in the first time.
@billsliu So, it kinda flickers once? But it's displayed acceptably after that flicker is done?
Yes it will show correctly after flicker is done. Click on the input control, the chrome address bar show up and software keyboard show up, the modal box moves up after keyboard and address bar show, and one or two seconds later modal box moves down to its correct position. It looks like the bootstrap modal sense the container size change event and try to move up or down to justify the size change event. The problem is bootstrap modal captures two size change event (address bar and keyboard) and adjust twice, so the bootstrap modal move up and down.
This is just my guess and the problem may be able to fix.
@billsliu Could you please re-test with the Bootstrap v4 alpha release (warning: not backward-compatible; docs: http://v4-alpha.getbootstrap.com )? I suspect it'd also be affected, and we might not bother trying to fix this for v3 since it's not a showstopper and v3 is on the back burner.
bootstrap 4 has the same issue. example for bootstrap 4: http://demo.clubclouds.com/sandbox/modal4.html
I dig into bootstrap 3 javascript source code, I found modal resize event, but bootstrap only handle scrollbar width in resize event, no code related with address bar and soft keyboard change.
It is definitely a browser related issue, it may have a way to work around and improve bootstrap modal. I currently have not got a clue, I will leave the issue for a while since the behavior is acceptable even not perfect.
ios has problem too, it flicker and move dramatically and quickly. I have dirty hack for ios device. see example ios hack for model: http://demo.clubclouds.com/sandbox/modalios.html
First. Html code modal (<div class="modal" id="myModal">...</div>) must be child of body.
Second. Add dirty hack to show.bs.modal event
// bootstrap modal enhancement with input field
$('body').on('show.bs.modal', '.modal', function (e) {
// fix the problem of ios modal form with input field
var $this = $(this);
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
// Position modal absolute and bump it down to the scrollPosition
var heightModal = Math.max($('body').height(), $(window).height(), $(document).height()) + 1;
$this.css({
position: 'absolute',
paddingTop: $(window).scrollTop() + 'px',
height: heightModal + 'px'
});
// Position backdrop absolute and make it span the entire page
//
// Also dirty, but we need to tap into the backdrop after Boostrap
// positions it but before transitions finish.
//
setTimeout(function () {
$('.modal-backdrop').css({
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: heightModal + 'px'
});
}, 500);
}
});
The above code is very ugly, but it just provide some idea this problem can be fixed.
Hi @cvrebert!
You appear to have posted a live example (http://jsbin.com/xupafu/edit), which is always a good first step. However, according to Bootlint, your example has some Bootstrap usage errors, which might potentially be causing your issue:
.modal elements must have a tabindex attribute.<head> is missing X-UA-Compatible <meta> tag that disables old IE compatibility modesYou'll need to fix these errors and post a revised example before we can proceed further.
Thanks!
(_Please note that this is a fully automated comment._)
With those minor and probably-irrelevant issues fixed: http://output.jsbin.com/xupafu
On Sauce Labs, the Samsung Galaxy S4 emulator running Android 4.4 doesn't exhibit any address bar hiding effect. Neither does my physical Nexus 10 tablet running Android 5.1.1.
@twbs/team Anyone have an Android smartphone to test this on?
I can observe a slight flicker to the top and back down on my Nexus 6P running Android 6.0.1 and Chrome 49.0.2623.91.
With same version Chrome but on LG G4 I don't see any problems/flickering
@juthilo If you perform the test on http://output.jsbin.com/sidejo/quiet and then close the modal and look at the list at the bottom, what does it say?
@cvrebert
visual: 323, layout: 365
visual: 309, layout: 309
visual: 604, layout: 604
Perhaps we could try debouncing the resize event handler. And/or filing a Chrome bug.
For me it works:
Remove everything from modal-content class and paste that in modal-head..those flickers gone.
I see this hasn't been updated in a while, is this still an issue?
I ran into a similar problem with the latest bootstrap on chrome android. It seems to only happen when running as a progressive web app in full screen mode. It happens exactly as described by bill:
"Click the button to open a modal box that has text input control. After the modal box shown you click on the text input control to set focus on input control. The modal box will move up and down".
The model is positioned perfectly above the keyboard the first time, but after the re-position the model is partially obstructed under the keyboard.
I create my modal dynamically so it is always happening for me.
I finally figured how to fix this, for web apps. In the web app manifest set the "display": "standalone" (not fullscreen). The problem has to do with how the virtual keyboard interacts with the screen. This link helped me to this point: https://www.outsystems.com/forums/discussion/22410/mobile-input-on-bottom-of-screen-behind-android-keyboard/
I found the solution like
$(document).ready(function() {
var isMobile = navigator.userAgent.toLowerCase().match(/android|iphone|ipad|ipod/i);
if(isMobile ) {
$('body').addClass('mobile-platform');
}
});
//In css file add like below
body.mobile-platform.modal-open {
position: fixed;
}
It's working for me.
$('body').on('show.bs.modal', '.modal', function (e) {
// fix the problem of ios modal form with input field
var $this = $(this);
if (navigator.userAgent.match(/Android/i) && $(window).width() < 767) {
$this.find('input').blur(function () {
$('.modal-open').removeClass('fix-modal')
})
.focus(function () {
$('.modal-open').addClass('fix-modal')
});
}
});
CSS:
.fix-modal{
position: fixed;
top: 0;
Had the same problem, thanks for the answers!
Most helpful comment
For me it works:
Remove everything from modal-content class and paste that in modal-head..those flickers gone.