'transform3d' ne fonctionne pas avec la position: enfants fixes

j'ai une situation où, dans des circonstances normales CSS, un div fixe serait placé exactement où il est spécifié ( top:0px , left:0px ).

cela ne semble pas être respecté si j'ai un parent qui a une transformation translate3d. Je ne suis pas à voir quelque chose? J'ai essayé d'autres options webkit-transform comme style et transform origin, mais je n'ai pas eu de chance.

j'ai joint un JSFiddle avec un exemple où j'aurais attendu la boîte jaune, être dans le coin supérieur de la page plutôt qu'à l'intérieur de l'élément conteneur.

http://jsfiddle.net/GMX5H/1 /

C'est une version simplifiée du violon:

<br>
<div style='position:relative; border: 1px solid #5511FF; 
            -webkit-transform:translate3d(0px, 20px , 0px); 
            height: 100px; width: 200px;'> 
    <div style='position: fixed; top: 0px; 
                box-shadow: 3px 3px 3px #333; 
                height: 20px; left: 0px;'>
        Inner block
    </div>
</div>

tous les conseils pour faire le travail translate3d avec un enfant en position fixe seront appréciés.

115
demandé sur TylerH 2013-03-04 07:53:47

12 réponses

c'est parce que le transform crée un nouveau système de coordonnées locales, selon spec W3C :

dans L'espace de noms HTML, toute valeur autre que none pour la transformation résulte en la création à la fois d'un contexte d'empilage et d'un bloc contenant. L'objet agit comme un bloc contenant fixe positionné descendants.

cela signifie que le positionnement fixe devient fixe à la transformé élément, plutôt que la fenêtre d'affichage.

il n'y a pas de solution que je sache.

Il est également documentée sur Eric Meyer l'article: de l'Onu-la fixation des Éléments Fixes avec CSS Transforme .

164
répondu saml 2015-05-18 15:41:51

comme Bradoergo suggéré, il suffit d'obtenir la fenêtre scrollTop et l'ajouter à la position absolue haut comme:

function fix_scroll() {
  var s = $(window).scrollTop();
  var fixedTitle = $('#fixedContainer');
  fixedTitle.css('position','absolute');
  fixedTitle.css('top',s + 'px');
}fix_scroll();

$(window).on('scroll',fix_scroll);

ça a marché pour moi de toute façon.

11
répondu UzumakiDev 2014-01-31 19:12:36

j'ai eu un clignotement sur mon nav supérieur fixe lorsque les éléments dans la page utilisaient transform, le suivant appliqué à mon nav supérieur a résolu le problème de saut / clignotement:

#fixedTopNav {
    position: fixed;
    top: 0;
    transform: translateZ(0);
    -webkit-transform: translateZ(0);
}

merci à cette réponse sur SO

11
répondu rob.m 2017-05-23 12:34:41

dans Firefox et Safari vous pouvez utiliser position: sticky; au lieu de position: fixed; mais il ne fonctionnera pas dans les autres navigateurs. Pour cela vous avez besoin de javascript.

3
répondu Dušan 2015-12-14 18:45:53

,

N'ayant pas trouvé de méthode satisfaisante pour faire face à cela; et faire quelques trucs de pane hors-toile (nécessitant traduire) - j'ai creusé dans un peu et découvert que (au moins pour mon cas d'utilisation) la meilleure méthode pour faire face à cela est d'appliquer la même traduction, mais briser les enfants qui ont besoin d'être fixé hors de leur parent (traduit) élément; et puis appliquer la traduction à un div à l'intérieur de la position: fixed envelopper.

l'apparence des résultats quelque chose comme ceci (dans votre cas):

<br>
<div style='position:relative; border: 1px solid #5511FF; 
            -webkit-transform:translate3d(0px, 20px , 0px); 
            height: 100px; width: 200px;'> 

</div>
<div style='position: fixed; top: 0px; 
            box-shadow: 3px 3px 3px #333; 
            height: 20px; left: 0px;'>
    <div style='-webkit-transform:translate3d(0px, 20px, 0px);'>
        Inner block
    </div>
</div>

violon fourche: https://jsfiddle.net/hju4nws1/

bien que cela ne soit pas idéal pour certains cas d'utilisation, typiquement si vous réparez un div, vous pourriez probablement moins se soucier de ce qui est son parent/où il tombe dans l'arbre de l'héritage dans votre DOM, et semble résoudre la plupart des maux de tête-tout en permettant à la fois translate et position: fixed de vivre dans (relatif) harmonie.

3
répondu reid 2017-03-07 23:32:08

j'ai un problème similaire et je crois qu'il y a du travail autour. Je suis en utilisant le composant logiciel enfichable.js et moi voulons que l'une des divs enfant du conteneur de contenu soit fixée à sa position. Cependant, lorsque le tiroir s'ouvre, JavaScript déclenche la propriété transform:translate3d pour le conteneur parent et cela affecte également l'élément fixe enfant (l'élément fixe se déplace avec son parent et reste fixe dans la nouvelle position).

