tag page cambiar javascript css google-chrome z-index scaletransform

javascript - page - Vídeo e índice z dentro del elemento escalado: algunos divs desaparecen



title tag html5 (8)

Aquí tienes: https://jsfiddle.net/Lcox1ecc/423/

Solo necesitas agregar -webkit-transform: translateZ(0); a la clase .on-top .

¡Feliz codificación!

Tengo un comportamiento un tanto extraño en Chrome y Safari. Tengo un contenedor escalado ( transform: scale() ) con un video y otros elementos dentro de él. En algunas escalas, los elementos posicionados absolutos con un alto índice z desaparecen y no vuelven a aparecer.

¿Cómo puedo arreglar esto? Tenga en cuenta que no puedo dar al elemento de video un índice z negativo y necesito usar overflow: hidden; .

Ejemplo

He hecho un ejemplo que escala el contenedor exterior hacia arriba y hacia abajo. A un valor de escala specifik, el elemento con la clase .on-top (y el texto "I should always be on top." ) desaparece. Cuando se reduce de nuevo, aparece de repente.

Enlace a exmaple: https://jsfiddle.net/iafiawik/Lcox1ecc/

Conclusiones

  • Parece que el tamaño del elemento importa. Cuanto más grande lo hago, más grande es el valor de escala antes de que desaparezca.
  • También he probado para establecer transform: scale(1.4) con CSS directamente en el elemento y el comportamiento es el mismo.

El problema no existe si yo:

  • Reemplace la etiqueta de video con un div
  • Eliminar position: absolute; de hermanos a .on-top (es decir, .below )
  • Eliminar el overflow: hidden; de .content
  • Si muevo .on-top para que se coloque después de la etiqueta de video en el flujo de documentos

(Pero, por supuesto, ninguna de estas soluciones me funciona en realidad debido a razones específicas del proyecto. Tampoco le puedo dar al elemento de video un índice z negativo y necesito usar overflow: hidden; )

Soluciones sugeridas de la comunidad (¡gracias!)

  • Dale a la etiqueta de video un índice z negativo (no puedo hacer esto porque a veces tengo elementos colocados detrás del video)
  • Eliminar el overflow: hidden; (No puedo eliminar el overflow: hidden; )

Navegadores

He visto este problema en Chrome (Mac) y Safari (Mac).

Actualización 1

Parece que este informe de error cubre bastante mi problema. Sin embargo, no proporciona una solución para ello.

Actualización 2

He respondido a mi propia pregunta proporcionando mi solución a este problema.

Actualización 3

.on-top muchas respuestas que modifican el z-index del video o agregan translateZ al elemento .on-top . Las demostraciones han demostrado que ambos enfoques solucionan el problema. Sin embargo, dado que mi estructura HTML es la salida de un editor de HTML visual (historia larga ...), no sé qué elementos estarán allí o si deberían estar en frente, debajo o al lado de un video. Por lo tanto, estoy buscando una solución que no requiera cambios en los elementos individuales que están dentro del elemento escalado.


Después de pasar mucho tiempo investigando este problema y probando diferentes enfoques, he llegado a la conclusión de que ninguna solución soluciona mi problema. Hay soluciones que solucionan el problema si puede controlar los índices z de los elementos que desaparecen, pero no puedo hacerlo ya que no se sabe que la estructura del HTML (es la salida del editor HTML). ). Estaba buscando una solución que no requiera cambios en los hijos individuales del padre escalado, pero hasta ahora no he encontrado ninguno.

Este informe de errores cubre prácticamente mi problema, pero no proporciona una solución para ello.

Puedo confirmar que esto sucede porque el elemento está fuera del ancho y alto original de los contenedores escalados:

