Impedir que a barra de rolagem seja adicionada à largura da página no Chrome

125

Eu tenho um pequeno problema ao tentar manter minhas páginas .html em uma largura consistente no Chrome, por exemplo, eu tenho uma página (1) com muito conteúdo que ultrapassa a altura da janela de visualização (palavra certa?), Então há uma barra de rolagem vertical nessa página (1). Na página (2) eu tenho o mesmo layout (menus, divs, ... etc), mas menos conteúdo, portanto, não há barras de rolagem verticais.

O problema é que na página (1) as barras de rolagem parecem empurrar os elementos ligeiramente para a esquerda (somando-se à largura?) Enquanto tudo parece bem centralizado na página (2)

Ainda sou um iniciante em HTML / CSS / JS e estou bastante convencido de que isso não é tão difícil, mas não tive sorte em descobrir a solução. Funciona como esperado no IE10 e FireFox (barras de rolagem não interferentes), só encontrei isso no Chrome.

Acemad
fonte

Respostas:

42

Você pode obter o tamanho da barra de rolagem e aplicar uma margem ao contêiner.

Algo assim:

var checkScrollBars = function(){
    var b = $('body');
    var normalw = 0;
    var scrollw = 0;
    if(b.prop('scrollHeight')>b.height()){
        normalw = window.innerWidth;
        scrollw = normalw - b.width();
        $('#container').css({marginRight:'-'+scrollw+'px'});
    }
}

CSS para remover a barra de rolagem h:

body{
    overflow-x:hidden;
}

Tente dar uma olhada nisso: http://jsfiddle.net/NQAzt/

Lwyrn
fonte
1
Solução inteligente, mas não entendo a condição no 'se'!
Acemad
3
O scrollHeight é a altura total de um elemento. O que você vê e o que está oculto. Um exemplo: sua janela tem 500px de altura, o corpo tem um conteúdo de 900px. 500px são mostrados, mas os outros 400px estão ocultos e a barra de rolagem aparecerá para mostrar este pixel remanescente. Portanto, a condição é como "se a altura de todo o conteúdo for maior que a altura do ponto de vista, adicione a margem ao corpo". Desculpe pelo meu inglês ruim
Lwyrn,
Entendi agora, obrigado pela explicação clara, tentei esta solução e consegui uma barra de rolagem horizontal adicional, mas não sei por quê.
Acemad,
2
Eu adicionei um pequeno pedaço de css para evitar isso na resposta :)
Lwyrn
4
Esta solução desativa a rolagem
avalanche1 de
117

AVISO LEGAL : a sobreposição foi descontinuada .
Você ainda pode usar isso se for absolutamente necessário, mas tente não fazer.

Isso só funciona em navegadores WebKit , mas gosto muito. Se comportará como autoem outros navegadores.

.yourContent{
   overflow-y: overlay;
}

Isso fará com que a barra de rolagem apareça apenas como uma sobreposição , não afetando a largura do seu elemento!

simonDos
fonte
Não está funcionando para o IE11. Existe alguma solução alternativa para o valor de sobreposição funcionar no IE.
Anvesh Reddy
não que eu saiba, você terá que se contentar com as outras opções propostas neste tópico para o IE
simonDos
Muito necessário! Levei mais de meia hora para ver o que diabos eu fiz de errado com minha marcação. Que estilos eu usei demais? Este também deve ser o padrão.
kushalvm
3
Mas está obsoleto
Akash Yellappa
1
Eu atualizei a solução para refletir isso. Meio triste: P
simonDos
57

Tudo que você precisa fazer é adicionar:

html {
    overflow-y: scroll;
}

No seu arquivo css, pois este terá o rolador, seja necessário ou não, embora você simplesmente não consiga rolar

Isso significa que a janela de visualização terá a mesma largura para ambos

Hive7
fonte
4
então, eu sou obrigado a adicionar barras de rolagem a ambos? não há uma maneira de simplesmente ignorar a largura da barra de rolagem vertical? Obrigado !
Acemad
Não há nenhuma maneira de ignorar que eu saiba, mas o que eu disse funciona muito bem @ Rockr90
Hive7
@ d3c0y isso é verdade e mencionei isso na resposta, mas é o método mais fácil de fazer isso. Não sei se isso mudou nos últimos 3 anos
Hive7
@aks. força o navegador a pensar que você pode rolar, então habilita a barra de rolagem e rolar y é o
rolador
1
overflow-y: scroll; irá adicionar / mostrar a barra de rolagem em todas as janelas de exibição, mesmo que não haja elementos roláveis.
Abhilash
35

Provavelmente

html {
    width: 100vw;
}

é exatamente o que você deseja.

Neurotransmissor
fonte
1
Isso funcionou muito bem para o meu caso de uso: gist.github.com/bmcminn/1ab50da18bde75f39bc88e8292a5a847 Estou usando calc()para determinar a largura da visualização do conteúdo principal para que o navegador fixo fora da tela possa ocupar o lado esquerdo da tela na área de trabalho, preservando o nativo rolar no celular.
bmcminn
3
Tenho mexido nas minhas barras de rolagem nas últimas 36 horas. Tive algumas soluções diferentes que funcionaram, mas levantaram outras questões. Esta é a primeira solução que funciona e me permite usar uma barra de rolagem normal em outro lugar. Obrigado.
kosher
De nada! Mas mexer com htmla largura de em vws é um pouco complicado , então tenha cuidado!
Neurotransmissor de
Isso funcionou muito bem, alguém pode explicar como isso funciona?
Zeus
1
A solução não é ruim, mas pode adicionar rolagem horizontal.
FDisk
18

