Come impedire il riposizionamento della pagina Web nella barra di scorrimento?


218

Ho un sito Web con DIV allineato al centro. Ora, alcune pagine hanno bisogno di scorrere, altre no. Quando passo da un tipo a un altro, l'aspetto di una barra di scorrimento sposta la pagina di alcuni pixel lateralmente. C'è un modo per evitarlo senza mostrare esplicitamente le barre di scorrimento su ogni pagina?


6
Perché nessuno menziona overflow-y: overlayin questo thread?
milkersarac,

3
Secondo i documenti di mozilla, overflow-y: overlayè ammortizzato: developer.mozilla.org/en-US/docs/Web/CSS/overflow
drojf

Risposte:


266

overflow-y: scroll è corretto, ma dovresti usarlo con il tag html, non body o altrimenti otterrai una doppia barra di scorrimento in IE 7
Quindi il CSS corretto sarebbe:

html {
  overflow-y: scroll;
}

1
IE 10+ ha una barra di scorrimento mobile, quindi è necessario disabilitarlo per questi browser
Ruben

1
questo può causare problemi come doppie barre di scorrimento quando si utilizza in combinazione con fancybox o twitter bootstrap modale
Ruben

informazioni extra: twitter bootstrap ora aggiunge .modal-open al tuo corpo quando un modal è aperto
Ruben

55
Vale la pena ricordare che questo mostra in modo permanente una barra di scorrimento verticale. Potrebbe non essere sempre accettabile.
Rustyx,

Ottengo una doppia barra di scorrimento sia in Chromium che in Firefox. Sto usando la scatola flessibile; forse questo sta causando questo ...
Garrett

72

Avvolgi il contenuto del tuo elemento scorrevole in un div e applicalo 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>

Il trucco è che 100vwrappresenta il 100% del viewport inclusa la barra di scorrimento. Se si sottrae 100%, che è lo spazio disponibile senza la barra di scorrimento, si finisce con la larghezza della barra di scorrimento o 0se non è presente. La creazione di un'imbottitura di quella larghezza a sinistra simulerà una seconda barra di scorrimento, spostando il contenuto centrato di nuovo a destra.

Nota che questo funzionerà solo se l'elemento scorrevole utilizza l'intera larghezza della pagina, ma questo non dovrebbe essere un problema la maggior parte delle volte perché ci sono solo pochi altri casi in cui hai centrato il contenuto scorrevole.


1
Sarebbe meglio applicato tramite una classe rispetto a uno stile in linea e funzionerebbe solo con questi browser , ma questa è una tecnica intelligente - non me ne ero reso conto 100vwe 100%misurato cose diverse, quindi ho imparato qualcosa di utile da questo!
Nick F,

21
Questo è assolutamente geniale ed è davvero la risposta migliore considerando che il supporto del browser per Calc è molto buono.
michael,

1
Puoi fare lo stesso tranne che invece di aggiungere un margine a sinistra, aggiungi un margine negativo a destra (vedi stackoverflow.com/a/39289453/6015444 ).
Touniouk,

2
Questa soluzione causerà problemi simili con il colore di sfondo come la risposta "larghezza: calc (100vw - 34px);" ma sul lato sinistro.
Maciej Lew,

1
Consiglierei di aggiungere alcune query multimediali a questo stile- @media screen and (min-width: 800px) {...} . Nei casi in cui il contenuto si adatta alla larghezza della pagina. Ad esempio su piccole risoluzioni ci sarà un gap non necessario, spostando il contenuto a destra
MarkosyanArtur

44

Penso di no. Ma lo stile bodycon overflow: scrolldovrebbe fare. Sembra che tu lo sappia, comunque.


3
Suona bene ... forza la pagina a mostrare sempre la barra di scorrimento se ne ha bisogno o no, ... quindi non c'è alcun cambiamento visivo tra i tipi di pagina.
eidylon,

1
Sì, ma IIRC, mostra entrambe le barre di scorrimento. Non ho davvero bisogno di quello orizzontale.
Dmitri Nesteruk,

È vero. Ma non c'è molto che posso fare per aiutarti :( In realtà, considero solo la prima frase della mia risposta come la vera risposta che si occupa della domanda.
Michael Krelin - hacker

49
overflow-y: scroll:)
Svish,

2
Di seguito è la risposta migliore
Sami,

36

Con lo scorrimento sempre mostrato, forse non va bene per il layout.

Prova a limitare la larghezza del corpo con css3

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

vwè la larghezza della finestra (vedi questo link per qualche spiegazione)
calccalcola in css3
34pxsta per doppia larghezza della barra di scorrimento (vedi questo per fisso o questo per calcolare se non ti fidi di dimensioni fisse)


