web-dev-qa-db-fra.com

La barre de défilement verticale mène à la barre de défilement horizontale

Mon CSS ressemble à ceci:

div.SOMECLASS {
  position: absolute;
  max-height: 300px
  height: auto;
  width: auto;
  overflow: auto;
  ...
}

L'échelle de hauteur et de largeur div automatiquement. La hauteur a cependant fixé un maximum: dès que cette valeur est atteinte, des barres de défilement verticales apparaissent. Cela fonctionne très bien houle.

Maintenant, le problème:
Si les barres de défilement verticales apparaissent, elles utilisent environ 10 pixels d'espace horizontal , car les barres de défilement seront placées à l'intérieur du div.
Cependant, la largeur n'est pas pas mise à l'échelle automatique pour tenir compte de ces 10 pixels supplémentaires utilisés par les barres de défilement verticales. Comme la largeur horizontale avant l'ajout des barres de défilement verticales était exactement la bonne pour le contenu (comme prévu par le width:auto), le div maintenant aussi affiche les barres de défilement horizontales - pour tenir compte des 10 pixels manquants. C'est idiot.

  • Comment puis-je éviter d'avoir ces barres de défilement horizontales et simplement mettre à l'échelle automatiquement la largeur du div pour adapter les barres de défilement verticales?

Si possible, je recherche une solution qui ne repose pas uniquement sur la désactivation complète du défilement horizontal, car cela sera probablement nécessaire à un moment donné (c'est-à-dire pour certaines entrées).

29

J'ai trouvé une solution qui fonctionne mais loin d'être parfaite:

J'ai ajouté un padding-right : 15px à mon div, pour agrandir automatiquement le div entier. Maintenant, si les barres de défilement verticales apparaissent, elles tiennent dans le rembourrage de sorte que la largeur horizontale est toujours correcte.

Malheureusement, le rembourrage apparaît également quand aucun défilement vertical n'est nécessaire, ce qui rend ma div un peu plus large qu'elle ne devrait l'être ...:/Eh bien, à mes yeux, cela est toujours préférable aux barres de défilement horizontales inutiles.

14
fgysin

Je viens de découvrir une solution passable (au moins pour ma version de ce problème).

J'assume le problème avec width: auto est qu'il se comporte de la même manière que width: 100vw; le problème est que lorsque la barre de défilement verticale apparaît, la largeur de la fenêtre d'affichage reste la même (malgré la barre de défilement ~ 10px), mais la la zone visible (comme je l'appelle) est réduite de 10 pixels.

Apparemment, définir la largeur par pourcentage la définit en fonction de cette "zone visible", donc changez votre code en:

div.SOMECLASS {
  position: absolute;
  max-height: 300px
  height: auto;
  width: 100%;
  overflow: auto;
  ...
}

devrait permettre au contenu de se redimensionner correctement!

p.s. Vous pouvez également ajouter à la place overflow-x: hidden, ce qui empêchera la barre de défilement horizontale d'apparaître, au lieu de simplement couper ~ 10 px du côté droit de votre div lorsque la barre de défilement verticale apparaît.

11
Spencer

Réglage souvent 100vw c'est le problème. Il suffit de le retirer et votre largeur sera de 100%, ce qui sera de toute façon ce que vous voulez.

0
bersling

Résultat de recherche numéro 1 sur Google pour mon problème (similaire à OP, mais pas le même).

Voici un scénario courant pour une barre de défilement horizontale apparemment inutile:

Vous avez un élément, par exemple, un tableau, qui utilise le dimensionnement automatique. Si le dimensionnement automatique est effectué avant toutes les lignes sont ajoutées, alors il ne calculera pas assez de place pour une barre de défilement verticale. Faire le redimensionnement après l'ajout de lignes a résolu mon problème - même alors, j'avais besoin d'un délai d'attente

this.http.get('someEndPoint').subscribe(rows => {
  this.rowData = rows;
  setTimeout(()=>{sizeColumnsToFit()}, 50);
});
0
solbs

Ce bogue (spécifique à Firefox) se produit même lorsque vous ne définissez pas de largeur fixe.

Par exemple, si vous avez une div de conteneur à défilement vertical (overflow: auto;) à l'intérieur d'une div enveloppe souple (display: inline-block;), puis lorsque vous redimensionnez la fenêtre pour être plus petite que le contenu peut envelopper, d'abord, une barre de défilement horizontale apparaîtra dans votre div de conteneur, et seulement après cela, la div de wrapper flexible s'agrandira ou, éventuellement, une barre de défilement horizontale secondaire apparaîtra dans votre fenêtre.

Le résultat est une barre de défilement horizontale inutile, qui ne peut faire défiler que la largeur de la barre de défilement verticale:

Screenshot of the example code showing the problem and a solution

Afin de vous débarrasser de ce problème, vous pouvez utiliser le code javascript de cet exemple (testé dans Firefox et Chromium):

<!DOCTYPE html>
<html>
<body>
    <style type="text/css">
    .page {height: 200px;width: 400px;overflow: auto;background-color: #ccc;border: 5px solid #000;margin: 5px;}
    .wrapper {display: inline-block;min-width: 100%;margin: 20px;}
    .scroller {overflow: auto;max-height: 100px;background-color: #f00;}
    .content {min-height: 500px;min-width: 400px;background-color: #cfc;}
    </style>
    <div class="page">
        <div class="wrapper">
            <div class="scroller">
                <div class="content">
                    The wrapper-div should expand to fit the scroller content.
                    Reduce the browser window width, and a useless horizontal scrollbar appears.
                </div>
            </div>
        </div>
    </div>
    <div class="page">
        <div class="wrapper">
            <div class="scroller ensure-scrollbar-width-padding">
                <div class="content">
                    But with the javascript-function, this is now fixed.
                    There is no horizontal scrollbar in the wrapper-div.
                </div>
            </div>
        </div>
    </div>
    <script>
    var ensureScrollbarWidthPadding = function(elem)
    {
        if(!parseInt(elem.scrollWidth) || !parseInt(elem.clientWidth) || !parseInt(elem.offsetWidth))
        {
            return; // no browser-support for this trick
        }

        var update = function()
        {
            // reset to as if not having any right-padding
            elem.style.paddingRight = '0px';

            // check if horizontal scrollbar appeared only because of the vertical scrollbar
            if(elem.scrollWidth !== elem.clientWidth)
            {
                elem.style.paddingRight = (elem.offsetWidth - elem.clientWidth) + 'px';
            }
            else
            {
                elem.style.paddingRight = '0px';
            }
        };

        window.addEventListener('resize', update, false);
        window.addEventListener('load', update, false);

        update();

        return update;
    };

    (function()
    {
        var elems = document.getElementsByClassName('ensure-scrollbar-width-padding');
        for(var i=0;i<elems.length;++i)
        {
            ensureScrollbarWidthPadding(elems[i]);
        }
    })();
    </script>
</body>
</html>

La fonction javascript assure que ScrollbarWidthPadding ajoute dynamiquement un padding-right au conteneur à défilement vertical, pour garantir que la barre de défilement horizontale n'apparaîtra jamais.

0
Yeti