Las posiciones fijas no funcionan cuando se usa -webkit-transform


155

Estoy usando -webkit-transform (y -moz-transform / -o-transform) para rotar un div. También se ha agregado la posición fija para que el div se desplace hacia abajo con el usuario.

En Firefox funciona bien, pero en los navegadores basados ​​en webkit está roto. ¡Después de usar -webkit-transform, la posición fija ya no funciona! ¿Cómo es eso posible?


44
Una página de demostración a menudo ayuda a las personas a responder preguntas: jsbin.com le permite crear páginas temporales para ilustrar el problema si no desea vincular a su sitio.
Rich Bradshaw

jsfiddle.net es otro buen ejemplo de un contenedor de edición temporal.
Kyle

@Rich Bradshaw jsbin.com es muy agradable. No lo sabía hasta ahora. La mayoría de mis proyectos los ejecuto localmente, así que lo usaré la próxima vez. Tnx
iSenne

77
No funciona bien en Firefox en absoluto.
vsync

3
Sigue siendo un problema en 2017. Parece que todavía se apegan a "¡Es una función, no un error!" argumento ...
Max

Respuestas:


87

Después de algunas investigaciones, ha habido un informe de error en el sitio web de Chromium sobre este problema, hasta ahora los navegadores Webkit no pueden procesar estos dos efectos juntos al mismo tiempo.

Sugeriría agregar algunos CSS de Webkit solo en su hoja de estilo y hacer que el div transformado sea una imagen y usarlo como fondo.

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

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

Entonces, por ahora, tendrá que hacerlo a la antigua usanza, hasta que los navegadores Webkit alcancen FF.

EDITAR: A partir del 24/10/2012, el error no se ha resuelto.


Esto parece no ser un error, sino un aspecto de la especificación debido a los dos efectos que requieren sistemas de coordenadas separados y órdenes de apilamiento. Como se explica en esta respuesta .


34
Incluso más años después, aún no resuelto. Bastante triste.
Amalgovinus

9
Según esta respuesta , no es un error, sino parte de la especificación.
MichaelRushton

15
siéntese y mire: apuesto a que vivirá su
décimo

29
30 de agosto de 2017, registro del capitán. También nos hemos encontrado con la extraña anomalía, que fue descrita hace mucho tiempo por otros capitanes. Una solución aún está por implementarse.
Luoruize

14
Este es el error del que me advirtió el padre de mi padre.
danjones_mcr

96

La especificación de Transformaciones CSS explica este comportamiento. Los elementos con transformaciones actúan como un bloque de contención para descendientes de posición fija, por lo tanto, la posición: arreglada debajo de algo con una transformación ya no tiene un comportamiento fijo.

Funcionan cuando se aplican al mismo elemento; el elemento se posicionará como fijo y luego se transformará.


9
Esa es la única respuesta útil y correcta. Deje de traducir el elemento primario y traduzca los elementos secundarios donde el elemento fijo es parte de él. Aquí está mi violín: JSFIDDLE
Falk

2
¿Y si también quiero transformar un elemento fijo?
Marc

7

Para cualquiera que encuentre que sus imágenes de fondo están desapareciendo en Chrome debido al mismo problema con el adjunto de fondo: corregido; - esta fue mi solución:

// 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');

    });
}  

6

Algo (un poco hacky) que funcionó para mí es position:sticky:

.fixed {
     position: sticky;
}

55
updates.html5rocks.com/2012/08/… ah sí .. pero no está bien soportado todavía parece
coiso

1
pegajoso es diferente. El principal problema es que con fijo queremos ignorar la posición del contenedor (muy útil para animaciones de opacidad, por ejemplo). No puedo creer que este error siga ahí años después. Horrible.
FlorianB

6

Agosto de 2016 y la posición fija y la animación / transformación siguen siendo un problema. La única solución que funcionó para mí fue crear una animación para el elemento secundario que lleva más tiempo.


Por favor responda a nuevas preguntas. Esas preguntas lo necesitan más que a la persona que hizo la pregunta en 2010. Deben haber resuelto el problema a estas alturas, ¿no le parece? Además, esta pregunta ya tiene una respuesta aceptada.
Umair Farooq

55
No! Todavía es un problema ... la persona que hizo la pregunta podría haber encontrado otra solución, pero encontré este hilo por una razón.
defligra el

Como desées. Dejé ese comentario mientras revisaba las primeras preguntas de la gente. Y como te uniste hoy y fue tu primera respuesta y también una respuesta tardía, es por eso que dejé ese comentario. No voté en contra. Esa es una buena oportunidad para ti.
Umair Farooq

1
@UmairFarooq tal vez hacer otra pregunta sería inútil porque podría marcarse como duplicado. Vine aquí solo con una búsqueda en google y encontré esta pregunta útil, defligra la respuesta también.
koMah

3

En realidad encontré otra forma de arreglar este "error":

Tengo un elemento contenedor que contiene la página con animaciones css3. Cuando la página completa la animación, la propiedad css3 tiene el valor: transform: translate (0,0) ;. Entonces, simplemente eliminé esta línea, y todo funcionó como debería: posición: fijo se muestra correctamente. Cuando se aplica la clase css para traducir la página, se agrega la propiedad translate y la animación css3 también funciona.

Ejemplo:

.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);    
 }

Demostración: http://jsfiddle.net/ZWcD9/


