Wie kann verhindert werden, dass die Bildlaufleiste die Webseite neu positioniert?

218

Ich habe eine Website mit zentriertem DIV. Einige Seiten müssen gescrollt werden, andere nicht. Wenn ich von einem Typ zu einem anderen wechsle, verschiebt das Erscheinungsbild einer Bildlaufleiste die Seite einige Pixel zur Seite. Gibt es eine Möglichkeit, dies zu vermeiden, ohne die Bildlaufleisten auf jeder Seite explizit anzuzeigen?

Dmitri Nesteruk
quelle
6
Warum erwähnt niemand overflow-y: overlayin diesem Thread?
Milkersarac
3
Laut den Mozilla-Dokumenten overflow-y: overlaywird abgeschrieben: developer.mozilla.org/en-US/docs/Web/CSS/overflow
drojf

Antworten:

266

overflow-y: scroll ist korrekt, aber Sie sollten es mit dem HTML-Tag verwenden, nicht mit body, sonst erhalten Sie in IE 7 eine doppelte Bildlaufleiste.
Das richtige CSS wäre also:

html {
  overflow-y: scroll;
}
Ruben
quelle
1
IE 10+ hat eine schwebende Bildlaufleiste, daher sollten Sie diese für diese Browser deaktivieren
Ruben
1
Dies kann Probleme wie doppelte Bildlaufleisten verursachen, wenn es in Kombination mit Fancybox oder Twitter Bootstrap Modal verwendet wird
Ruben
Zusätzliche Informationen: Twitter Bootstrap fügt jetzt .modal-open zu Ihrem Körper hinzu, wenn ein Modal geöffnet ist
Ruben
55
Erwähnenswert ist, dass hier permanent eine vertikale Bildlaufleiste angezeigt wird. Kann nicht immer akzeptabel sein.
Rustyx
Ich bekomme eine doppelte Bildlaufleiste in Chromium und Firefox. Ich benutze Flex-Box; Vielleicht verursacht das das ...
Garrett
72

Wickeln Sie den Inhalt Ihres scrollbaren Elements in ein div und wenden Sie es an 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>

Der Trick besteht darin, dass 100vw100% des Ansichtsfensters einschließlich der Bildlaufleiste dargestellt werden. Wenn Sie subtrahieren 100%, was der verfügbare Platz ohne die Bildlaufleiste ist, erhalten Sie die Breite der Bildlaufleiste oder 0wenn sie nicht vorhanden ist. Wenn Sie links einen Abstand dieser Breite erstellen, wird eine zweite Bildlaufleiste simuliert, die den zentrierten Inhalt wieder nach rechts verschiebt.

Bitte beachten Sie, dass dies nur funktioniert, wenn das scrollbare Element die gesamte Breite der Seite verwendet. Dies sollte jedoch die meiste Zeit kein Problem sein, da es nur wenige andere Fälle gibt, in denen Sie scrollbaren Inhalt zentriert haben.

Rapti
quelle
1
Wäre besser über eine Klasse als über einen Inline-Stil anzuwenden und funktioniert nur in diesen Browsern , aber dies ist eine clevere Technik - ich hatte das nicht erkannt 100vwund 100%verschiedene Dinge gemessen, also habe ich etwas Nützliches daraus gelernt!
Nick F
21
Dies ist absolut genial und die beste Antwort, wenn man bedenkt, dass die Browserunterstützung für calc sehr gut ist.
Michael
1
Sie können dasselbe tun, außer dass Sie, anstatt links einen Rand hinzuzufügen, rechts einen negativen Rand hinzufügen (siehe stackoverflow.com/a/39289453/6015444 ).
Touniouk
2
Diese Lösung verursacht ähnliche Probleme mit der Hintergrundfarbe wie die Antwort "width: calc (100vw - 34px);" aber auf der linken Seite.
Maciej Lew
1
Ich würde empfehlen, diesem Stil einige Medienabfragen hinzuzufügen @media screen and (min-width: 800px) {...} . In Fällen, in denen der Inhalt der Seitenbreite entspricht. Zum Beispiel wird es bei kleinen Auflösungen unnötige Lücken geben, die den Inhalt nach rechts verschieben
MarkosyanArtur
44

