web-dev-qa-db-fra.com

Twitter Bootstrap modal sur les appareils mobiles

Les modaux d'amorçage ne fonctionnent pas correctement sous Android et iOS. Le suivi des problèmes reconnaît le problème mais n'offre pas de solution efficace:

Les modaux en 2.0 sont cassés sur le mobile.

La fenêtre modale dans 2.0 ne se positionne pas correctement

L'écran s'assombrit mais le modal lui-même n'est pas visible dans la fenêtre. Il est possible de le trouver en haut de la page. Le problème se produit lorsque vous avez fait défiler la page.

Voici une partie pertinente de bootstrap-responsive.css:

.modal {
position:fixed;
top:50%;
left:50%;
z-index:1050;
max-height:500px;
overflow:auto;
width:560px;
background-color:#fff;
border:1px solid #999;
-webkit-border-radius:6px;
-moz-border-radius:6px;
border-radius:6px;
-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);
-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);
box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);
-webkit-background-clip:padding-box;
-moz-background-clip:padding-box;
background-clip:padding-box;
margin:-250px 0 0 -280px;
}

Puis-je appliquer un correctif?

65
ty.

EDIT: Une modification non modale de Bootstrap _] modale a été conçue pour résoudre les problèmes de réponse/mobile. C’est peut-être le moyen le plus simple et le plus simple de remédier au problème.

Depuis, un correctif a été trouvé dans l'un des problèmes dont vous avez discuté plus tôt

dans bootstrap-responsive.css

.modal { 
    position: fixed; 
    top: 3%; 
    right: 3%; 
    left: 3%; 
    width: auto; 
    margin: 0; 
}
.modal-body { 
    height: 60%; 
}

et dans bootstrap.css

.modal-body { 
    max-height: 350px; 
    padding: 15px; 
    overflow-y: auto; 
    -webkit-overflow-scrolling: touch; 
 }
62
acconrad

La réponse de Gil est prometteuse (la bibliothèque à laquelle il a accédé) --- mais pour le moment, cela ne fonctionne toujours pas lorsque vous faites défiler l'écran vers le bas sur l'appareil mobile.

J'ai résolu le problème pour moi-même en utilisant juste un extrait de CSS à la fin de mes fichiers CSS:

@media (max-width: 767px) {
  #content .modal.fade.in {
    top: 5%;
  }
}

Le sélecteur #content est simplement un identifiant qui enveloppe mon code html afin que je puisse remplacer la spécificité de Bootstrap (défini sur votre propre identifiant enveloppant votre code html modal).

L'inconvénient: Il n'est pas centré verticalement sur les appareils mobiles.

L'avantage: C'est visible, et sur les plus petits appareils, un modal de taille raisonnable occupera une grande partie de l'écran, de sorte que le "non-centrage" ne sera pas aussi apparent.

Pourquoi ça marche:

Lorsque vous êtes à une taille d'écran réduite avec le CSS réactif de Bootstrap, pour les périphériques avec des écrans plus petits, il règle .modal.fade.in en haut à "auto". Pour une raison quelconque, les navigateurs Webkit mobiles semblent avoir du mal à comprendre le placement vertical avec l'affectation "auto". Donc, il suffit de revenir à une valeur fixe et cela fonctionne très bien. 

Comme le modal est déjà défini sur postition: absolute, la valeur est relative à la hauteur de la fenêtre de visualisation, pas à la hauteur du document. Elle fonctionne donc quelle que soit la longueur de la page ou l'endroit où vous faites défiler l'écran.

14
jlovison

La solution de niftylettuce in numéro 2130 semble réparer les modaux dans toutes les plateformes mobiles ...

09/01/12 UPDATE: le correctif a été mis à jour ici: Twitter bootstrap jquery plugins

(le code ci-dessous est plus ancien mais fonctionne toujours)

// # Twitter Bootstrap modal responsive fix by @niftylettuce
//  * resolves #407, #1017, #1339, #2130, #3361, #3362, #4283
//   <https://github.com/Twitter/bootstrap/issues/2130>
//  * built-in support for fullscreen Bootstrap Image Gallery
//    <https://github.com/blueimp/Bootstrap-Image-Gallery>

// **NOTE:** If you are using .modal-fullscreen, you will need
//  to add the following CSS to `bootstrap-image-gallery.css`:
//
//  @media (max-width: 480px) {
//    .modal-fullscreen {
//      left: 0 !important;
//      right: 0 !important;
//      margin-top: 0 !important;
//      margin-left: 0 !important;
//    }
//  }
//

