Comment empêcher la barre de défilement de repositionner la page Web?

218

J'ai un site Web avec DIV aligné au centre. Maintenant, certaines pages ont besoin de défilement, d'autres non. Lorsque je passe d'un type à un autre, l'apparition d'une barre de défilement déplace la page de quelques pixels sur le côté. Existe-t-il un moyen d'éviter cela sans afficher explicitement les barres de défilement sur chaque page?

Dmitri Nesteruk
la source
6
Pourquoi personne ne mentionne overflow-y: overlaydans ce fil?
milkersarac
3
Selon les documents mozilla, overflow-y: overlayest déprécié: developer.mozilla.org/en-US/docs/Web/CSS/overflow
drojf

Réponses:

266

overflow-y: scroll est correct, mais vous devez l'utiliser avec la balise html, pas body, sinon vous obtenez une double barre de défilement dans IE 7
Ainsi, le bon css serait:

html {
  overflow-y: scroll;
}
Ruben
la source
1
IE 10+ a une barre de défilement flottante, vous devez donc la désactiver pour ces navigateurs
Ruben
1
cela peut provoquer des problèmes tels que les doubles barres de défilement lors de l'utilisation en combinaison avec fancybox ou twitter bootstrap modal
Ruben
info supplémentaire: le bootstrap twitter ajoute désormais .modal-open à votre corps lorsqu'un modal est ouvert
Ruben
55
Il convient de mentionner que cela montre en permanence une barre de défilement verticale. Peut ne pas toujours être acceptable.
rustyx
Je reçois une double barre de défilement dans Chromium et Firefox. J'utilise flex-box; peut-être que cela cause cela ...
Garrett
72

Enveloppez le contenu de votre élément déroulant dans un div et appliquez padding-left: calc(100vw - 100%);.

<body>
    <div style="padding-left: calc(100vw - 100%);">
        Some Content that is higher than the user's screen
    </div>
</body>

L'astuce est que cela 100vwreprésente 100% de la fenêtre, y compris la barre de défilement. Si vous soustrayez 100%, qui est l'espace disponible sans la barre de défilement, vous vous retrouvez avec la largeur de la barre de défilement ou 0si elle n'est pas présente. La création d'un remplissage de cette largeur à gauche simulera une deuxième barre de défilement, décalant le contenu centré vers la droite.

Veuillez noter que cela ne fonctionnera que si l'élément déroulant utilise toute la largeur de la page, mais cela ne devrait pas poser de problème la plupart du temps car il n'y a que peu d'autres cas où vous avez centré du contenu défilant.

Rapti
la source
1
Serait mieux appliqué via une classe qu'un style en ligne, et ne fonctionnera que dans ces navigateurs , mais c'est une technique intelligente - je ne l'avais pas réalisé 100vwet 100%mesuré différentes choses, j'ai donc appris quelque chose d'utile!
Nick F
21
C'est absolument génial et c'est vraiment la meilleure réponse étant donné que le support du navigateur pour calc est très bon.
michael
1
Vous pouvez faire de même sauf qu'au lieu d'ajouter une marge à gauche, vous ajoutez une marge négative à droite (voir stackoverflow.com/a/39289453/6015444 ).
Touniouk
2
Cette solution entraînera des problèmes similaires avec la couleur d'arrière-plan, comme la réponse "width: calc (100vw - 34px);" mais sur le côté gauche.
Maciej Lew
1
Je recommanderais d'ajouter quelques requêtes multimédias à ce style @media screen and (min-width: 800px) {...} . Dans les cas où le contenu s'adaptera à la largeur de la page. Par exemple sur les petites résolutions, il y aura un écart inutile, déplaçant le contenu vers la droite
MarkosyanArtur
44

Je crois que non. Mais styling bodyavec overflow: scrolldevrait faire. Vous semblez cependant le savoir.

Michael Krelin - pirate
la source
3
Cela sonne bien ... force la page à toujours afficher la barre de défilement, qu'elle en ait besoin ou non, ... alors il n'y a pas de changement visuel entre les types de page.
eidylon
1
Oui, mais IIRC, cela montre les deux barres de défilement. Je n'ai pas vraiment besoin de l'horizontale.
Dmitri Nesteruk
C'est vrai. Mais je ne peux pas faire grand-chose pour vous aider :( En fait, je ne considère que la première phrase de ma réponse comme la vraie réponse qui traite de la question.
Michael Krelin - pirate informatique le
49
overflow-y: scroll:)
Svish
2
Voici la meilleure réponse
Sami
36