Ich denke nicht. Aber Styling bodymit overflow: scrollsollte reichen. Das scheinen Sie aber zu wissen.

Michael Krelin - Hacker
quelle
3
Hört sich gut an ... zwingen Sie die Seite, immer die Bildlaufleiste anzuzeigen, ob sie benötigt wird oder nicht, ... dann gibt es keine visuelle Änderung zwischen den Seitentypen.
Eidylon
1
Ja, aber IIRC, dies zeigt beide Bildlaufleisten. Ich brauche die horizontale nicht wirklich.
Dmitri Nesteruk
Das ist richtig. Aber ich kann nicht viel tun, um Ihnen zu helfen :( Eigentlich betrachte ich nur den ersten Satz meiner Antwort als die wirkliche Antwort, die sich mit der Frage befasst.
Michael Krelin - Hacker
49
overflow-y: scroll:)
Svish
2
Das Folgende ist die bessere Antwort
Sami
36

Wenn der Bildlauf immer angezeigt wird, ist dies möglicherweise nicht gut für das Layout.

Versuchen Sie, die Körperbreite mit css3 zu begrenzen

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

vwist die Breite des Ansichtsfensters (siehe diesen Link für eine Erklärung).
calcBerechnen in CSS3
34pxsteht für doppelte Breite der Bildlaufleiste (siehe dies für feste oder dies zu berechnen, wenn Sie festen Größen nicht vertrauen)

Moesio
quelle
4
Alles ist sinnlos, bis jemand braucht.
Moesio
3
Dies ist visuell viel weniger aufdringlich als nur das Erzwingen von Bildlaufleisten, wie in der akzeptierten Antwort beschrieben.
Silas Hansen
4
Dies hat bisher am besten für meine Bedürfnisse funktioniert. Ich habe auch hinzugefügt, padding-left: 34px;um meine Seite gleichmäßig zu zentrieren.
Pat Migliaccio
3
Dies sollte die akzeptierte Antwort sein, im Gegensatz zu der derzeit akzeptierten, die tatsächlich die Frage beantwortet!
Coz
2
Dies wird Probleme verursachen, wenn Sie Navbar / Header mit einer anderen Farbe als Körperhintergrund oder unterer Rand usw. haben
Zia Ul Rehman Mughal
28
html {
  overflow-x: hidden;
  margin-right: calc(-1 * (100vw - 100%));
}

Beispiel . Klicken Sie auf die Schaltfläche "Mindesthöhe ändern".

Mit können calc(100vw - 100%)wir die Breite der Bildlaufleiste berechnen (und wenn sie nicht angezeigt wird, ist sie 0). Idee: Mit negativem Rand rechts können wir die Breite <html>auf diese Breite erhöhen . Sie sehen eine horizontale Bildlaufleiste - diese sollte mit ausgeblendet werden overflow-x: hidden.

Pongo
quelle
Ich musste den Körper in ein Div stecken und den Rand auf das Div anwenden, damit es funktioniert (ähnlich wie bei Rapti ). Aber das sieht so viel ordentlicher aus.
Touniouk
1
Dies funktioniert hervorragend und scheint in Chrome oder Firefox nicht zu unerwünschten horizontalen Bildlaufleisten zu führen. Warum nicht einfach verwenden calc(100% - 100vw)anstatt zu multiplizieren -1?
SystemParadox
13

Ich weiß nicht, ob dies ein alter Beitrag ist, aber ich hatte das gleiche Problem und wenn Sie nur vertikal scrollen möchten, sollten Sie es versuchen overflow-y:scroll


quelle
13

Wenn Sie die Größe ändern oder nach dem Laden einiger Daten die Bildlaufleiste hinzufügen, können Sie Folgendes versuchen, eine Klasse erstellen und diese Klasse anwenden.

.auto-scroll {
   overflow-y: overlay;
   overflow-x: overlay;
}
Kunalkamble
quelle
3

Ich habe das Problem auf einer meiner Websites gelöst, indem ich die Breite des Körpers in Javascript explizit durch die Größe des Ansichtsfensters abzüglich der Breite der Bildlaufleiste festgelegt habe. Ich verwende eine hier dokumentierte jQuery-basierte Funktion , um die Breite der Bildlaufleiste zu bestimmen.

<body id="bodyid>