var adjustModal = function($modal) {
  var top;
  if ($(window).width() <= 480) {
    if ($modal.hasClass('modal-fullscreen')) {
      if ($modal.height() >= $(window).height()) {
        top = $(window).scrollTop();
      } else {
        top = $(window).scrollTop() + ($(window).height() - $modal.height()) / 2;
      }
    } else if ($modal.height() >= $(window).height() - 10) {
      top = $(window).scrollTop() + 10;
    } else {
      top = $(window).scrollTop() + ($(window).height() - $modal.height()) / 2;
    }
  } else {
    top = '50%';
    if ($modal.hasClass('modal-fullscreen')) {
      $modal.stop().animate({
          marginTop  : -($modal.outerHeight() / 2)
        , marginLeft : -($modal.outerWidth() / 2)
        , top        : top
      }, "fast");
      return;
    }
  }
  $modal.stop().animate({ 'top': top }, "fast");
};

var show = function() {
  var $modal = $(this);
  adjustModal($modal);
};

var checkShow = function() {
  $('.modal').each(function() {
    var $modal = $(this);
    if ($modal.css('display') !== 'block') return;
    adjustModal($modal);
  });
};

var modalWindowResize = function() {
  $('.modal').not('.modal-gallery').on('show', show);
  $('.modal-gallery').on('displayed', show);
  checkShow();
};

$(modalWindowResize);
$(window).resize(modalWindowResize);
$(window).scroll(checkShow);
4
Gil Birman

Nous utilisons ce code pour centrer les boîtes de dialogue modales Bootstrap à leur ouverture. Je n'ai eu aucun problème avec eux sur iOS lorsque je l'utilisais, mais je ne suis pas sûr que cela fonctionne pour Android.

$('.modal').on('show', function(e) {
    var modal = $(this);
    modal.css('margin-top', (modal.outerHeight() / 2) * -1)
         .css('margin-left', (modal.outerWidth() / 2) * -1);
    return this;
});
2
Jeradan

Certes, je n’ai essayé aucune des solutions énumérées ci-dessus, mais j’ai (éventuellement) sauté de joie lorsque j’ai essayé le projet Bootstrap-modal de jschr dans Bootstrap 3 (lié à la réponse en haut). Le js me causait des problèmes alors je l'ai abandonné (peut-être que le mien était un problème unique ou qu'il fonctionnait bien pour Bootstrap 2), mais les fichiers CSS par eux-mêmes semblent faire l'affaire dans le navigateur 2.3.4 natif d'Android.

Dans mon cas, j’ai eu jusqu’à présent recours à la détection (sous-optimale) d’agent d’utilisateur avant d’utiliser les substitutions pour permettre le comportement attendu des téléphones modernes.

Par exemple, si vous souhaitez que tous les téléphones Android version 3.x et inférieure utilisent uniquement l'ensemble des hacks, vous pouvez ajouter une classe "oldPhoneModalNeeded" au corps après la détection de l'agent utilisateur à l'aide de javascript, puis modifier les propriétés CSS Bootstrap-modal de jschr en .oldPhoneModalNeeded est toujours un ancêtre.

1

vous pouvez ajouter cette propriété globalement en javascript:

if( navigator.userAgent.match(/iPhone|iPad|iPod/i) ) {
    var styleEl = document.createElement('style'), styleSheet;
    document.head.appendChild(styleEl);
    styleSheet = styleEl.sheet;
    styleSheet.insertRule(".modal { position:absolute; bottom:auto; }", 0);
 }
1
Hetdev

Pour moi, $('[data-toggle="modal"]').click(function(){}); fonctionne correctement.

0
Otabek Suvankulov

Nous avons trouvé une solution très compliquée à ce problème, mais cela fonctionne ... J'ai ajouté une classe au lien utilisé pour ouvrir le modal (avec la cible de données), puis à l'aide de Jquery, ajouté un événement de clic à cette classe qui récupère la cible de données, trouve le modal qu'il est censé ouvrir, puis l'ouvre via Javascript. Ça fonctionne très bien pour moi. J'ai également ajouté un contrôle mobile sur le mien afin qu'il fonctionne uniquement sur mobile, mais ce n'est pas obligatoire. 

$('.forceOpen').click(function() {
  var id = $(this).attr('data-target');
  $('.modal').modal('hide');
  $(id).modal('show');
});
0
Rockster160

Principalement Nexus 7 problème modal, modal descendait à l'écran

  .modal:before {
    content: '';
    display: inline-block;
    height: 50%; (the value was 100% for center the modal)
    vertical-align: middle;
    margin-right: -4px;
  }
0
gem007bd

Ma solution ...

Ver en jsfiddle