Le défilement étant toujours affiché, ce n'est peut-être pas bon pour la mise en page.

Essayez de limiter la largeur du corps avec CSS3

body {
    width: calc(100vw - 34px);
}

vwest la largeur de la fenêtre d'affichage (voir ce lien pour des explications)
calccalculer dans css3
34pxsignifie largeur de barre de défilement double (voir ceci pour fixe ou ceci pour calculer si vous ne faites pas confiance aux tailles fixes)

Moesio
la source
4
Tout est futile jusqu'à ce que quelqu'un en ait besoin.
Moesio
3
C'est visuellement beaucoup moins intrusif que de simplement forcer des barres de défilement comme le décrit la réponse acceptée.
Silas Hansen
4
Cela a fonctionné le mieux pour mes besoins jusqu'à présent, j'ai également ajouté padding-left: 34px;pour centrer uniformément ma page.
Pat Migliaccio
3
Cela devrait être la réponse acceptée, contrairement à celle actuellement acceptée, elle répond en fait à la question!
Coz
2
Cela causera des problèmes si vous avez une barre de navigation / en-tête de couleur différente de l'arrière-plan du corps ou de la bordure inférieure, etc.
Zia Ul Rehman Mughal
28
html {
  overflow-x: hidden;
  margin-right: calc(-1 * (100vw - 100%));
}

Exemple . Cliquez sur le bouton "modifier la hauteur minimale".

Avec calc(100vw - 100%)nous pouvons calculer la largeur de la barre de défilement (et si elle n'est pas affichée, elle sera 0). Idée: en utilisant une marge négative à droite, nous pouvons augmenter la largeur de <html>cette largeur. Vous verrez une barre de défilement horizontale - elle doit être masquée à l'aide de overflow-x: hidden.

pongo
la source
J'ai dû mettre le corps dans un div et appliquer la marge au div pour qu'il fonctionne (similaire à la réponse de Rapti .) Mais cela semble tellement plus net.
Touniouk
1
Cela fonctionne très bien et ne semble pas entraîner de barres de défilement horizontales indésirables dans Chrome ou Firefox. Pourquoi ne pas simplement utiliser calc(100% - 100vw)au lieu de multiplier par -1?
SystemParadox
13

Je ne sais pas s'il s'agit d'un ancien message, mais j'ai eu le même problème et si vous souhaitez faire défiler verticalement, vous devriez essayer overflow-y:scroll


la source
13

Si vous changez de taille ou après avoir chargé certaines données, vous ajoutez la barre de défilement, vous pouvez essayer de suivre, créer une classe et appliquer cette classe.

.auto-scroll {
   overflow-y: overlay;
   overflow-x: overlay;
}
kunalkamble
la source
3

J'ai résolu le problème sur l'un de mes sites Web en définissant explicitement la largeur du corps en javascript par la taille de la fenêtre moins la largeur de la barre de défilement. J'utilise une fonction basée sur jQuery documentée ici pour déterminer la largeur de la barre de défilement.

<body id="bodyid>

var bodyid = document.getElementById('bodyid');
bodyid.style.width = window.innerWidth - scrollbarWidth() + "px";
Frank L
la source
10
Je ne peux même pas commencer à expliquer pourquoi c'est une si mauvaise pratique.
mythofechelon
20
@BenHooper: J'aimerais savoir pourquoi c'est une mauvaise pratique.
Saad
1
Que se passe-t-il si vous redimensionnez la fenêtre?
Braden Steffaniak
3

Développer la réponse en utilisant ceci:

body {
    width: calc(100vw - 17px);
}

Un commentateur a suggéré d'ajouter également un remplissage à gauche pour maintenir le centrage:

body {
    padding-left: 17px;
    width: calc(100vw - 17px);
}

Mais les choses ne semblent pas correctes si votre contenu est plus large que la fenêtre d'affichage. Pour résoudre ce problème, vous pouvez utiliser des requêtes multimédias, comme ceci:

@media screen and (min-width: 1058px) {
    body {
        padding-left: 17px;
        width: calc(100vw - 17px);
    }
}

Où le 1058px = largeur du contenu + 17 * 2

Cela permet à une barre de défilement horizontale de gérer le débordement x et de maintenir le contenu centré centré lorsque la fenêtre est suffisamment large pour contenir votre contenu à largeur fixe

Greg St.Onge
la source
3

S'étendant sur la réponse de Rapti , cela devrait tout aussi bien fonctionner, mais cela ajoute plus de marge sur le côté droit de la bodyet la masque avec une htmlmarge négative , au lieu d'ajouter un remplissage supplémentaire qui pourrait potentiellement affecter la mise en page de la page. De cette façon, rien n'est changé sur la page réelle (dans la plupart des cas), et le code est toujours fonctionnel.

html {
    margin-right: calc(100% - 100vw);
}
body {
    margin-right: calc(100vw - 100%);
}
Grant Gryczan
la source
J'ai trouvé que sur Chrome, cela ajoute un défilement horizontal sur les pages qui ont une barre de défilement verticale sur mon site bootstrap.
Ginger Squirrel
Avez-vous essayé de chercher pourquoi? Vérifiez l'inspecteur d'élément et voyez si Bootstrap ne respecte pas les marges, les barres de défilement ou quelque chose du genre.
Grant Gryczan
1
C'était probablement quelque chose à voir avec les marges de 15 pixels que le bootstrap met sur tout, lors de l'inspection de la page, la marge du conteneur tombe sous la barre de défilement. J'ai postulé overflow-x: hiddenet cela l'a corrigé.
Ginger Squirrel
3

La solution de @ kashesandr a fonctionné pour moi, mais pour masquer la barre de défilement horizontale, j'ai ajouté un autre style pour le corps. voici la solution complète:

CSS

<style>
/* prevent layout shifting and hide horizontal scroll */
html {
  width: 100vw;
}
body {
  overflow-x: hidden;
}
</style>

JS

$(function(){
    /**
     * For multiple modals.
     * Enables scrolling of 1st modal when 2nd modal is closed.
     */
    $('.modal').on('hidden.bs.modal', function (event) {
      if ($('.modal:visible').length) {
        $('body').addClass('modal-open');
      }
    });
});

Solution JS uniquement (lorsque le 2e modal est ouvert à partir du 1er modal):

/**
 * For multiple modals.
 * Enables scrolling of 1st modal when 2nd modal is closed.
 */
$('.modal').on('hidden.bs.modal', function (event) {
  if ($('.modal:visible').length) {
    $('body').addClass('modal-open');
    $('body').css('padding-right', 17);
  }
});
Hassan Tareq
la source
2

J'ai essayé de résoudre probablement le même problème que celui causé par la .modal-openclasse de bootstrap twitter appliqué body. La solution html {overflow-y: scroll}n'aide pas. Une solution possible que j'ai trouvée est d'ajouter {width: 100%; width: 100vw}à l' htmlélément.

kashesandr
la source
1
ou changez-le en body {overflow-y: scroll}
Ruben
1
Mais cela afficherait toujours une barre de défilement même si elle n'est pas requise.
Rapti
Vous devez expliquer pourquoi définissez-vous la largeur deux fois? html { width: 100vw; }a travaillé pour moi
Hassan Tareq
Pour moi, cela crée en fait deux barres de défilement
rbansal
2

J'ai l'habitude d'avoir ce problème, mais le moyen le plus simple de le résoudre est le suivant (cela fonctionne pour moi):

sur le type de fichier CSS:

body{overflow-y:scroll;}

aussi simple que ça! :)

