web-dev-qa-db-fra.com

Les positions corrigées ne fonctionnent pas avec -webkit-transform

J'utilise -webkit-transform (et -moz-transform/-o-transform) pour faire pivoter un div. Avoir également une position fixe ajoutée pour que la division défile avec l'utilisateur.

Dans Firefox, cela fonctionne bien, mais dans les navigateurs Webkit, il est cassé. Après avoir utilisé -webkit-transform, la position corrigée ne fonctionne plus! Comment est-ce possible?

138
iSenne

Après quelques recherches, il y a eu un rapport de bogue sur le site Web Chromium à ce sujet. Jusqu'à présent, les navigateurs Webkit ne peuvent pas afficher ces deux effets simultanément. 

Je suggérerais d’ajouter du CSS Webkit uniquement dans votre feuille de style, de transformer la div transformée en une image et de l’utiliser comme arrière-plan.

@media screen and (-webkit-min-device-pixel-ratio:0) {
  /* Webkit-specific CSS here (Chrome and Safari) */

  #transformed_div {
    /* styles here, background image etc */
  }
}

Donc, pour l'instant, vous devrez le faire à l'ancienne, jusqu'à ce que les navigateurs Webkit rattrapent FF.

EDIT: Le 24/10/2012, le bogue n'a pas été résolu.


Cela ne semble pas être un bogue, mais un aspect de la spécification en raison des deux effets nécessitant des systèmes de coordonnées et des ordres d'empilement distincts. Comme expliqué dans cette réponse .

77
Kyle

La spécification CSS Transforms explique ce comportement. Les éléments avec des transformations agissent comme un bloc conteneur pour les descendants à positions fixes, donc position: fixé sous quelque chose avec une transformation n'a plus de comportement fixe.

Ils fonctionnent lorsqu'ils sont appliqués au même élément. l'élément sera positionné comme fixe, puis transformé.

78
smfr

Pour tous ceux qui trouvent que leurs images d'arrière-plan disparaissent dans Chrome à cause du même problème avec l'attachement à l'arrière-plan: corrigé; - c'était ma solution:

// run js if Chrome is being used
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
    // set background-attachment back to the default of 'scroll'
    $('.imagebg').css('background-attachment', 'scroll');

    // move the background-position according to the div's y position
    $(window).scroll(function(){

        scrollTop = $(window).scrollTop();
        photoTop = $('.imagebg').offset().top;
        distance = (photoTop - scrollTop);
        $('.imagebg').css('background-position', 'center ' + (distance*-1) + 'px');

    });
}  
7
Jayden Lawson

Août 2016 et position fixe & animation/transformation est toujours un problème. La seule solution qui a fonctionné pour moi était de créer une animation pour l'élément enfant qui prend plus de temps.

6
defligra

En fait, j'ai trouvé un autre moyen de résoudre ce "bug":

J'ai un élément conteneur qui contient une page avec des animations CSS3. Lorsque la page a terminé l'animation, la propriété css3 a la valeur: transform: translate (0,0) ;. Donc, je viens de supprimer cette ligne, et tout a fonctionné comme il se doit - position: fixed est affiché correctement. Lorsque la classe css est appliquée pour traduire la page, la propriété de traduction est ajoutée et l'animation css3 fonctionne également.

Exemple:

.page {
     top: 50px;
     position: absolute;
     transition: ease 0.6s all;
     /* -webkit-transform: translate(0, 0); */
     /* transform: translate(0,0); */
 }
 .page.hide {
     -webkit-transform: translate(100%, 0);
     transform: translate(-100%, 0);    
 }

Démo: http://jsfiddle.net/ZWcD9/

3
lowselfesteemsucks

Quelque chose (un peu hacky) qui a fonctionné pour moi est plutôt de position:sticky

.fixed {
     position: sticky;
}
3
yckart

L'ajout du -webkit-transform à l'élément corrigé a résolu le problème pour moi.

.fixed_element {
   -webkit-transform: translateZ(0);
   position: fixed;
   ....
} 
2
Ron

