web-dev-qa-db-fra.com

Propriété de transformation CSS3 fonctionnant différemment dans Internet Explorer

J'utilise le CSS suivant pour centrer une div au milieu de ma page:

.someWrapper {
    width: 100%;
    height: 100%;
    position: relative;
}

.centredDiv {
    width: (some width);
    height: (some height)
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translate(-50%, -50%);
      -moz-transform: translate(-50%, -50%);
        -ms-transform: translate(-50%, -50%);
          -o-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
}

J'ai testé cela dans Chrome, Firefox et Safari et cela fonctionne comme prévu. Cependant, dans Internet Explorer (test sur IE11), bien qu'il centre la division au milieu de la fenêtre, IE semble penser qu'il existe encore une "division fantôme" invisible à 50% et à 50% vers le bas qui pas été transformé.

Il en résulte tout un tas d'espace de débordement blanc et d'inutiles barres de défilement dans le coin inférieur droit de l'écran. Si j'active le débordement: caché, cela peut résoudre le problème, mais ce n'est pas une option réalisable sur mon site Web.

Alors pourquoi IE fait-il cela et existe-t-il un moyen facile de le contourner?

EDIT: Le code suivant illustre le problème. Ouvrez le code dans Chrome ou Firefox, il n'y a pas de débordement. Ouvrez-le dans IE (en test dans IE11) et vous verrez un débordement provoquant un espace blanc et des barres de défilement vers le bas et vers la droite. 

<!DOCTYPE HTML>
  <html>
    <head>
     <style>
       html, body {
         height: 100%;
         width: 100%;
         margin: 0;
         padding: 0;
       }

       #wrapper {
         width: 100%;
         height: 100%;
         position: relative;
       }

       #centred {
         width: 90%;
         height: 90%;
         position: absolute;
         top: 50%;
         left: 50%;
         background-color: red;
         -webkit-transform: translate(-50%, -50%);
         -moz-transform: translate(-50%, -50%);
         -ms-transform: translate(-50%, -50%);
         -o-transform: translate(-50%, -50%);
         transform: translate(-50%, -50%);
       }
     </style>
   </head>
 <body>
   <div id="wrapper">
     <div id="centred">
       Hello world!
     </div>
   </div>
 </body>
</html> 
16
AzzyDude

Approche plus facile

Au lieu de positionner à partir de top et left, placez plutôt à partir de bottom et right. Ceci fait, changez simplement vos traductions -50% en positives 50%. Cela supprimera le débordement, par exemple.

.center-center {
    position: absolute;
    bottom: 50%;
    right: 50%;
    transform: translate(50%, 50%);
}

Vous pouvez voir ces changements en action ici: http://jsfiddle.net/bd17gsss/

Il convient de noter que ce bogue est toujours classé et notre équipe lui accordera la considération appropriée lorsque le temps et les cycles le permettent.

Réponse originale

Il semble y avoir un bogue de mise en page avec position: absolute dans cette démo particulière. Son comportement est similaire à position: relative alors que ce ne devrait pas être le cas. J'ai ouvert un bogue sur ce problème pour que l'équipe Internet Explorer approfondisse ses recherches.

Pour l'instant, vous pouvez passer votre valeur de position de absolute à fixed, ce qui semble rendre l'élément centré correctement. Cela vous évite d'avoir à utiliser un ensemble fixe de dimensions à plusieurs reprises et vous permet d'utiliser cette approche comme une classe de style .modal à usage général qui centrera tout ce à quoi elle s'applique.

La mise en garde évidente avec ce changement est que votre élément est positionné en fonction de la fenêtre d'affichage et non plus du document lui-même. Cela le gèlera à l'écran efficacement.

.modal {
    position: fixed;
    top: 50%; left: 50%;
    background-color: red;
    transform: translate(-50%, -50%);
}

