Estive procurando por uma solução do tipo "caixa de luz" que permita isso, mas ainda não a encontrei (sugira se souber de alguma).
O comportamento que estou tentando recriar é igual ao que você veria no Pinterest ao clicar em uma imagem. A sobreposição é rolável ( como em toda a sobreposição se move para cima como uma página na parte superior de uma página ), mas o corpo atrás da sobreposição é fixo.
Tentei criar isso apenas com CSS ( ou seja, uma div
sobreposição na parte superior da página e no corpooverflow: hidden
), mas isso não impede a div
rolagem.
Como impedir a rolagem do corpo / página, mas a rolagem dentro do contêiner de tela cheia?
Respostas:
Teoria
Observando a implementação atual do site do pinterest (isso pode mudar no futuro), quando você abre a sobreposição, uma
noscroll
classe é aplicada aobody
elemento eoverflow: hidden
é definida, portanto,body
não é mais rolável.A sobreposição (criado on-the-fly ou já dentro da página e tornada visível através
display: block
, não faz diferença) temposition : fixed
eoverflow-y: scroll
, comtop
,left
,right
ebottom
propriedades definido para0
: esse estilo faz a sobreposição de preencher toda a janela.A parte
div
interna da sobreposição é apenasposition: static
a barra de rolagem vertical que você vê relacionada a esse elemento. Como resultado, o conteúdo é rolável, mas a sobreposição permanece fixa.Quando você fecha o zoom, oculta a sobreposição (via
display: none
) e também pode removê-la completamente via javascript (ou apenas o conteúdo interno, cabe a você como injetá-la).Como etapa final, você também deve remover a
noscroll
classe parabody
(para que a propriedade overflow retorne ao seu valor inicial)Código
(funciona alterando o
aria-hidden
atributo da sobreposição para mostrá-lo e ocultá-lo e aumentar sua acessibilidade).Marcação
(botão aberto)
(botão de sobreposição e fechamento)
CSS
Javascript (baunilha-JS)
Finalmente, aqui está outro exemplo no qual a sobreposição é aberta com um efeito de desvanecimento por um CSS
transition
aplicado àopacity
propriedade. Tambémpadding-right
é aplicado um para evitar um refluxo no texto subjacente quando a barra de rolagem desaparecer.CSS
fonte
div
deve ter estilo CSSposition:fixed
e rolagem de estouro vertical. Usei com sucessooverflow-y:auto;
e, para rolagem de momento / inércia do iOS, adicionei-webkit-overflow-scrolling:touch;
ao CSS. Eu useidisplay:block;
,width:100%;
eheight:100%;
CSS para ter uma janela de exibição de página inteira.Se você deseja evitar o excesso de rolagem no ios, é possível adicionar a posição fixa à sua classe .noscroll
fonte
position:fixed
é que ele estava redimensionando meu corpo principal. Talvez tenha sido em conflito com outro CSS, masoverflow:hidden
é tudo o que era necessárioNão use
overflow: hidden;
onbody
. Rola automaticamente tudo para o topo. Também não há necessidade de JavaScript. Fazer uso deoverflow: auto;
. Essa solução ainda funciona com o Safari móvel:Estrutura HTML
Styling
Veja a demonstração aqui e o código fonte aqui .
Atualizar:
Para as pessoas que desejam que a barra de espaço do teclado funcione, faça a página para cima / para baixo: você precisa se concentrar na sobreposição, por exemplo, clicando nela, ou manualmente, JS focando nela antes que essa parte do
div
teclado responda. O mesmo acontece quando a sobreposição é "desativada", pois está apenas movendo a sobreposição para o lado. Caso contrário, para o navegador, estes são apenas dois se normaisdiv
e não saberia por que deveria se concentrar em nenhum deles.fonte
html, body { height: 100%; }
(como na demonstração) para que isso funcione corretamente..offset()
valores para o cálculo fica confuso, etc ...overscroll-behavior
A propriedade css permite substituir o comportamento de rolagem de estouro padrão do navegador ao atingir a parte superior / inferior do conteúdo.Basta adicionar os seguintes estilos para sobrepor:
Atualmente trabalha no Chrome, Firefox e IE ( caniuse )
Para mais detalhes, consulte o artigo de desenvolvedores do Google .
fonte
overflow-y: scroll
(da sua demo do Codepen). O argumento levantado por @pokrishka é válido, mas no meu caso não é uma preocupação. De qualquer forma, gostaria de saber se as implementações dos navegadores cobrirão esses detalhes no futuro. Descobri que, no Firefox, redimensionando o navegador para que o modal não caiba na tela e redimensionando-o novamente para que essa propriedade funcione (por exemplo, a rolagem é contida) mesmo após o redimensionamento para o tamanho original - até que a página seja recarregada , finalmente.A maioria das soluções tem o problema de não manter a posição de rolagem, então dei uma olhada em como o Facebook faz isso. Além de definir o conteúdo subjacente,
position: fixed
eles também definem a parte superior dinamicamente para manter a posição de rolagem:Em seguida, quando você remover a sobreposição novamente, precisará redefinir a posição de rolagem:
Criei um pequeno exemplo para demonstrar esta solução
fonte
Vale notar que, às vezes, adicionar "overflow: hidden" à tag body não funciona. Nesses casos, você também precisará adicionar a propriedade à tag html.
fonte
width: 100%; height: 100%;
De um modo geral, se você deseja que um pai (o corpo neste caso) impeça a rolagem quando uma criança (a sobreposição nesse caso) rola, faça do filho um irmão do pai para impedir que o evento de rolagem borbulhe até o pai. No caso de o pai ser o corpo, isso requer um elemento adicional de empacotamento:
Consulte Rolar conteúdo específico de DIV com a barra de rolagem principal do navegador para ver seu funcionamento.
fonte
A resposta escolhida está correta, mas tem algumas limitações:
<body>
no fundo<input>
em um no modal direcionará todos os pergaminhos futuros para<body>
Não tenho uma correção para o primeiro problema, mas queria esclarecer o segundo. Confusamente, o Bootstrap costumava documentar o problema do teclado, mas eles alegaram que o problema foi corrigido, citando http://output.jsbin.com/cacido/quiet como um exemplo da correção.
Na verdade, esse exemplo funciona bem no iOS com meus testes. No entanto, atualizá-lo para o Bootstrap mais recente (v4) o interrompe.
Na tentativa de descobrir qual era a diferença entre eles, reduzi um caso de teste para não depender mais do Bootstrap, http://codepen.io/WestonThayer/pen/bgZxBG .
Os fatores decisivos são bizarros. Evitar o problema do teclado parece exigir que
background-color
não esteja definido na raiz que<div>
contém o modal e o conteúdo do modal deve ser aninhado em outro<div>
, que possa ter sidobackground-color
definido.Para testá-lo, remova o comentário da linha abaixo no exemplo do Codepen:
fonte
Para dispositivos sensíveis ao toque, tente adicionar uma
101vh
div transparente de 1px de largura e altura mínima no invólucro da sobreposição. Então adicione-webkit-overflow-scrolling:touch; overflow-y: auto;
ao invólucro. Isso faz o safari móvel pensar que a sobreposição é rolável, interceptando o evento de toque do corpo.Aqui está uma página de amostra. Abra no safari móvel: http://www.originalfunction.com/overlay.html
https://gist.github.com/YarGnawh/90e0647f21b5fa78d2f678909673507f
fonte
-webkit-overflow-scrolling:touch;
para cada contêiner rolável para interceptar eventos de toque.O comportamento que você deseja impedir é chamado de encadeamento de rolagem. Para desativá-lo, defina
na sua sobreposição em CSS.
fonte
Eu encontrei esta pergunta tentando resolver o problema que tive com minha página no Ipad e no iPhone - o corpo estava rolando quando eu exibia div fixo como pop-up com imagem.
Algumas respostas são boas, mas nenhuma delas resolveu meu problema. Encontrei a seguinte postagem no blog de Christoffer Pettersson. A solução apresentada ajudou a solucionar o problema que tive com os dispositivos iOS e o meu problema de rolagem em segundo plano.
Seis coisas que aprendi sobre a rolagem de elástico do iOS Safari
Como foi sugerido, incluo os principais pontos da postagem do blog, caso o link fique desatualizado.
"Para desativar que o usuário possa rolar a página de plano de fundo enquanto o" menu está aberto ", é possível controlar quais elementos devem ou não ser rolados, aplicando algum JavaScript e uma classe CSS.
Com base nesta resposta do Stackoverflow, você pode controlar se os elementos com a rolagem de desativação não devem executar sua ação de rolagem padrão quando o evento touchmove for acionado. "
E, em seguida, coloque a classe desativar-rolagem na página div:
fonte
Você pode fazer isso facilmente com alguns "novos" css e JQuery.
Inicialmente:
body {... overflow:auto;}
Com o JQuery, você pode alternar dinamicamente entre 'overlay' e 'body'. Quando estiver no 'corpo', useQuando em 'overlay', use
JQuery para o switch ('body' -> 'overlay'):
JQuery para o switch ('overlay' -> 'body'):
fonte
Eu gostaria de adicionar respostas anteriores porque tentei fazer isso, e algum layout foi interrompido assim que mudei o corpo para a posição: fixo. Para evitar isso, eu também precisava definir a altura do corpo para 100%:
fonte
Use o seguinte HTML:
Em seguida, JavaScript para interceptar e parar de rolar:
Então, para que as coisas voltem ao normal:
$(".page").off("touchmove");
fonte
Se a intenção é desativar em dispositivos móveis / touch, a maneira mais direta de fazer isso é usando
touch-action: none;
.Exemplo:
(O exemplo não funciona no contexto de Estouro de pilha. Você precisará recriá-lo em uma página independente.)
Se você deseja desativar a rolagem do
#app
contêiner, basta adicionartouch-action: none;
.fonte
tente isso
fonte
Se você deseja interromper a rolagem body / html, adicione o seguinte
CSS
HTML
Basicamente, você poderia fazer isso sem JS.
A idéia principal é adicionar html / body com height: 100% e overflow: auto. e dentro da sua sobreposição, você pode ativar / desativar a rolagem com base nos seus requisitos.
Espero que isto ajude!
fonte
No meu caso, nenhuma dessas soluções funcionou no iPhone (iOS 11.0).
A única solução eficaz que está funcionando em todos os meus dispositivos é esta: ios-10-safari-impedir-rolagem-atrás-de-uma-sobreposição-fixa-e-manter-posição-rolagem
fonte
Use o código abaixo para desativar e ativar a barra de rolagem.
fonte