1
Para mí, era el hecho de tener estos estilos en el contenedor que contenía el elemento fijo lo que impedía que el fijo fuera pegajoso: -webkit-perspective: 1000; -webkit-transform-style: preservar-3d; Se quitó esto y todo funciona bien. ¡Eran optimizaciones cuestionables de todos modos!
Amalgovinus

Eliminar la transformación, por cualquier medio, es probablemente la mejor solución hasta ahora. Algo así como un desvanecimiento gradual, una vez completado, debe ser extraíble sin afectar la apariencia del elemento. En realidad, no estoy seguro de lo que haría tener un transformX (0) dando vueltas para representar el rendimiento, en todo caso; podría ignorarse, dañar el rendimiento o mejorarlo al forzar algún tipo de aceleración 3D. Quién sabe. En cualquier caso, una vez que se completa una animación, o incluso antes de que se le agregue un elemento fijo, uno simplemente puede eliminar las clases CSS para la transformación.
Triynko

1

en mi proyecto phonegap, el webkit transform -webkit-transform: translateZ (0); trabajado como un encanto. Ya funcionaba en Chrome y Safari, pero no en el navegador móvil. También puede haber un problema más es que los DIV de WRAPPER no se completan en algunos casos. Aplicamos la clase clara en caso de DIV flotantes.

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

1

Probablemente debido a un error en Chrome, ya que no puedo replicar en Safari ni Firefox, pero esto funciona en Chrome 40.0.2214.111 http://jsbin.com/hacame/1/edit?html,css,output

Es una estructura muy particular, por lo que de ninguna manera es una solución CSS universalmente aplicable de una sola línea, pero tal vez alguien pueda jugar con ella para que funcione en Safari y Firefox.


1

Tuve este problema al intentar implementar react-color con react-swipeable-views (rsw). El problema para mí fue que rsw se aplica translate(-100%, 0)a un panel de pestañas que rompe la división de posición fija predeterminada agregada en la pantalla completa que al hacer clic cierra el modelo de selector de color.

Para mí, la solución fue aplicar la transformación opuesta al elemento fijo (en este caso, translate(100%, 0)que solucionó mi problema. No estoy seguro de si esto es útil en otros casos, pero pensé que compartiría de todos modos.

Aquí hay un ejemplo que muestra lo que he descrito anteriormente:

https://codepen.io/relativemc/pen/VwweEez


0

Agregar el -webkit-transformelemento fijo me resolvió el problema.

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

20
Eso no funcionó para mí. ¿Eres capaz de crear una demostración de que funciona?
alex

44
Esto solucionó un problema para mí en Chrome, FWIW. Gracias Ron
Chris

3
Gracias, esto me solucionó un problema. ¡Salvó mi vida!
Styke

1
@Neil Monroe, Android 2.3 es una historia completamente nueva. No es compatible con el posicionamiento fijo en absoluto :)
Wiseman

8
Aquí hay un violín donde el uso translateZ(0) NO funciona. Es cierto que a veces funciona, he visto ocasiones en las que funcionó. Pero todavía no puedo reducirlo.
Zequez

0

Esto es lo que funciona para mí en todos los navegadores y dispositivos móviles probados (Chrome, IE, Firefox, Safari, iPad, iphone 5 y 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%);
}

2
¿Por qué los votos negativos? Sería bueno que hicieras un comentario sobre por qué rechazaste mi respuesta.
Murf

0

la posición fija de un elemento se rompe si aplica la transformación a cualquier antepasado.

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

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

0

Si puede usar JavaScript como una opción, esto puede ser una solución alternativa para posicionar un elemento fijo de posición relativo a la ventana cuando está dentro de un elemento transformado:

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

De acuerdo, también tendrá que ajustar sus alturas y ancho porque fixedElcalculará con base en su contenedor. Eso depende de su caso de uso, pero esto le permitirá establecer de manera predecible la posición de algo fijo, independientemente de su contenedor.


0

Agregue una clase dinámica mientras el elemento se transforma. $('#elementId').addClass('transformed'). Luego continúa declarando en css,

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

luego

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

luego

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

Ahora posición: fijo cuando se proporciona un valor de propiedad superior e índice z en un elemento secundario, funciona bien y permanece fijo hasta que el elemento primario se transforma. Cuando se revierte la transformación, el elemento secundario aparece como fijo nuevamente. Esto debería facilitar la situación si en realidad está utilizando una barra lateral de navegación que se abre y cierra con un clic, y tiene un conjunto de pestañas que debe permanecer fijo mientras se desplaza hacia abajo en la página.


0

en mi caso descubrí que no podemos usar transform: translateX () antes de transform: translateY (). si queremos usar ambos debemos usar transform: translate (,).


-1

Por favor, no vote, porque esta no es la respuesta exacta, pero podría ayudar a alguien porque es una forma rápida de desactivar la transformación. Si realmente no necesita la transformación en el padre y desea que su posición fija vuelva a funcionar:

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

1
Esto es, como, realmente en el título de la pregunta
Eugene Pankov

@EugenePankov No veo 'ninguno' en el título. Fue lo que solucionó mi problema y, en general, nadie sugiere apagarlo. Aunque esta no es la respuesta exacta a esa pregunta, podría ayudar a alguien que no quiere usar la transformación y la transformación proviene de otra biblioteca. Así que no quiero votos, pero por favor no voten. Editaré mi pregunta para decir que no quiero votar.
makkasi
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.