El elemento es visible a scale(1.227) (el borde rojo indica el tamaño original de #scaled ):

... pero no a scale(1.228) :

Por lo tanto, mi solución es agregar otro elemento de envoltura fuera del elemento escalado que no esté escalado, pero actualizar sus propiedades de width y height acuerdo con sus primeros valores de escala secundarios. Este elemento tiene overflow: hidden; y evita que los elementos sean visibles.

Esta no es una solución perfecta, ya que uno podría experimentar una pequeña brecha entre el elemento escalado y el elemento envolvente más externo (problemas de redondeo), pero es lo mejor que puedo hacer dadas las circunstancias.

var goalScale = 140; var startScale = 100; var currentScale = 100; var shouldScaleUp = true; var container = document.getElementById("scaled"); var scaledContainer = document.getElementById("resized-container"); var scaleInfo = document.getElementById("scale-info"); function step() { var contentWidth = 1024; var contentHeight = 768; container.style.transform = "scale(" + (currentScale / 100) + ")"; scaledContainer.style.width = contentWidth * ((currentScale / 100)) + "px"; scaledContainer.style.height = contentHeight * ((currentScale / 100)) + "px"; scaleInfo.innerText = "Scale: " + (currentScale / 100); if (currentScale === goalScale) { shouldScaleUp = false; } if (currentScale === startScale) { shouldScaleUp = true; } if (shouldScaleUp) { currentScale += 0.5; } else { currentScale -= 0.5; } window.requestAnimationFrame(step); } window.requestAnimationFrame(step);

#resized-container { position: fixed; width: 1024px; height: 768px; overflow: hidden; border: 10px solid red; top: 200px; left: 200px; } #scaled { background: #cccccc; width: 1024px; height: 768px; position: absolute; transform-origin: left top; } .content { height: 100%; position: relative; margin-left: auto; margin-right: auto; background: rgba(34, 34, 56, 0.2); } .below { position: absolute; width: 300px; height: 300px; right: 0px; top: 100px; background: purple; z-index: 1; opacity: 0.8; } .below-2 { z-index: 3; right: 100px; } .below-3 { z-index: 4; right: 400px; } .on-top { position: absolute; width: 50px; right: -30px; top: 150px; background: pink; z-index: 5; padding: 20px; } .on-top h1 { font-size: 20px; } #video { position: absolute; z-index: 4; width: 1024px; height: 768px; background: rgba(0, 0, 0, 0.4); }

<div id="resized-container"> <div id="scaled"> <div id="scale-info"> </div> <div class="content"> <h2 class="below below-1"> I have z-index 1 </h2> <div class="on-top"> <h1> I should always be on top.<br /> I have z-index 5 </h1> </div> <h2 class="below below-2"> I have z-index 3 </h2> <video id="video" src="https://www.w3schools.com/html/mov_bbb.mp4"></video> <h2 class="below below-3"> I have z-index 4 </h2> </div> </div> </div>




Me encontré con algo similar a esto la semana pasada con el posicionamiento de elementos absolutos y transformaciones ...

No sé si esto te ayudará, pero aquí hay un enlace.

Transformación CSS: traduce posición de movimientos: división interna fija.

Al final lo arreglé usando una transformación: translateX (ninguna) vs translateX (0).

Súper extraño comportamiento seguro, pero el enlace ofrece algunos enlaces más para ayudar a aclarar las cosas, como en su comportamiento según las especificaciones.


Me gusta mucho la respuesta de Lo único que viene a la mente, sería reescribir con position: relative . Pero no sé si esa es una opción.


Parece un error en Chrome. Tenga en cuenta que cuando escala la imagen, el inspector de elementos le dice que el tamaño de #scaled es 1024x768:

Donde como en Firefox:

Ahora, al parecer, Chrome usa el tamaño incorrecto para concluir que .on-top está completamente fuera del contenido .content y lo oculta debido a un desbordamiento oculto (no debería estar haciendo esto, pero aparentemente está tratando de optimizar cualquier elemento que se muestre arriba de un video). ). Ejemplos:

Scale: 1.225 Parent width: 1254.40 Child left: 1254.40 - (100 + 90) * 1.225 = 1021.65 Result: less than 1024 (partially inside) Scale: 1.230 Parent width: 1259.52 Child left: 1259.52 - (100 + 90) * 1.230 = 1025.82 Result: greater than 1024 (completely outside)

Lamentablemente no pude encontrar una solución elegante. Idealmente, debería revisar su marca HTML y CSS, tal vez alinear el elemento superior con el borde izquierdo. Como último recurso, puede mover los elementos más hacia la izquierda utilizando el borde transparente:

var goalScale = 140; var startScale = 100; var currentScale = 100; var shouldScaleUp = true; var container = document.getElementById("scaled"); var scaleInfo = document.getElementById("scale-info"); function step() { container.style.transform = "scale(" + (currentScale / 100) + ")"; scaleInfo.innerText = "Scale: " + (currentScale / 100); if (currentScale === goalScale) { shouldScaleUp = false; } if (currentScale === startScale) { shouldScaleUp = true; } if (shouldScaleUp) { currentScale += 0.5; } else { currentScale -= 0.5; } window.requestAnimationFrame(step); } window.requestAnimationFrame(step);

.scale-info { position: fixed; left: 0; top: 0; } #scaled { background: #cccccc; width: 1024px; height: 768px; position: fixed; left: 200px; top: 200px; } .content { height: 100%; overflow: hidden; position: relative; margin-left: auto; margin-right: auto; background: rgba(34, 34, 56, 0.2); } .below { position: absolute; width: 300px; height: 300px; right: 0px; top: 100px; background: purple; z-index: 1; opacity: 0.8; } .below-2 { z-index: 3; right: 100px; } .below-3 { z-index: 4; right: 400px; } .on-top { position: absolute; width: 50px; right: 100px; top: 150px; background: pink; z-index: 5; padding: 20px; /* a 200px border moves the element towards left */ border-left: 200px solid transparent; background-clip: padding-box; } .on-top h1 { font-size: 20px; } #video { position: absolute; z-index: 4; width: 1024px; height: 768px; background: rgba(0, 0, 0, 0.4); }

<div id="scale-info"></div> <div id="scaled"> <div class="content"> <h2 class="below below-1"> I have z-index 1</h2> <div class="on-top"> <h1> I should always be on top.<br> I have z-index 5</h1> </div> <h2 class="below below-2"> I have z-index 3</h2> <video id="video" src="https://www.w3schools.com/html/mov_bbb.mp4"></video> <h2 class="below below-3"> I have z-index 4</h2> </div> </div>


Un enfoque, si puede modificar un poco su html, es envolver sus elementos problemáticos en un contenedor del mismo tamaño que el video y el contenedor, con el índice z apropiado. De esa manera, tendría capas claras del mismo tamaño y posición, en las que puede colocar elementos más complejos. Como este por ejemplo:

<div id="top-container"> <div class="on-top"> <h1> I should always be on top.<br /> I have z-index 5 </h1> </div> </div> #top-container { width: 100%; height: 100%; position: absolute; z-index: 5; }

https://jsfiddle.net/06oykj8o/4/