4
Tutto è inutilità finché qualcuno non ne ha bisogno.
Moesio,

3
Questo è visivamente molto meno invadente del solo forzare gli scollbar come descrive la risposta accettata.
Silas Hansen,

4
Questo ha funzionato al meglio per le mie esigenze finora, ho anche aggiunto padding-left: 34px;per centrare uniformemente la mia pagina.
Pat Migliaccio,

3
Questa dovrebbe essere la risposta accettata, a differenza di quella attualmente accettata sta effettivamente rispondendo alla domanda!
Coz,

2
Ciò causerà problemi se si dispone di una barra di navigazione / intestazione con colore diverso dallo sfondo del corpo o dal bordo inferiore ecc.
Zia Ul Rehman Mughal,

28
html {
  overflow-x: hidden;
  margin-right: calc(-1 * (100vw - 100%));
}

Esempio . Fai clic sul pulsante "modifica altezza minima".

Con calc(100vw - 100%)possiamo calcolare la larghezza della barra di scorrimento (e se non viene visualizzata, sarà 0). Idea: usando il margine negativo a destra, possiamo aumentare la larghezza di <html>questa larghezza. Vedrai una barra di scorrimento orizzontale, che dovrebbe essere nascosta usando overflow-x: hidden.


Ho dovuto mettere il corpo in un div e applicare il margine al div per farlo funzionare (in modo simile alla risposta di Rapti ). Ma sembra molto più ordinato.
Touniouk,

1
Funziona alla grande e non sembra provocare barre di scorrimento orizzontali indesiderate in Chrome o Firefox. Perché non usare semplicemente calc(100% - 100vw)anziché moltiplicare per -1?
SystemParadox,

13

Non so se questo è un vecchio post, ma ho avuto lo stesso problema e se vuoi scorrere verticalmente, dovresti provare overflow-y:scroll


13

Se si modifica la dimensione o dopo aver caricato alcuni dati si sta aggiungendo la barra di scorrimento, è possibile provare a seguire, creare classe e applicare questa classe.

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

3

Ho risolto il problema su uno dei miei siti Web impostando esplicitamente la larghezza del corpo in javascript in base alla dimensione del riquadro di visualizzazione meno la larghezza della barra di scorrimento. Uso una funzione basata su jQuery documentata qui per determinare la larghezza della barra di scorrimento.

<body id="bodyid>

var bodyid = document.getElementById('bodyid');
bodyid.style.width = window.innerWidth - scrollbarWidth() + "px";

10
Non riesco nemmeno a spiegare perché questa è una cattiva pratica.
mythofechelon,

20
@BenHooper: vorrei sapere perché questa è una cattiva pratica.
Saad,

1
Cosa succede se si ridimensiona la finestra?
Braden Steffaniak, il

3

Espandendo la risposta usando questo:

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

Un commentatore ha suggerito di aggiungere anche il padding sinistro per mantenere il centraggio:

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

Ma le cose non sembrano corrette se il contenuto è più ampio del viewport. Per risolvere questo problema, puoi utilizzare le query multimediali, in questo modo:

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

Dove 1058px = larghezza del contenuto + 17 * 2

Ciò consente a una barra di scorrimento orizzontale di gestire l'overflow x e mantiene centrato il contenuto centrato quando la finestra è abbastanza ampia da contenere il contenuto a larghezza fissa


3

Estendendo la risposta di Rapti , questo dovrebbe funzionare altrettanto bene, ma aggiunge più margine al lato destro bodye lo nasconde con htmlmargine negativo , invece di aggiungere ulteriore riempimento che potrebbe influenzare potenzialmente il layout della pagina. In questo modo, nulla viene modificato nella pagina effettiva (nella maggior parte dei casi) e il codice è ancora funzionante.

html {
    margin-right: calc(100% - 100vw);
}
body {
    margin-right: calc(100vw - 100%);
}

Ho scoperto che su Chrome questo aggiunge uno scorrimento orizzontale sulle pagine che hanno una barra di scorrimento verticale sul mio sito bootstrap.
Ginger Squirrel,

Hai provato a capire perché? Controlla la finestra di ispezione degli elementi e verifica se Bootstrap si rovina con margini, barre di scorrimento o simili.
Grant Gryczan,

1
Probabilmente era qualcosa a che fare con i margini di 15px che bootstrap mette su tutto, quando si ispeziona la pagina il margine del contenitore cade sotto la barra di scorrimento. Ho applicato overflow-x: hiddene risolto il problema.
Ginger Squirrel,

3

La soluzione di @ kashesandr ha funzionato per me, ma per nascondere la barra di scorrimento orizzontale ho aggiunto un altro stile per il corpo. ecco la soluzione completa:

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 (quando 2 ° modale aperto dal 1 ° modale):