avec ceci étant dit, la propriété fixe devient partiellement inutile. Pour résoudre ce problème, on peut ajouter un écouteur d'événements qui lancerait une tranform:translate3d séparée pour le div fixe enfant. Et la direction de cette translation devrait être opposée à celle de la transformation du parent:translate3d.

le seul problème est que je ne sais pas comment l'écrire et il aurait été cool si quelqu'un a pris un coup à elle.

1
répondu Anson Wakaka 2013-09-12 07:12:14

j'ai rencontré le même problème. La seule différence est que mon élément avec "position: fixed" avait ses propriétés de style " top " et "left" définies à partir de JS. J'ai donc pu appliquer une correction:

var oRect = oElement.getBoundingClientRect();

oRect object contiendra real (relatif au port de vue) coordonnées en haut et à gauche. Pour que vous puissiez ajuster votre équipement.style.haut et oElement.style.propriétés gauche.

0
répondu Mike Dobrin 2013-07-22 12:29:52

j'ai une barre latérale off canvas qui utilise-webkit-transform: translate3d. Cela m'empêchait de placer un pied de page fixe sur la page. J'ai résolu le problème en ciblant une classe sur la page html qui est ajoutée à la balise sur l'initialisation de la barre latérale et en écrivant ensuite un CSS :not qualificatif à l'état "-webkit-transform: none;" à la balise html lorsque cette classe n'est pas présente sur la balise html. Espérons que cela aide quelqu'un là-bas avec cette même question!

0
répondu WeisbergWeb 2016-06-22 21:19:25

essayer d'appliquer la transformation opposée à l'élément enfant:

<div style='position:relative; border: 1px solid #5511FF; 
            -webkit-transform:translate3d(0px, 20px , 0px); 
            height: 100px; width: 200px;'> 
    <div style='position: fixed; top: 0px; 
                -webkit-transform:translate3d(-100%, 0px , 0px); 
                box-shadow: 3px 3px 3px #333; 
                height: 20px; left: 0px;'>
        Inner block
    </div>
</div>
0
répondu Mari Do 2016-08-06 13:59:02

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

.translat3d(@x, @y, @z) { 
     -webkit-transform: translate3d(@X, @y, @z); 
             transform: translate3d(@x, @y, @z);
      //All other subsidaries as -moz-transform, -o-transform and -ms-transform 
}

puis

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

puis

.transformed {
    #elementId { 
        .translate3d(0px, 20px, 0px);
    }
}

maintenant position: fixed lorsque fourni avec un top et z-index valeurs de propriété sur un élément enfant juste travailler très bien et rester fixe jusqu'à ce que l'élément parent se transforme. Lorsque la transformation est inversée, l'élément enfant apparaît comme fixe. Ce si la situation est plus facile si vous utilisez réellement une barre latérale de navigation qui bascule ouvrir et se ferme sur un clic, et vous avez un tab-set qui devrait rester collant pendant que vous faites défiler la page.

0
répondu mr.G 2018-07-30 19:08:19

Une façon de traiter cette question est d'appliquer la même transformation à l'élément fixe:

<br>
<div style='position:relative; border: 1px solid #5511FF; 
            -webkit-transform:translate3d(0px, 20px , 0px); 
            height: 100px; width: 200px;'> 
    <div style='position: fixed; top: 0px; 
                -webkit-transform:translate3d(0px, 20px , 0px); 
                box-shadow: 3px 3px 3px #333; 
                height: 20px; left: 0px;'>
        Inner block
    </div>
</div>
-1
répondu fgassert 2015-09-03 04:07:37

si vous travaillez sur mobile avec un menu offcanvas peut-être ce code vous aidera.

    $('#toggle-button').click(function () {
    slideout.toggle();

    // Sticky menu with off canvas menu (for mobile)
    var isMenuDisplaced = $('.sticky-menu').hasClass('is-displaced');

    if (isMenuDisplaced === false) {
        $('.sticky-menu').addClass('is-displaced');
        var scrollTopPosition = $(window).scrollTop();
        $('.sticky-menu').css('position', 'absolute');
        $('.sticky-menu').css('top', scrollTopPosition + 'px');
    }

    else {
        window.setTimeout(function () {
            $('.sticky-menu').removeClass('is-displaced');
            $('.sticky-menu').css('position', 'fixed');
            $('.sticky-menu').css('top', 0);
        }, 400);
    }


})
-4
répondu Juanma - ZeneK 2017-01-09 22:10:04