var bodyid = document.getElementById('bodyid');
bodyid.style.width = window.innerWidth - scrollbarWidth() + "px";
Frank L.
quelle
10
Ich kann nicht einmal erklären, warum dies so eine schlechte Praxis ist.
Mythosofechelon
20
@ BenHooper: Ich würde gerne wissen, warum dies eine schlechte Praxis ist.
Saad
1
Was passiert, wenn Sie die Fenstergröße ändern?
Braden Steffaniak
3

Erweitern Sie die Antwort damit:

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

Ein Kommentator schlug vor, auch die linke Polsterung hinzuzufügen, um die Zentrierung beizubehalten:

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

Aber dann sehen die Dinge nicht richtig aus, wenn Ihr Inhalt breiter als das Ansichtsfenster ist. Um dies zu beheben, können Sie Medienabfragen wie folgt verwenden:

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

Wobei 1058px = Inhaltsbreite + 17 * 2

Auf diese Weise kann eine horizontale Bildlaufleiste den x-Überlauf verarbeiten und den zentrierten Inhalt zentriert halten, wenn das Ansichtsfenster breit genug ist, um Ihren Inhalt mit fester Breite aufzunehmen

Greg St.Onge
quelle
3

Ausgehend von Raptis Antwort sollte dies genauso gut funktionieren, aber es fügt mehr Rand auf der rechten Seite des hinzu bodyund verbirgt ihn mit negativem htmlRand, anstatt zusätzliche Auffüllungen hinzuzufügen, die möglicherweise das Layout der Seite beeinflussen könnten. Auf diese Weise wird (in den meisten Fällen) nichts auf der eigentlichen Seite geändert, und der Code ist weiterhin funktionsfähig.

html {
    margin-right: calc(100% - 100vw);
}
body {
    margin-right: calc(100vw - 100%);
}
Grant Gryczan
quelle
Ich habe festgestellt, dass dies bei Chrome einen horizontalen Bildlauf auf Seiten mit einer vertikalen Bildlaufleiste auf meiner Bootstrap-Site hinzufügt.
Ingwer Eichhörnchen
Haben Sie versucht zu untersuchen, warum? Überprüfen Sie den Elementinspektor und prüfen Sie, ob Bootstrap Ränder, Bildlaufleisten oder ähnliches aufweist.
Grant Gryczan
1
Es hatte wahrscheinlich etwas mit den 15-Pixel-Rändern zu tun, die Bootstrap für alles bereitstellt. Bei der Überprüfung der Seite fällt der Containerrand unter die Bildlaufleiste. Ich habe mich beworben overflow-x: hiddenund das hat es behoben.
Ingwer Eichhörnchen
3

Die Lösung von @ kashesandr hat bei mir funktioniert, aber um die horizontale Bildlaufleiste auszublenden, habe ich einen weiteren Stil für den Körper hinzugefügt. Hier ist die Komplettlösung:

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');
      }
    });
});

JS Only Solution (wenn das 2. Modal vom 1. Modal geöffnet wurde):

