He estado buscando una solución de tipo "caja de luz" que permita esto, pero aún no he encontrado una (por favor, sugiera si conoce alguna).
El comportamiento que intento recrear es como el que verías en Pinterest al hacer clic en una imagen. La superposición es desplazable ( como en toda la superposición se mueve hacia arriba como una página en la parte superior de una página ) pero el cuerpo detrás de la superposición está fijo.
Intenté crear esto solo con CSS ( es decir, una div
superposición en la parte superior de toda la página y el cuerpooverflow: hidden
), pero no impide que se div
pueda desplazar.
¿Cómo evitar que el cuerpo / página se desplace pero siga desplazándose dentro del contenedor de pantalla completa?
Respuestas:
Teoría
Al observar la implementación actual del sitio pinterest (puede cambiar en el futuro), cuando abre la superposición
noscroll
, se aplica una clase albody
elemento yoverflow: hidden
se establece, porbody
lo que ya no se puede desplazar.La superposición (creado en la marcha o ya dentro de la página y se hace visible a través
display: block
, no hay diferencia) tieneposition : fixed
yoverflow-y: scroll
, contop
,left
,right
ybottom
propiedades definidas0
: este estilo hace que la superposición de llenar toda la ventana gráfica.El
div
interior de la superposición está en su lugar justoposition: static
entonces, la barra de desplazamiento vertical que ves está relacionada con ese elemento. Como resultado, el contenido es desplazable pero la superposición permanece fija.Cuando cierra el zoom, oculta la superposición (a través de
display: none
) y luego también puede eliminarla por completo a través de javascript (o solo el contenido dentro, depende de usted cómo inyectarlo).Como paso final, también debe eliminar la
noscroll
clasebody
(para que la propiedad de desbordamiento vuelva a su valor inicial)Código
(funciona cambiando el
aria-hidden
atributo de la superposición para mostrarlo y ocultarlo y aumentar su accesibilidad).Marcado
(botón de apertura)
(botón de superposición y cierre)
CSS
Javascript (vanilla-JS)
Finalmente, aquí hay otro ejemplo en el que la superposición se abre con un efecto de desvanecimiento por un CSS
transition
aplicado a laopacity
propiedad. Tambiénpadding-right
se aplica a para evitar un reflujo en el texto subyacente cuando la barra de desplazamiento desaparece.CSS
fuente
div
debe tener un estilo CSSposition:fixed
y un desplazamiento vertical de desbordamiento. Utilicé con éxitooverflow-y:auto;
y para el desplazamiento de impulso / inercia de iOS, agregué-webkit-overflow-scrolling:touch;
al CSS. Solíadisplay:block;
,width:100%;
yheight:100%;
CSS para tener una vista de página completa.Si desea evitar el desplazamiento excesivo en ios, puede agregar una posición fija a su clase .noscroll
fuente
position:fixed
es que estaba cambiando el tamaño de mi cuerpo principal. Tal vez estaba en conflicto con otros CSS, perooverflow:hidden
es todo lo que se necesitabaNo utilice
overflow: hidden;
elbody
. Desplaza automáticamente todo a la parte superior. No hay necesidad de JavaScript tampoco. Hacer uso deoverflow: auto;
. Esta solución incluso funciona con Safari móvil:Estructura HTML
Estilo
Vea la demostración aquí y el código fuente aquí .
Actualizar:
Para las personas que desean la barra espaciadora del teclado, la página arriba / abajo funciona: debe enfocarse en la superposición, por ejemplo, hacer clic en ella, o JS se enfoca manualmente antes de que esta parte del
div
teclado responda. Lo mismo ocurre cuando la superposición está "apagada", ya que solo está moviendo la superposición hacia un lado. De lo contrario para el navegador, estos son solo dosdiv
s normales y no sabría por qué debería centrarse en ninguno de ellos.fuente
html, body { height: 100%; }
(como en la demostración) para que esto funcione correctamente..offset()
valores para el cálculo se cometa un error, etc ...overscroll-behavior
La propiedad css permite anular el comportamiento de desplazamiento de desbordamiento predeterminado del navegador al llegar a la parte superior / inferior del contenido.Simplemente agregue los siguientes estilos para superponer:
Actualmente funciona en Chrome, Firefox e IE ( caniuse )
Para más detalles, consulte el artículo de desarrolladores de Google .
fuente
overflow-y: scroll
Resolví con una combinación de esto con (de su demostración de Codepen). El punto planteado por @pokrishka es válido, pero en mi caso no es una preocupación. En cualquier caso, me pregunto si las implementaciones de los navegadores cubrirán este detalle en el futuro. Descubrí que, en Firefox, se cambia el tamaño del navegador para que el modal no se ajuste a la pantalla y luego se cambia el tamaño nuevamente para que haga que esta propiedad funcione (es decir, el desplazamiento está contenido) incluso después de cambiar el tamaño a tamaño completo, hasta que la página se vuelva a cargar , al menos.La mayoría de las soluciones tienen el problema de que no retienen la posición de desplazamiento, así que eché un vistazo a cómo lo hace Facebook. Además de configurar el contenido subyacente
position: fixed
, también configuran la parte superior dinámicamente para mantener la posición de desplazamiento:Luego, cuando elimine la superposición nuevamente, debe restablecer la posición de desplazamiento:
Creé un pequeño ejemplo para demostrar esta solución
fuente
Vale la pena señalar que a veces agregar "desbordamiento: oculto" a la etiqueta del cuerpo no funciona. En esos casos, también deberá agregar la propiedad a la etiqueta html.
fuente
width: 100%; height: 100%;
En términos generales, si desea que un padre (el cuerpo en este caso) evite que se desplace cuando un niño (la superposición en este caso) se desplaza, entonces haga que el niño sea hermano del padre para evitar que el evento de desplazamiento aumente el padre. En el caso de que el padre sea el cuerpo, esto requiere un elemento de envoltura adicional:
Consulte Desplazar contenidos DIV particulares con la barra de desplazamiento principal del navegador para ver su funcionamiento.
fuente
La respuesta elegida es correcta, pero tiene algunas limitaciones:
<body>
en el fondo<input>
en el modal, todos los desplazamientos futuros se dirigirán a<body>
No tengo una solución para el primer problema, pero quería arrojar algo de luz sobre el segundo. Confusamente, Bootstrap solía documentar el problema del teclado, pero afirmaron que se solucionó, citando http://output.jsbin.com/cacido/quiet como un ejemplo de la solución.
De hecho, ese ejemplo funciona bien en iOS con mis pruebas. Sin embargo, actualizarlo al último Bootstrap (v4) lo rompe.
En un intento por descubrir cuál era la diferencia entre ellos, reduje un caso de prueba para que ya no dependiera de Bootstrap, http://codepen.io/WestonThayer/pen/bgZxBG .
Los factores decisivos son extraños. Evitar el problema del teclado parece requerir que
background-color
no se establezca en la raíz que<div>
contiene el modal y el contenido del modal debe estar anidado en otro<div>
, que puede haberbackground-color
establecido.Para probarlo, descomente la línea siguiente en el ejemplo de Codepen:
fuente
Para dispositivos táctiles, intente agregar un
101vh
div transparente de 1px de ancho y altura mínima en la envoltura de la superposición. Luego añade-webkit-overflow-scrolling:touch; overflow-y: auto;
al envoltorio. Esto engaña al safari móvil para que piense que la superposición es desplazable, interceptando así el evento táctil del cuerpo.Aquí hay una página de muestra. Abrir en safari móvil: http://www.originalfunction.com/overlay.html
https://gist.github.com/YarGnawh/90e0647f21b5fa78d2f678909673507f
fuente
-webkit-overflow-scrolling:touch;
para cada contenedor desplazable para interceptar eventos táctiles.El comportamiento que desea evitar se llama encadenamiento de desplazamiento. Para deshabilitarlo, establezca
en tu superposición en CSS.
fuente
Encontré esta pregunta tratando de resolver el problema que tenía con mi página en Ipad y Iphone: el cuerpo se desplazaba cuando mostraba div fijo como ventana emergente con imagen.
Algunas respuestas son buenas, sin embargo, ninguna de ellas resolvió mi problema. Encontré la siguiente publicación de blog de Christoffer Pettersson. La solución presentada allí ayudó al problema que tenía con los dispositivos iOS y ayudó a mi problema de fondo de desplazamiento.
Seis cosas que aprendí sobre el desplazamiento de la banda de goma de iOS Safari
Como se sugirió, incluyo los puntos principales de la publicación del blog en caso de que el enlace quede desactualizado.
"Para deshabilitar que el usuario pueda desplazarse por la página de fondo mientras el" menú está abierto ", es posible controlar qué elementos deben permitirse desplazarse o no, aplicando JavaScript y una clase CSS.
Según esta respuesta de Stackoverflow , puede controlar que los elementos con el desplazamiento de desactivación no realicen su acción de desplazamiento predeterminada cuando se activa el evento de movimiento táctil ".
Y luego coloque la clase de desplazamiento de desactivación en la página div:
fuente
Puede hacerlo fácilmente con algunos "nuevos" css y JQuery.
Inicialmente:
body {... overflow:auto;}
con JQuery puede cambiar dinámicamente entre 'superposición' y 'cuerpo'. Cuando esté en 'cuerpo', useCuando está en uso 'superpuesto'
JQuery para el conmutador ('cuerpo' -> 'superposición'):
JQuery para el conmutador ('superposición' -> 'cuerpo'):
fuente
Me gustaría agregar a las respuestas anteriores porque intenté hacer eso, y algunos diseños se rompieron tan pronto como cambié el cuerpo a la posición: fijo. Para evitar eso, también tuve que establecer la altura del cuerpo al 100%:
fuente
Use el siguiente HTML:
Luego JavaScript para interceptar y detener el desplazamiento:
Luego, para que las cosas vuelvan a la normalidad:
$(".page").off("touchmove");
fuente
Si la intención es deshabilitar en dispositivos móviles / táctiles, entonces la forma más sencilla de hacerlo es mediante el uso
touch-action: none;
.Ejemplo:
(El ejemplo no funciona en el contexto de Desbordamiento de pila. Deberá volver a crearlo en una página independiente).
Si desea deshabilitar el desplazamiento del
#app
contenedor, simplemente agreguetouch-action: none;
.fuente
prueba esto
fuente
Si desea detener el desplazamiento del cuerpo / html, agregue lo siguiente
CSS
HTML
Básicamente, podrías hacerlo sin JS.
La idea principal es agregar html / body con height: 100% y overflow: auto. y dentro de su superposición, puede habilitar / deshabilitar el desplazamiento según sus requisitos.
¡Espero que esto ayude!
fuente
En mi caso, ninguna de estas soluciones funcionó en iPhone (iOS 11.0).
La única solución efectiva que funciona en todos mis dispositivos es esta: ios-10-safari-prevent-scrolling-behind-a-fixed-overlay-and-maintenance-scroll-position
fuente
Use el código a continuación para deshabilitar y habilitar la barra de desplazamiento.
fuente