/**
 * 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);
  }
});

2

Ho provato a risolvere probabilmente lo stesso problema a cui si .modal-openapplicava la classe bootstrap di Twitter body. La soluzione html {overflow-y: scroll}non aiuta. Una possibile soluzione che ho trovato è quello di aggiungere {width: 100%; width: 100vw}al htmlelemento.


1
o cambiarlo in body {overflow-y: scroll}
Ruben,

1
Ma ciò mostrerebbe sempre una barra di scorrimento anche se non è richiesta.
Rapti,

Dovresti spiegare perché stai impostando la larghezza due volte? html { width: 100vw; }ha funzionato per me
Hassan Tareq,

Per me, in realtà crea due barre di scorrimento
rbansal

2

Io ho questo problema, ma il modo più semplice per risolverlo è questo (questo funziona per me):

sul tipo di file CSS:

body{overflow-y:scroll;}

così semplice! :)


2

Le soluzioni pubblicate usando calc (100vw - 100%) sono sulla buona strada, ma c'è un problema con questo: avrai sempre un margine a sinistra della dimensione della barra di scorrimento, anche se ridimensioni la finestra in modo che il il contenuto riempie l'intera finestra.

Se si tenta di aggirare questo problema con una query multimediale, si verificherà un momento imbarazzante poiché il margine non si ridurrà progressivamente man mano che si ridimensiona la finestra.

Ecco una soluzione che aggira questo e AFAIK non ha inconvenienti:

Invece di usare margin: auto per centrare i tuoi contenuti, usa questo:

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

Sostituisci 500 px con metà della larghezza massima del contenuto (quindi in questo esempio la larghezza massima del contenuto è 1000 px). Il contenuto ora rimarrà centrato e il margine diminuirà progressivamente fino a quando il contenuto non riempie la finestra.

Per evitare che il margine diventi negativo quando la finestra è più piccola della larghezza massima, basta aggiungere una query multimediale in questo modo:

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

Et voilà!


2

Se la larghezza della tabella non cambia, puoi impostare la larghezza dell'elemento (come tbody) che contiene la barra di scorrimento> 100% (consentendo spazio extra per la barra di scorrimento) e impostare overflow-y su "overlay" (quindi che la barra di scorrimento rimanga fissa e non sposterà la tabella a sinistra quando appare). Impostare anche un'altezza fissa per l'elemento con la barra di scorrimento, in modo che la barra di scorrimento venga visualizzata al superamento dell'altezza. Così:

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

Nota: dovrai regolare manualmente la larghezza% in quanto la% di spazio occupata dalla barra di scorrimento sarà relativa alla larghezza della tabella (ovvero: larghezza della tabella più piccola, più% necessaria per adattarsi alla barra di scorrimento, poiché la sua dimensione in pixel è costante )

Un esempio di tabella dinamica:

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>


1

Basta impostare la larghezza dell'elemento contenitore in questo modo per risolvere il problema

width: 100vw;

Questo farà sì che quell'elemento ignori la barra di scorrimento e funzioni con il colore di sfondo o le immagini.


-3

Ho usato un po 'di jquery per risolvere questo problema

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

$(document).ready(function(){
  $(window).load(function() {
    $('html').css({
      'overflow-y': ''
    });
  });
});

3
Probabilmente stai ricevendo una scarsa ricezione della tua risposta perché questa soluzione richiede un intero framework JavaScript. "jQuery tutte le cose!"
Paul Lammertsma,

3
sì, jQuery è sicuramente la strada da percorrere - doxdesk.com/img/updates/20091116-so-large.gif
Annonymous

-4
@media screen and (min-width: 1024px){
    body {
    min-height: 700px
    }
}

Benvenuto in Stack Overflow! Sebbene questo frammento di codice possa risolvere la domanda, inclusa una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che in futuro stai rispondendo alla domanda dei lettori e che queste persone potrebbero non conoscere i motivi del tuo suggerimento sul codice. Si prega inoltre di cercare di non riempire il codice con commenti esplicativi, questo riduce la leggibilità sia del codice che delle spiegazioni!
Andrew Myers,

-5

Contrariamente alla risposta accettata che suggerisce una barra di scorrimento permanente nella finestra del browser anche se il contenuto non trabocca sullo schermo , preferirei usare:

html{
  height:101%;
}

Questo perché l'aspetto della barra di scorrimento ha più senso se il contenuto trabocca effettivamente .

Questo ha più senso di così .


1
Almeno l'ultima frase è sbagliata nella tua risposta. Ha un senso simile con l'eccesso di pagina vuota stampata dalla stampante.
vp_arth,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.