En IOS8 Safari hay un nuevo error con la posición corregida.
Si enfoca un área de texto que está en un panel fijo, safari lo desplazará hasta la parte inferior de la página.
Esto hace que sea imposible trabajar con todo tipo de IU, ya que no tiene forma de ingresar texto en áreas de texto sin desplazarse por la página hacia abajo y perder su lugar.
¿Hay alguna forma de solucionar este error de forma limpia?
#a {
height: 10000px;
background: linear-gradient(red, blue);
}
#b {
position: fixed;
bottom: 20px;
left: 10%;
width: 100%;
height: 300px;
}
textarea {
width: 80%;
height: 300px;
}
<html>
<body>
<div id="a"></div>
<div id="b"><textarea></textarea></div>
</body>
</html>
Respuestas:
Basado en este buen análisis de este problema, he usado esto en
html
ybody
elementos en css:Creo que me está funcionando muy bien.
fuente
transform: translateZ(0);
desde stackoverflow.com/questions/7808110/…La mejor solución que se me ocurrió es cambiar al uso
position: absolute;
de enfoque y calcular la posición en la que estaba cuando se estaba usandoposition: fixed;
. El truco es que elfocus
evento se activa demasiado tarde, por lo quetouchstart
debe utilizarse.La solución en esta respuesta imita muy de cerca el comportamiento correcto que tuvimos en iOS 7.
Requisitos:
El
body
elemento debe tener un posicionamiento para asegurar un posicionamiento adecuado cuando el elemento cambia a posicionamiento absoluto.El código ( ejemplo en vivo ):
El siguiente código es un ejemplo básico para el caso de prueba proporcionado y se puede adaptar para su caso de uso específico.
Aquí está el mismo código sin el truco para comparar .
Consideración:
Si el
position: fixed;
elemento tiene cualquier otro elemento padre con posicionamiento ademásbody
, cambiar aposition: absolute;
puede tener un comportamiento inesperado. Debido a la naturaleza deposition: fixed;
esto, probablemente no sea un problema importante, ya que anidar dichos elementos no es común.Recomendaciones:
Si bien el uso del
touchstart
evento filtrará la mayoría de los entornos de escritorio, es probable que desee utilizar el rastreo de agentes de usuario para que este código solo se ejecute para el iOS 8 roto, y no para otros dispositivos como Android y versiones anteriores de iOS. Desafortunadamente, todavía no sabemos cuándo Apple solucionará este problema en iOS, pero me sorprendería que no se solucione en la próxima versión principal.fuente
¡Encontré un método que funciona sin la necesidad de cambiar a la posición absoluta!
Código completo sin comentarios
Rompiéndolo
Primero, debe tener el campo de entrada fijo hacia la parte superior de la página en el HTML (es un elemento fijo, por lo que debería tener sentido semánticamente tenerlo cerca de la parte superior de todos modos):
Luego, debe guardar la posición de desplazamiento actual en variables globales:
Entonces necesita una forma de detectar dispositivos iOS para que no afecte a las cosas que no necesitan la corrección (función tomada de https://stackoverflow.com/a/9039885/1611058 )
Ahora que tenemos todo lo que necesitamos, aquí está la solución :)
fuente
Pude solucionar esto para las entradas seleccionadas agregando un detector de eventos a los elementos seleccionados necesarios, luego desplazándome por un desplazamiento de un píxel cuando la selección en cuestión gana el foco.
Esta no es necesariamente una buena solución, pero es mucho más simple y confiable que las otras respuestas que he visto aquí. El navegador parece volver a renderizar / volver a calcular la posición: fija; atributo basado en el desplazamiento proporcionado en la función window.scrollBy ().
fuente
Al igual que Mark Ryan Sallee sugirió, descubrí que cambiar dinámicamente la altura y el desbordamiento de mi elemento de fondo es la clave; esto no le da a Safari nada para desplazarse.
Entonces, después de que finalice la animación de apertura del modal, cambie el estilo del fondo:
Cuando cierras el modal, cámbialo de nuevo:
Si bien otras respuestas son útiles en contextos más simples, mi DOM era demasiado complicado (gracias a SharePoint) para usar el intercambio de posición absoluta / fija.
fuente
¿Limpiamente? No.
Recientemente tuve este problema con un campo de búsqueda fijo en un encabezado fijo, lo mejor que puede hacer en este momento es mantener la posición de desplazamiento en una variable en todo momento y, al realizar la selección, hacer que la posición del elemento fijo sea absoluta en lugar de fija con una parte superior posición basada en la posición de desplazamiento del documento.
Sin embargo, esto es muy feo y todavía resulta en un extraño desplazamiento hacia adelante y hacia atrás antes de aterrizar en el lugar correcto, pero es lo más cercano que pude conseguir.
Cualquier otra solución implicaría anular la mecánica de desplazamiento predeterminada del navegador.
fuente
¡Esto ahora está arreglado en iOS 10.3!
Los hacks ya no deberían ser necesarios.
fuente
No me he ocupado de este error en particular, pero tal vez haya puesto un overflow: hidden; en el cuerpo cuando el área de texto está visible (o simplemente activa, según su diseño). Esto puede tener el efecto de no hacer que el navegador esté "hacia abajo" para desplazarse.
fuente
Una posible solución sería reemplazar el campo de entrada.
codepen
fuente
Ninguna de estas soluciones funcionó para mí porque mi DOM es complicado y tengo páginas de desplazamiento infinitas dinámicas, así que tuve que crear la mía propia.
Fondo: estoy usando un encabezado fijo y un elemento más abajo que se pega debajo de él una vez que el usuario se desplaza hacia abajo. Este elemento tiene un campo de entrada de búsqueda. Además, tengo páginas dinámicas agregadas durante el desplazamiento hacia adelante y hacia atrás.
Problema: en iOS, cada vez que el usuario hacía clic en la entrada en el elemento fijo, el navegador se desplazaba hasta la parte superior de la página. Esto no solo provocó un comportamiento no deseado, sino que también provocó que mi página dinámica se agregara en la parte superior de la página.
Solución esperada: sin desplazamiento en iOS (ninguno) cuando el usuario hace clic en la entrada en el elemento adhesivo.
Solución:
Requisitos: JQuery mobile es necesario para que funcionen las funciones startsroll y stopscroll.
Se incluye antirrebote para suavizar cualquier retraso creado por el elemento adhesivo.
Probado en iOS10.
fuente
Ayer salté algo como esto estableciendo la altura de #a a la altura máxima visible (la altura del cuerpo era en mi caso) cuando #b es visible
ex:
ps: perdón por el ejemplo tardío, solo noté que era necesario.
fuente
Tuve el problema, las siguientes líneas de código lo resolvieron por mí:
fuente