/**
 * 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
quelle
2

Ich habe versucht, wahrscheinlich das gleiche Problem zu beheben, das durch die .modal-openangewendete Twitter-Bootstrap- Klasse verursacht wurde body. Die Lösung html {overflow-y: scroll}hilft nicht. Eine mögliche Lösung, die ich gefunden habe, ist das Hinzufügen {width: 100%; width: 100vw}zum htmlElement.

kashesandr
quelle
1
oder ändern Sie es in body {overflow-y: scroll}
Ruben
1
Aber das würde immer eine Bildlaufleiste anzeigen, auch wenn es nicht erforderlich ist.
Rapti
Sie sollten erklären, warum Sie die Breite zweimal einstellen. html { width: 100vw; }arbeitete für mich
Hassan Tareq
Für mich erstellt es tatsächlich zwei Bildlaufleisten
Rbansal
2

Früher hatte ich dieses Problem, aber der einfachste Weg, es zu beheben, ist folgender (das funktioniert bei mir):

zum CSS-Dateityp:

body{overflow-y:scroll;}

so einfach! :) :)

Melvin Guerrero
quelle
2

Die mit calc (100vw - 100%) veröffentlichten Lösungen befinden sich auf dem richtigen Weg, aber es gibt ein Problem: Sie haben für immer einen Rand links von der Größe der Bildlaufleiste, selbst wenn Sie die Größe des Fensters so ändern, dass die Inhalt füllt das gesamte Ansichtsfenster aus.

Wenn Sie versuchen, dies mit einer Medienabfrage zu umgehen, haben Sie einen unangenehmen Moment, da der Rand beim Ändern der Fenstergröße nicht immer kleiner wird.

Hier ist eine Lösung, die das umgeht und AFAIK hat keine Nachteile:

Verwenden Sie Folgendes, anstatt margin: auto zum Zentrieren Ihrer Inhalte zu verwenden:

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

Ersetzen Sie 500px durch die Hälfte der maximalen Breite Ihres Inhalts (in diesem Beispiel beträgt die maximale Breite des Inhalts 1000px). Der Inhalt bleibt nun zentriert und der Rand wird schrittweise verringert, bis der Inhalt das Ansichtsfenster ausfüllt.

Um zu verhindern, dass der Rand negativ wird, wenn das Ansichtsfenster kleiner als die maximale Breite ist, fügen Sie einfach eine Medienabfrage wie folgt hinzu:

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

Et voilà!

Jonathan SI
quelle
2

Wenn sich die Breite der Tabelle nicht ändert, können Sie die Breite des Elements (z. B. tbody), das die Bildlaufleiste enthält, auf> 100% einstellen (wobei zusätzlicher Platz für die Bildlaufleiste vorhanden ist) und overflow-y auf "overlay" setzen (so) dass die Bildlaufleiste fest bleibt und die Tabelle nicht nach links verschiebt, wenn sie angezeigt wird). Stellen Sie außerdem mit der Bildlaufleiste eine feste Höhe für das Element ein, damit die Bildlaufleiste angezeigt wird, sobald die Höhe überschritten wird. Wie so:

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

Hinweis: Sie müssen die Breite% manuell anpassen, da der prozentuale Platzbedarf der Bildlaufleiste relativ zu Ihrer Tabellenbreite ist (dh: kleinere Tabellenbreite, mehr% erforderlich, um die Bildlaufleiste anzupassen, da die Größe in Pixel konstant ist )

Ein dynamisches Tabellenbeispiel:

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
quelle
1

Wenn Sie einfach die Breite Ihres Containerelements so einstellen, reicht dies aus

width: 100vw;

Dadurch ignoriert dieses Element die Bildlaufleiste und arbeitet mit Hintergrundfarben oder Bildern.

Barsonax
quelle
-3

Ich habe eine Frage gestellt, um das zu lösen

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

$(document).ready(function(){
  $(window).load(function() {
    $('html').css({
      'overflow-y': ''
    });
  });
});
Will McMillian
quelle
3
Ihre Antwort wird wahrscheinlich schlecht aufgenommen, da für diese Lösung ein vollständiges JavaScript-Framework erforderlich ist. "jQuery all die Dinge!"
Paul Lammertsma
3
Ja, jQuery ist definitiv der richtige
Annonymous
-4
@media screen and (min-width: 1024px){
    body {
    min-height: 700px
    }
}
Vicky
quelle
Willkommen bei Stack Overflow! Während dieses Code-Snippet die Frage lösen kann, hilft das Hinzufügen einer Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen. Bitte versuchen Sie auch, Ihren Code nicht mit erklärenden Kommentaren zu überfüllen. Dies verringert die Lesbarkeit sowohl des Codes als auch der Erklärungen!
Andrew Myers
-5

Im Gegensatz zu der akzeptierten Antwort, die eine permanente Bildlaufleiste im Browserfenster vorschlägt, selbst wenn der Inhalt nicht über den Bildschirm läuft , würde ich lieber Folgendes verwenden:

html{
  height:101%;
}

Dies liegt daran, dass das Erscheinungsbild der Bildlaufleiste sinnvoller ist, wenn der Inhalt tatsächlich überläuft .

Das macht mehr Sinn als das .

Nikunj Madhogaria
quelle
1
Zumindest der letzte Satz ist in Ihrer Antwort falsch. Ähnlich ist es, wenn überschüssige leere Seiten vom Drucker gedruckt werden.
vp_arth