Probablement à cause d'un bogue dans Chrome, car je ne peux pas répliquer dans Safari ni Firefox, mais cela fonctionne dans Chrome 40.0.2214.111 http://jsbin.com/hacame/1/edit?html,css,output

C'est une structure très particulière, donc ce n'est en aucun cas un correctif CSS unique, mais quelqu'un peut peut-être le modifier pour le faire fonctionner dans Safari et Firefox.

1
Kerry Johnson

sur mon projet phonegap, la transformation webkit -webkit-transform: translateZ (0); a fonctionné comme un charme . Il fonctionnait déjà en chrome et safari mais pas le navigateur mobile . il peut aussi y avoir un autre problème si WRAPPER DIVs ne sont pas terminés dans certains cas. nous appliquons une classe claire dans le cas de DIV flottantes.

<div class="Clear"></div> .Clear, .Clearfix{clear:both;}
1
abksharma

Voici ce qui fonctionne pour moi sur tous les navigateurs et appareils mobiles testés (Chrome, IE, Firefox, Safari, iPad, iPhone 5 et 6, Android).

img.ui-li-thumb {
    position: absolute;
    left: 1px;
    top: 50%;

    -ms-transform: translateY(-50%);
    -webkit-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -o-transform: translateY(-50%);
    transform: translateY(-50%);
}
0
TrackABill.com

Si vous pouvez utiliser javascript comme option, cela peut constituer une solution de contournement pour positionner un élément fixe à position fixe par rapport à la fenêtre lorsqu'il se trouve dans un élément transformé:

  let fixedEl // some node that you is position 
              // fixed inside of an element that has a transform

  const rect = fixedEl.getBoundingClientRect()
  const distanceFromWindowTop = rect.top
  const distanceFromWindwoLeft = rect.left
  let top = fixedEl.offsetTop
  let left = fixedEl.offsetLeft

  if(distanceFromWindowTop !== relativeTop) {
    top = -distanceFromWindowTop
    fixedEl.style.top = `${top}px`
  }

  if(distanceFromWindowLeft !== relativeLeft) {
    left = -distanceFromWindowLeft
    fixedEl.style.left = `${left}px`
  }

Certes, vous devrez également ajuster vos hauteurs et votre largeur car fixedEl calculera en fonction de son conteneur. Cela dépend de votre cas d'utilisation, mais cela vous permettra de fixer de manière prévisible la position de quelque chose de fixe, quel que soit son conteneur.

0
Adrian Adkison

Ajouter une classe dynamique pendant que l'élément transforme .$('#elementId').addClass('transformed'). Ensuite, déclarez en css,

.translatX(@x) { 
     -webkit-transform: translateX(@X); 
             transform: translateX(@x);
      //All other subsidaries as -moz-transform, -o-transform and -ms-transform 
}

puis

#elementId { 
      -webkit-transform: none; 
              transform: none;
}

puis

.transformed {
    #elementId { 
        .translateX(@neededValue);
    }
}

Now position: fixed lorsque les valeurs top et z-index de la propriété sont définies sur un élément enfant fonctionnent parfaitement et restent fixes jusqu'à la transformation de l'élément parent Lorsque la transformation est annulée, l'élément enfant apparaît de nouveau comme étant corrigé. Cela devrait faciliter la situation si vous utilisez réellement une barre latérale de navigation qui ouvre et ferme en un clic, et vous avez un jeu d'onglets qui doit rester collant lorsque vous faites défiler la page.

0
mr.G

la position fixe d'un élément est brisée si vous appliquez une transformation à un ancêtre quelconque.

<div style='position:fixed;-.*-transform:scale(2)'>...</div> //ok

<div style='-.*-transform:scale(2)'>
      <div style='position:fixed'>...</div> // broken
</div>
0
bortunac

Ne votez pas, s'il vous plaît, car ce n'est pas une réponse exacte, mais pourrait aider quelqu'un car c'est un moyen rapide de désactiver la transformation. Si vous n'avez vraiment pas besoin de la transformation sur le parent et que vous voulez que votre position fixe fonctionne à nouveau:

#element_with_transform {
  -webkit-transform: none;
  transform: none;
}
0
makkasi