Pour démontrer le succès de cette approche avec différentes dimensions, nous pouvons parcourir quelques exemples de jeux et tester le rendu de l'élément pour s'assurer qu'il est correctement centré:

(function () {

    var xandy,
        index = 0,
        modal = document.querySelector( ".modal" ),
        sizes = [
            { x: "50%"  , y: "30%"   },
            { x: "400px", y: "288px" },
            { x: "25vw" , y: "75vh"  },
            { x: "90%"  , y: "90%"   }
        ];

    setInterval(function changeSize () {
        xandy = sizes[ index++ % sizes.length ];
        modal.style.width = xandy.x;
        modal.style.height = xandy.y;
    }, 1000 );

}());

Le résultat final peut être visualisé en ligne ici: http://jsfiddle.net/jonathansampson/c00u5ev8/

22
Sampson

Si quelqu'un d'autre s'amuse encore à essayer de résoudre ce problème (vu que les bogues d'Internet Explorer ne sont jamais résolus, nous aimons tous les contourner) et que vous souhaitez pouvoir utiliser position: relative; au lieu de position: absolute;, ou en haut et à gauche plutôt qu'en bas et à droite, essayez ceci à la place:

.centredDiv {
    position: relative;
    top: calc(50% - 100vh);
    left: calc(50% - 100vw);
    transform: translate(-50%, -50%) translate(100vw, 100vh);
}

Vous pouvez utiliser 100 hauteur/largeur de vue ou une valeur de pixel arbitraire représentant une hauteur/largeur de défilement théorique maximale, de sorte que les valeurs supérieure/gauche ne dépassent jamais le parent, puis ne les décalent que dans la transformation.


Si j'étais dans un ascenseur avec Hitler, Staline et Internet Explorer et que j'avais une arme à feu avec une seule balle ... je tuerais Internet Explorer.

1
JacDek

Si vous venez de répondre à cette question dans un autre fil, vous pouvez utiliser display: table; et display: table-cell; pour résoudre ce problème (fonctionne également avec plusieurs navigateurs!), Consultez mon code en direct ici: http://codepen.io/TheDutchCoder/pen/GggWqP

Dans votre cas ce serait:

#wrapper {
  display: table;
  width: 100%;
  height: 100%;
}

#centred {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}
1
Reinier Kaper

Pour moi, le problème avec traduction ne fonctionnant pas dans IE 11 était simplement que la page était automatiquement exécutée en mode de compatibilité, ce qui entraînait l'exécution de IE 11 comme s'il s'agissait d'un navigateur plus ancien, ce qui ne prend pas en charge la traduction en CSS.

Ma solution était simplement de mettre cette balise dans la tête:

<head>
  <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
  ....

Cela indique à IE de s'exécuter en utilisant le "dernier" code, ce qui signifie essentiellement que IE 11 affiche la page avec le code IE 11 et non en tant que version antérieure du navigateur.

Si vous souhaitez figer la compatibilité avec une version spécifique de IE, vous pouvez le faire avec cette balise, en utilisant différentes valeurs de "contenu". La valeur "IE-Edge" lui indique d'utiliser le dernier code disponible.

Si vous voulez savoir si votre page est affichée en mode de compatibilité, appuyez sur F12 pour afficher les outils de développement dans le navigateur, passez à l'onglet "Console" et rechargez la page. L'onglet de la console va dire quelque chose comme:

http://yoursite.com is running in Compatibility View because ...

s'il fonctionne bien en mode de compatibilité.

0
BI Developer

Votre code est trop abrégé et sans exemple, il est difficile de donner des conseils. La partie (some dynamic height/width) me préoccupe, c’est-à-dire que cela me semble être un lieu où votre problème pourrait se poser.

Pour votre information, vous pouvez consulter la propre explication de Microsoft sur Transformer dans IE .

0
Douglas Denhartog

Ajoutez simplement transition: all .2s ease-in-out; sous votre ligne de transformation.

0
Hieu Tran AGI