151 votes

transform3d ne fonctionne pas avec position : fixed children

J'ai une situation où, dans des circonstances CSS normales, un div fixe serait positionné exactement là 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. Est-ce que je ne vois pas 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 que la boîte jaune soit dans le coin supérieur de la page plutôt qu'à l'intérieur de l'élément conteneur.

Vous trouverez ci-dessous une version simplifiée du violon :

#outer {
    position:relative; 
    -webkit-transform:translate3d(0px, 20px , 0px); 
    height: 300px; 
    border: 1px solid #5511FF; 
    padding: 10px;
    background: rgba(100,180,250, .8); 
    width: 80%;
}
#middle{
    position:relative; 
    border: 1px dotted #445511; 
    height: 300px; 
    padding: 5px;
    background: rgba(250,10,255, .6);
}
#inner {
    position: fixed; 
    top: 0px;
    box-shadow: 3px 3px 3px #333; 
    height: 20px; 
    left: 0px;
    background: rgba(200,180,80, .8); 
    margin: 5px; 
    padding: 5px;
}

<div id="container">
    Blue: Outer, <br>
    Purple: Middle<br>
    Yellow: Inner<br>
    <div id="outer"> 
        <div id="middle">
            <div id="inner">
                Inner block
            </div>
        </div>
    </div>
</div>

Comment faire pour que translate3d fonctionne avec des enfants à position fixe ?

220voto

saml Points 2463

Cela s'explique par le fait que le transform crée un nouveau système de coordonnées locales, conformément à Spécification du W3C :

Dans l'espace de noms HTML, toute valeur autre que none pour la transformation entraîne la création à la fois d'un contexte d'empilement et d'un bloc contenant. L'objet agit comme un bloc contenant pour les descendants positionnés de manière fixe.

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

Il n'y a pas actuellement de solution de contournement à ma connaissance.

Elle est également documentée sur l'article d'Eric Meyer : Déverrouiller les éléments fixes avec les transformations CSS .

13voto

UzumakiDev Points 528

Comme Bradoergo l'a suggéré, il suffit de prendre la fenêtre scrollTop et l'ajouter à la position absolue en 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);

Cela a fonctionné pour moi en tout cas.

13voto

rob.m Points 810

J'avais un scintillement sur mon nav supérieur fixe lorsque les éléments de la page utilisaient la transformation, ce qui suit appliqué à mon nav supérieur a résolu le problème de saut / scintillement :

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

Grâce à cette réponse sur SO

5voto

Dušan Points 478

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

3voto

reid Points 151

À mon avis, la meilleure méthode pour résoudre ce problème consiste à appliquer la même translation, mais en séparant les enfants qui doivent être corrigés de leur élément parent (traduit), puis en appliquant la translation à un div à l'intérieur de l'élément position: fixed l'emballage.

Les résultats ressemblent à ceci (dans votre cas) :

<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>

JSFiddle : https://jsfiddle.net/hju4nws1/

Bien que cela ne soit pas idéal pour certains cas d'utilisation, si vous corrigez un div, vous ne vous souciez probablement pas de savoir quel élément est son parent/où il se situe dans l'arbre d'héritage dans votre DOM, et cela semble résoudre la plupart des maux de tête - tout en permettant à la fois aux translate y position: fixed de vivre en harmonie (relative).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X