Empêcher la barre de défilement de s'ajouter à la largeur de la page sur Chrome

125

J'ai un petit problème en essayant de garder mes pages .html à une largeur cohérente sur Chrome, par exemple j'ai une page (1) avec beaucoup de contenu qui dépasse la hauteur de la fenêtre (mot correct?), Donc il y a une barre de défilement verticale sur cette page (1). Sur la page (2), j'ai la même disposition (menus, divs, ... etc) mais moins de contenu, donc pas de barres de défilement verticales là-dedans.

Le problème est que sur la page (1) les barres de défilement semblent pousser légèrement les éléments vers la gauche (s'ajoutant à la largeur?) Alors que tout semble bien centré sur la page (2)

Je suis encore un débutant en HTML / CSS / JS, et je suis assez convaincu que ce n'est pas si difficile, mais je n'ai pas eu de chance de trouver la solution. Cela fonctionne comme prévu sur IE10 et FireFox (barres de défilement non interférentes), je ne l'ai rencontré que sur Chrome.

Acemad
la source

Réponses:

42

Vous pouvez obtenir la taille de la barre de défilement, puis appliquer une marge au conteneur.

Quelque chose comme ça:

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 pour supprimer la barre de défilement h:

body{
    overflow-x:hidden;
}

Essayez de jeter un œil à ceci: http://jsfiddle.net/NQAzt/

Lwyrn
la source
1
Solution intelligente, je ne comprends pas la condition dans le «si» cependant!
Acemad
3
ScrollHeight est la hauteur totale d'un élément. Ce que vous voyez et ce qui est caché. Un exemple: votre fenêtre mesure 500px de hauteur, le corps a un contenu de 900px. 500px sont affichés mais les 400px restants sont masqués et la barre de défilement apparaîtra pour afficher ce pixel restant. Donc, la condition est comme "si la hauteur de tout le contenu est supérieure à la hauteur du point de vue, ajoutez la marge au corps". Désolé pour mon mauvais anglais
Lwyrn
Je l'ai maintenant, merci pour l'explication claire, j'ai essayé cette solution et j'ai obtenu une barre de défilement horizontale supplémentaire, je ne sais pas pourquoi.
Acemad le
2
J'ai ajouté un petit morceau de css pour l'empêcher dans la réponse :)
Lwyrn
4
Cette solution désactive le défilement
avalanche1
117

DISCLAIMER : la superposition est obsolète .
Vous pouvez toujours l'utiliser si vous devez absolument le faire, mais essayez de ne pas le faire.

Cela ne fonctionne que sur les navigateurs WebKit , mais je l'aime beaucoup. Se comportera comme autosur les autres navigateurs.

.yourContent{
   overflow-y: overlay;
}

Cela fera apparaître la barre de défilement uniquement comme une superposition , n'affectant donc pas la largeur de votre élément!

simonDos
la source
Cela ne fonctionne pas pour IE11. Y a-t-il une solution pour que la valeur de superposition fonctionne dans IE.
Anvesh Reddy
pas pour autant que je sache, vous devrez vous contenter des autres options proposées dans ce fil pour IE
simonDos
Très nécessaire! J'ai mis plus d'une demi-heure pour voir ce que j'ai fait de mal avec mon balisage. Quels styles ai-je abusé? Cela devrait également être la valeur par défaut.
kushalvm
3
Mais il est obsolète
Akash Yellappa
1
J'ai mis à jour la solution pour refléter cela. Kinda sad: P
simonDos
57

Il ne vous reste plus qu'à ajouter:

html {
    overflow-y: scroll;
}

Dans votre fichier css, il y aura le défilement, qu'il soit nécessaire ou non, bien que vous ne puissiez tout simplement pas faire défiler

Cela signifie que la fenêtre aura la même largeur pour les deux

Ruche7
la source
4
alors, je suis obligé d'ajouter des barres de défilement aux deux? n'y a-t-il pas un moyen d'ignorer simplement la largeur de la barre de défilement verticale? Je vous remercie !
Acemad
Il n'y a aucun moyen de l'ignorer que je sache, mais ce que j'ai dit fonctionne un régal @ Rockr90
Hive7
@ d3c0y c'est vrai et je l'ai mentionné dans la réponse mais c'est la méthode la plus simple pour le faire. Je ne sais pas si cela a changé au cours des 3 dernières années
Hive7
@aks. cela oblige le navigateur à penser que vous pouvez faire défiler, donc permet de faire défiler la barre et de faire défiler y est le défilement latéral
Hive7
1
overflow-y: faire défiler; ajoutera / affichera la barre de défilement dans toutes les fenêtres même s'il n'y a pas d'éléments défilables.
Abhilash
35

Probablement

html {
    width: 100vw;
}

est exactement ce que vous voulez.

Neurotransmetteur
la source
1
Cela a très bien fonctionné pour mon cas d'utilisation: gist.github.com/bmcminn/1ab50da18bde75f39bc88e8292a5a847 J'utilise calc()pour déterminer la largeur de la vue principale du contenu afin que la navigation hors écran fixe puisse occuper le côté gauche de l'écran sur le bureau, tout en préservant le natif faites défiler sur mobile.
bmcminn
3
Je joue avec mes barres de défilement depuis 36 heures. J'ai eu quelques solutions différentes qui ont fonctionné, mais ont soulevé d'autres problèmes. C'est la première solution qui fonctionne à la fois et me permet d'utiliser une barre de défilement normale ailleurs. Je vous remercie.
casher
Vous êtes les bienvenus! Mais jouer avec htmlla largeur de vws en s est un peu piraté , alors soyez prudent!
Neurotransmetteur
Cela a très bien fonctionné, quelqu'un peut-il expliquer comment cela fonctionne?
Zeus
1
Solution pas mal, mais cela pourrait ajouter un défilement horizontal.
FDisk
18