//Fix modal mobile Boostrap 3
function Show(id){
    //Fix CSS
    $(".modal-footer").css({"padding":"19px 20px 20px","margin-top":"15px","text-align":"right","border-top":"1px solid #e5e5e5"});
    $(".modal-body").css("overflow-y","auto");
    //Fix .modal-body height
    $('#'+id).on('shown.bs.modal',function(){
        $("#"+id+">.modal-dialog>.modal-content>.modal-body").css("height","auto");
        h1=$("#"+id+">.modal-dialog").height();
        h2=$(window).height();
        h3=$("#"+id+">.modal-dialog>.modal-content>.modal-body").height();
        h4=h2-(h1-h3);      
        if($(window).width()>=768){
            if(h1>h2){
                $("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
            }
            $("#"+id+">.modal-dialog").css("margin","30px auto");
            $("#"+id+">.modal-dialog>.modal-content").css("border","1px solid rgba(0,0,0,0.2)");
            $("#"+id+">.modal-dialog>.modal-content").css("border-radius",6);               
            if($("#"+id+">.modal-dialog").height()+30>h2){
                $("#"+id+">.modal-dialog").css("margin-top","0px");
                $("#"+id+">.modal-dialog").css("margin-bottom","0px");
            }
        }
        else{
            //Fix full-screen in mobiles
            $("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
            $("#"+id+">.modal-dialog").css("margin",0);
            $("#"+id+">.modal-dialog>.modal-content").css("border",0);
            $("#"+id+">.modal-dialog>.modal-content").css("border-radius",0);   
        }
        //Aply changes on screen resize (example: mobile orientation)
        window.onresize=function(){
            $("#"+id+">.modal-dialog>.modal-content>.modal-body").css("height","auto");
            h1=$("#"+id+">.modal-dialog").height();
            h2=$(window).height();
            h3=$("#"+id+">.modal-dialog>.modal-content>.modal-body").height();
            h4=h2-(h1-h3);
            if($(window).width()>=768){
                if(h1>h2){
                    $("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
                }
                $("#"+id+">.modal-dialog").css("margin","30px auto");
                $("#"+id+">.modal-dialog>.modal-content").css("border","1px solid rgba(0,0,0,0.2)");
                $("#"+id+">.modal-dialog>.modal-content").css("border-radius",6);               
                if($("#"+id+">.modal-dialog").height()+30>h2){
                    $("#"+id+">.modal-dialog").css("margin-top","0px");
                    $("#"+id+">.modal-dialog").css("margin-bottom","0px");
                }
            }
            else{
                //Fix full-screen in mobiles
                $("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
                $("#"+id+">.modal-dialog").css("margin",0);
                $("#"+id+">.modal-dialog>.modal-content").css("border",0);
                $("#"+id+">.modal-dialog>.modal-content").css("border-radius",0);   
            }
        };
    });  
    //Free event listener
    $('#'+id).on('hide.bs.modal',function(){
        window.onresize=function(){};
    });  
    //Mobile haven't scrollbar, so this is touch event scrollbar implementation
    var y1=0;
    var y2=0;
    var div=$("#"+id+">.modal-dialog>.modal-content>.modal-body")[0];
    div.addEventListener("touchstart",function(event){
        y1=event.touches[0].clientY;
    });
    div.addEventListener("touchmove",function(event){
        event.preventDefault();
        y2=event.touches[0].clientY;
        var limite=div.scrollHeight-div.clientHeight;
        var diff=div.scrollTop+y1-y2;
        if(diff<0)diff=0;
        if(diff>limite)diff=limite;
        div.scrollTop=diff;
        y1=y2;
    });
    //Fix position modal, scroll to top.    
    $('html, body').scrollTop(0);
    //Show
    $("#"+id).modal('show');
}
0
infinito84

Bien que cette question soit assez ancienne, certaines personnes risquent encore de tomber dessus en cherchant une solution pour améliorer l'UX des modaux sur les téléphones mobiles.

J'ai créé une librairie pour améliorer le comportement des modaux Bootrsrap sur les téléphones.

Bootstrap 3: https://github.com/keaukraine/bootstrap-fs-modal

Bootstrap 4: https://github.com/keaukraine/bootstrap4-fs-modal

0
keaukraine

OK, ça ne marche pas, je l’ai essayé aujourd’hui le 5 septembre 2012, mais vous devez être sûr de regarder la démo 

La solution de niftylettuce dans le numéro 2130 semble résoudre tous les problèmes de modaux plateformes mobiles ...

01/09/12 MISE À JOUR: Le correctif a été mis à jour ici: Plugins jquery pour Twitter bootstrap

voici le lien vers la Demo Cela fonctionne très bien ici le code que j'ai utilisé 

            title_dialog.modal();
            title_dialog.modalResponsiveFix({})
            title_dialog.touchScroll();
0
edgar