Melvin Guerrero
la source
2

Les solutions publiées en utilisant calc (100vw - 100%) sont sur la bonne voie, mais il y a un problème avec ceci: vous aurez toujours une marge à gauche de la taille de la barre de défilement, même si vous redimensionnez la fenêtre pour que le le contenu remplit la fenêtre entière.

Si vous essayez de contourner cela avec une requête multimédia, vous aurez un moment de claquement gênant car la marge ne diminuera pas progressivement lorsque vous redimensionnerez la fenêtre.

Voici une solution qui contourne cela et AFAIK n'a aucun inconvénient:

Au lieu d'utiliser margin: auto pour centrer votre contenu, utilisez ceci:

body {
margin-left: calc(50vw - 500px);
}

Remplacez 500px par la moitié de la largeur maximale de votre contenu (dans cet exemple, la largeur maximale du contenu est de 1000px). Le contenu restera désormais centré et la marge diminuera progressivement jusqu'à ce que le contenu remplisse la fenêtre.

Afin d'empêcher la marge de devenir négative lorsque la fenêtre est plus petite que la largeur maximale, ajoutez simplement une requête multimédia comme ceci:

@media screen and (max-width:1000px) {
    body {
        margin-left: 0;
    }
}

Et voilà!

Jonathan SI
la source
2