Les navigateurs Webkit comme Safari et Chrome soustraient la largeur de la barre de défilement de la largeur de page visible lors du calcul de la largeur: 100% ou 100vw. Plus d'informations sur le défilement et la largeur de page de DM Rutherford .

Essayez d'utiliser à la overflow-y: overlayplace.

Kyle Dumovic
la source
9
Veuillez ne pas publier de réponses identiques à plusieurs questions. Publiez une bonne réponse, puis votez / marquez pour fermer les autres questions comme des doublons. Si la question n'est pas un doublon, adaptez vos réponses à la question.
Paul Roub
Cela devrait fonctionner, mais la superposition n'est pas encore standard et n'est pas non plus prise en charge dans tous les navigateurs.
Zia Ul Rehman Mughal
Problème rapide: dans Safari, cela a provoqué l'arrêt du défilement de la page
joshfindit
13

J'ai trouvé que je pourrais ajouter

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

directement dans mon css et cela rendrait la barre de défilement invisible, mais me permettrait toujours de faire défiler (sur Chrome au moins). Bon lorsque vous ne voulez pas d'une barre de défilement distrayante sur votre page!

fuzzy_logic_77
la source
5
C'est une solution quelque peu risquée et non multi-navigateurs si stackoverflow.com/questions/9251354/…
Alex Pyzhianov
4

Pour les conteneurs de largeur fixe, une solution de navigateur croisé CSS pure peut être réalisée en enveloppant le conteneur dans un autre div et en appliquant la même largeur aux deux 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;
}

Cliquez ici pour voir un exemple sur Codepen

Robbendebiene
la source
3

Il ne semble pas que mon autre réponse fonctionne tout à fait correctement pour le moment (mais je continuerai d'essayer de la rendre opérationnelle).

Mais fondamentalement, ce que vous devrez faire, et ce qu'il essayait de faire de manière dynamique, c'est de définir la largeur du contenu à un peu moins que celle du volet défilable parent.
Ainsi, lorsque la barre de défilement apparaît, elle n'a aucun effet sur le contenu.

Cet EXEMPLE montre une manière plus pirate d'atteindre cet objectif, en codant en dur les widths au lieu d'essayer de faire en sorte que le navigateur le fasse pour nous via padding.
Si cela est possible, c'est la solution la plus simple si vous ne voulez pas d'une barre de défilement permanente.

Hashbrown
la source
C'est une bonne solution, mais je travaille sur un site Web réactif utilisant Bootstrap, et il est important d'automatiser la largeur et tout, que dites-vous?
Acemad
à moins que (par ordre de probabilité décroissante) soit: quelqu'un trouve comment faire fonctionner mon autre réponse (avec un rembourrage ou une marge); vous pouvez en quelque sorte utiliser des requêtes multimédias pour appliquer le remplissage de manière sélective; ou les expressions css sont implémentées dans les navigateurs modernes pour appliquer sélectivement le remplissage. Je pense que seule une barre de défilement permanente ou l'utilisation de JS pour détecter la barre de défilement est la voie à suivre
Hashbrown
1

EDIT: cette réponse n'est pas tout à fait correcte pour le moment, reportez-vous à mon autre réponse pour voir ce que j'essayais de faire ici. J'essaie de résoudre le problème, mais si vous pouvez offrir de l'aide, faites-le dans les commentaires, merci!

L'utilisation padding-rightatténuera l'apparition soudaine d'une barre de défilement

EXEMPLE

Chrome devtools montrant le remplissage non déplacé

Comme vous pouvez le voir à partir des points, le texte arrive au même point de la page avant de s'habiller, indépendamment du fait qu'une barre de défilement soit présente ou non.
En effet, lorsqu'une barre de défilement est introduite, le remplissage se cache derrière elle, donc la barre de défilement ne pousse pas sur le texte!

Hashbrown
la source
3
La largeur de la barre de défilement peut changer en fonction du système d'exploitation et du navigateur que vous utilisez. Il peut mesurer 20px ainsi que 40px
Lwyrn
2
Eh
1
Les parchemins de certains appareils / navigateurs OS n'ont même pas de largeur.
Sergey Goliney
0
.modal-dialog {
   position: absolute;
   left: calc(50vw - 300px);
}

où 300 px est la moitié de la largeur de ma fenêtre de dialogue.

C'est en fait la seule chose qui a fonctionné pour moi.

Piotr Siatkowski
la source
0

J'ai eu le même problème sur Chrome. Cela ne m'est arrivé que lorsque la barre de défilement est toujours visible. (trouvé dans les paramètres généraux) J'ai un modal et quand j'ouvre le modal j'ai remarqué que ...

body {
    padding-left: 15px;
}

est ajouté au corps. Pour empêcher cela, j'ai ajouté

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

Je ne peux pas ajouter de commentaire pour la première réponse et cela fait longtemps ... mais cette démo a un problème:

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

b.prop ('scrollHeight') vaut toujours b.height (),

Je pense que ça devrait être comme ça:

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

Enfin je recommande une méthode:

html {
 overflow-y: scroll;
}

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

:root body {
  position: absolute;
}

body {
 width: 100vw;
 overflow: hidden;
}
Jeremy
la source