Navegadores Webkit como Safari e Chrome subtraem a largura da barra de rolagem da largura visível da página ao calcular a largura: 100% ou 100vw. Mais em Scrolling and Page Width de DM Rutherford .

Tente usar em seu overflow-y: overlaylugar.

Kyle Dumovic
fonte
9
Por favor, não poste respostas idênticas para várias perguntas. Poste uma boa resposta e, em seguida, vote / sinalize para fechar as outras questões como duplicatas. Se a pergunta não for uma duplicata, adapte suas respostas à pergunta.
Paul Roub
Isso deve funcionar, mas a sobreposição ainda não é padrão nem é compatível com todos os navegadores.
Zia Ul Rehman Mughal
Soluço rápido: no Safari, isso fazia com que a página parasse de rolar
joshfindit
13

Eu descobri que poderia adicionar

::-webkit-scrollbar { 
display: none; 
}

diretamente para o meu css e tornaria a barra de rolagem invisível, mas ainda me permitiria rolar (no Chrome, pelo menos). Bom para quando você não quer uma barra de rolagem perturbadora em sua página!

fuzzy_logic_77
fonte
5
É um tanto arriscado e não é uma solução para vários navegadores, embora stackoverflow.com/questions/9251354/…
Alex Pyzhianov
4

Para contêineres com largura fixa, uma solução cruzada de navegador CSS puro pode ser realizada envolvendo o contêiner em outro div e aplicando a mesma largura a ambos os divs.

#outer {
  overflow-y: auto;
  overflow-x: hidden;
  /*
   * width must be an absolute value otherwise the inner divs width must be set via
   * javascript to the computed width of the parent container
   */
  width: 200px;
}

#inner {
  width: inherit;
}

Clique aqui para ver um exemplo no Codepen

Robbendebiene
fonte
3

Não parece que minha outra resposta esteja funcionando bem no momento (mas vou continuar tentando colocá-la em operação).

Mas basicamente o que você precisa fazer, e o que ele estava tentando fazer dinamicamente, é definir a largura do conteúdo para um pouco menos do que a do painel pai rolável.
Assim, quando a barra de rolagem aparecer, ela não terá efeito sobre o conteúdo.

Este EXEMPLO mostra uma maneira mais hacky de atingir esse objetivo, codificando widths em vez de tentar fazer com que o navegador faça isso por nós via padding.
Se isso for viável, esta é a solução mais simples se você não quiser uma barra de rolagem permanente.

Hashbrown
fonte
Essa é uma boa solução, porém estou trabalhando em um site responsivo usando Bootstrap, e é importante automatizar a largura e tudo, o que você me diz?
Acemad
bem, a menos (em ordem de probabilidade decrescente): alguém descubra como fazer minha outra resposta funcionar (com preenchimento ou margem); você pode, de alguma forma, usar consultas de mídia para aplicar preenchimento seletivamente; ou expressões css são implementadas em navegadores modernos para aplicar preenchimento seletivamente. Acho que apenas uma barra de rolagem permanente ou usar JS para detectar a barra de rolagem é o caminho a percorrer
Hashbrown
1

EDITAR: esta resposta não está totalmente certa no momento, consulte minha outra resposta para ver o que eu estava tentando fazer aqui. Estou tentando consertar, mas se puderem ajudar nos comentários, obrigado!

O uso padding-rightirá mitigar o aparecimento repentino de uma barra de rolagem

EXEMPLO

Chrome Devtools mostrando preenchimento inalterado

Como você pode ver pelos pontos, o texto vai para o mesmo ponto na página antes de quebrar, independentemente de haver ou não uma barra de rolagem.
Isso ocorre porque quando uma barra de rolagem é introduzida, o preenchimento fica oculto atrás dela, então a barra de rolagem não empurra o texto!

Hashbrown
fonte
3
A largura da barra de rolagem pode mudar depende de qual sistema operacional e navegador você está usando. Pode medir 20 px, bem como
40 px
2
bem, você usaria o máximo de todos os valores possíveis
Hashbrown
1
Alguns dispositivos / scrolls do navegador do sistema operacional nem mesmo têm largura.
Sergey Goliney de
0
.modal-dialog {
   position: absolute;
   left: calc(50vw - 300px);
}

onde 300 px é a metade da largura da minha janela de diálogo.

Esta é realmente a única coisa que funcionou para mim.

Piotr Siatkowski
fonte
0

Eu tive o mesmo problema no Chrome. Só aconteceu para mim quando a barra de rolagem está sempre visível. (encontrado nas configurações gerais) Eu tenho um modal e quando abro o modal percebi que ...

body {
    padding-left: 15px;
}

é adicionado ao corpo. Para impedir que isso aconteça, acrescentei

body {
    padding-left: 0px !important;
}
NatD
fonte
0

Não consigo adicionar comentários para a primeira resposta e já faz muito tempo ... mas essa demonstração tem um problema:

if(b.prop('scrollHeight')>b.height()){
    normalw = window.innerWidth;
    scrollw = normalw - b.width();
    $('#container').css({marginRight:'-'+scrollw+'px'});
}

b.prop ('scrollHeight') sempre é igual a b.height (),

Acho que deveria ser assim:

if(b.prop('scrollHeight')>window.innerHeight) ...

Por fim, recomendo um método:

html {
 overflow-y: scroll;
}

:root {
  overflow-y: auto;
  overflow-x: hidden;
}

:root body {
  position: absolute;
}

body {
 width: 100vw;
 overflow: hidden;
}
jeremy
fonte