Si la largeur du tableau ne change pas, vous pouvez définir la largeur de l'élément (tel que tbody) qui contient la barre de défilement> 100% (permettant un espace supplémentaire pour la barre de défilement) et définir overflow-y sur "overlay" (donc que la barre de défilement reste fixe et ne déplace pas le tableau vers la gauche lorsqu'il apparaît). Définissez également une hauteur fixe pour l'élément avec la barre de défilement, afin que la barre de défilement apparaisse une fois la hauteur dépassée. Ainsi:

tbody {
  height: 100px;
  overflow-y: overlay;
  width: 105%
}

Remarque: vous devrez ajuster manuellement la largeur% car le% d'espace occupé par la barre de défilement sera relatif à la largeur de votre table (c'est-à-dire: plus petite largeur de table, plus de% requis pour s'adapter à la barre de défilement, car sa taille en pixels est constante )

Un exemple de table dynamique:

function addRow(tableID)
{
    var table = document.getElementById(tableID);
    var rowCount = table.rows.length;
    var row = table.insertRow(rowCount);
    var colCount = table.rows[0].cells.length;
  
    for(var i=0; i<colCount; i++)
    {
        var newRow = row.insertCell(i);

        newRow.innerHTML = table.rows[0].cells[i].innerHTML;
        newRow.childNodes[0].value = "";
    }
}
 
function deleteRow(row)
{
    var table = document.getElementById("data");
    var rowCount = table.rows.length;
    var rowIndex = row.parentNode.parentNode.rowIndex;

    document.getElementById("data").deleteRow(rowIndex);
}
.scroll-table {
  border-collapse: collapse;
}

.scroll-table tbody {
  display:block;
  overflow-y:overlay;
  height:60px;
  width: 105%
}

.scroll-table tbody td {
  color: #333;
  padding: 10px;
  text-shadow: 1px 1px 1px #fff;
}

.scroll-table thead tr {
  display:block;
}

.scroll-table td {
    border-top: thin solid; 
    border-bottom: thin solid;
}

.scroll-table td:first-child {
    border-left: thin solid;
}

.scroll-table td:last-child {
    border-right: thin solid;
}

.scroll-table tr:first-child {
    display: none;
}

.delete_button {
    background-color: red;
    color: white;
}

.container {
  display: inline-block;
}

body {
  text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
  <link rel="stylesheet" href="test_table.css">
</head>

<body>
<h1>Dynamic Table</h1>
<div class="container">

  <table id="data" class="scroll-table">
    <tbody>
      <tr>
        <td><input type="text" /></td>
        <td><input type="text" /></td>
        <td><input type="button" class="delete_button" value="X" onclick="deleteRow(this)"></td>
      </tr>
    </tbody>
  </table>

  <input type="button" value="Add" onclick="addRow('data')" />

</div>

<script src="test_table.js"></script>
</body>
</html>

Robert James Mieta
la source
1

Il suffit de régler la largeur de votre élément de conteneur comme ceci fera l'affaire

width: 100vw;

Cela fera que cet élément ignorera la barre de défilement et cela fonctionnera avec la couleur d'arrière-plan ou les images.

Barsonax
la source
-3

J'ai utilisé du jquery pour résoudre ce problème

$('html').css({
    'overflow-y': 'hidden'
});

$(document).ready(function(){
  $(window).load(function() {
    $('html').css({
      'overflow-y': ''
    });
  });
});
Will McMillian
la source
3
Vous recevez probablement une mauvaise réception de votre réponse, car cette solution nécessite un framework JavaScript complet. "jQuery toutes les choses!"
Paul Lammertsma
3
ouais, jQuery est définitivement la voie à suivre - doxdesk.com/img/updates/20091116-so-large.gif
anonyme
-4
@media screen and (min-width: 1024px){
    body {
    min-height: 700px
    }
}
Vicky
la source
Bienvenue dans Stack Overflow! Bien que cet extrait de code puisse résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question pour les lecteurs à l'avenir, et ces personnes pourraient ne pas connaître les raisons de votre suggestion de code. Essayez également de ne pas surcharger votre code avec des commentaires explicatifs, cela réduit la lisibilité du code et des explications!
Andrew Myers
-5

Contrairement à la réponse acceptée qui suggère une barre de défilement permanente sur la fenêtre du navigateur même si le contenu ne déborde pas de l'écran , je préférerais utiliser:

html{
  height:101%;
}

En effet, l'apparence de la barre de défilement a plus de sens si le contenu déborde réellement .

Cela a plus de sens que cela .

Nikunj Madhogaria
la source
1
Au moins la dernière phrase est erronée dans votre réponse. Cela a un sens similaire avec une page vide excédentaire imprimée par l'imprimante.
vp_arth