วิธีการป้องกันแถบเลื่อนจากการเปลี่ยนตำแหน่งหน้าเว็บ?


218

ฉันมีเว็บไซต์ที่มี DIV ที่จัดกึ่งกลาง ตอนนี้บางหน้าต้องเลื่อนบางคนไม่ เมื่อฉันย้ายจากประเภทหนึ่งไปยังอีกประเภทลักษณะที่ปรากฏของแถบเลื่อนจะย้ายพิกเซลไปทางด้านข้างไม่กี่พิกเซล มีวิธีใดในการหลีกเลี่ยงสิ่งนี้โดยไม่แสดงแถบเลื่อนในแต่ละหน้าอย่างชัดเจนหรือไม่


6
ทำไมไม่มีใครพูดถึงoverflow-y: overlayในหัวข้อนี้?
milkersarac

3
เอกสารอ้างอิงของ mozilla overflow-y: overlayนั้นคิดค่าเสื่อมราคา: developer.mozilla.org/en-US/docs/Web/CSS/overflow
drojf

คำตอบ:


266

overflow-y: scroll ถูกต้อง แต่คุณควรใช้กับ tag html ไม่ใช่ body หรืออย่างอื่นคุณจะได้ double scrollbar ใน IE 7
ดังนั้น css ที่ถูกต้องน่าจะเป็น:

html {
  overflow-y: scroll;
}

1
IE 10+ มี scrollbar แบบลอยดังนั้นคุณควรปิดการใช้งานสิ่งนี้สำหรับเบราว์เซอร์เหล่านี้
Ruben

1
นี้อาจทำให้เกิดปัญหาเช่นเลื่อนคู่เมื่อใช้ร่วมกับ fancybox หรือ Twitter บูตกิริยา
Ruben

ข้อมูลพิเศษ: twitter bootstrap ตอนนี้เพิ่ม. modal-open ให้กับคุณเมื่อ modal เปิดอยู่
Ruben

55
เป็นมูลค่าการกล่าวขวัญว่านี่แสดงแถบเลื่อนแนวตั้งอย่างถาวร อาจไม่เป็นที่ยอมรับเสมอไป
rustyx

ฉันได้รับแถบเลื่อนคู่ในทั้ง Chromium และ Firefox ฉันกำลังใช้เฟล็กซ์บ็อกซ์ บางทีนั่นอาจจะเป็นสาเหตุนี้ ...
การ์เร็ต

72

ห่อเนื้อหาขององค์ประกอบเลื่อนของคุณเป็น div 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>

เคล็ดลับคือ100vwแสดงถึง 100% ของวิวพอร์ตรวมถึงแถบเลื่อน หากคุณลบ100%ซึ่งเป็นพื้นที่ว่างที่ไม่มีแถบเลื่อนคุณจะพบกับความกว้างของแถบเลื่อนหรือ0หากไม่มีอยู่ การสร้างช่องว่างภายในของความกว้างนั้นทางด้านซ้ายจะจำลองแถบเลื่อนที่สองโดยเลื่อนเนื้อหากึ่งกลางกลับไปทางขวา

โปรดทราบว่านี่จะใช้งานได้หากองค์ประกอบที่เลื่อนได้ใช้ความกว้างทั้งหมดของหน้า แต่ไม่น่าจะมีปัญหาได้บ่อยครั้งเพราะมีเพียงบางกรณีเท่านั้นที่คุณมีเนื้อหาที่เลื่อนได้อยู่ตรงกลาง


1
จะใช้กับคลาสได้ดีกว่าสไตล์อินไลน์และจะใช้ได้เฉพาะในเบราว์เซอร์เหล่านี้แต่นี่เป็นเทคนิคที่ฉลาด - ฉันไม่ได้ตระหนักถึงสิ่งนั้น100vwและ100%วัดสิ่งต่าง ๆ ดังนั้นฉันเรียนรู้สิ่งที่มีประโยชน์จากสิ่งนี้!
Nick F

21
นี่เป็นอัจฉริยะอย่างแท้จริงและเป็นคำตอบที่ดีที่สุดในการพิจารณาการสนับสนุนเบราว์เซอร์สำหรับ Calc นั้นดีมาก
ไมเคิล

1
คุณสามารถทำเช่นเดียวกันได้ยกเว้นการเพิ่มระยะขอบทางซ้ายคุณเพิ่มระยะขอบติดลบทางด้านขวา (ดูstackoverflow.com/a/39289453/6015444 )
Touniouk

2
วิธีนี้จะทำให้เกิดปัญหาที่คล้ายกันกับสีพื้นหลังเช่นคำตอบ "width: calc (100vw - 34px);" แต่ด้านซ้าย
Maciej Lew

1
ผมอยากจะแนะนำให้เพิ่มคำสั่งสื่อบางอย่างเพื่อ @media screen and (min-width: 800px) {...} style- ในกรณีที่เนื้อหาจะพอดีกับความกว้างของหน้า ตัวอย่างเช่นความละเอียดขนาดเล็กจะมีช่องว่างที่ไม่จำเป็นขยับเนื้อหาไปทางขวา
MarkosyanArtur

44

ผมคิดว่าไม่. แต่จัดแต่งทรงผมbodyด้วยoverflow: scrollควรจะทำอย่างไร คุณดูเหมือนจะรู้ว่าแม้ว่า


3
ฟังดูดี ... บังคับให้หน้าแสดงแถบเลื่อนเสมอว่าต้องการหรือไม่ ... จากนั้นจะไม่มีการเปลี่ยนแปลงระหว่างประเภทหน้าเว็บ
eidylon

1
ใช่ แต่ IIRC จะแสดงแถบเลื่อนทั้งสอง ฉันไม่ต้องการแนวนอนจริงๆ
Dmitri Nesteruk

นั่นเป็นเรื่องจริง แต่มีไม่มากที่ฉันสามารถทำได้เพื่อช่วยให้คุณ: (ที่จริงแล้วฉันพิจารณาเฉพาะประโยคแรกของคำตอบของฉันเท่านั้นที่จะเป็นคำตอบที่แท้จริงที่เกี่ยวข้องกับคำถามนี้
Michael Krelin - แฮกเกอร์

49
overflow-y: scroll:)
Svish

2
ต่อไปนี้เป็นคำตอบที่ดีกว่า
Sam

36

ด้วยการเลื่อนแสดงอยู่เสมออาจไม่ดีสำหรับการจัดวาง

พยายาม จำกัด ความกว้างของร่างกายด้วย css3

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

vwคือความกว้างของวิวพอร์ต (ดูลิงค์นี้สำหรับคำอธิบาย)
calcคำนวณใน css3
34pxย่อมาจากความกว้างของแถบเลื่อนสองเท่า (ดูที่นี่เพื่อแก้ไขหรือเพื่อคำนวณหากคุณไม่เชื่อถือขนาดคงที่)


4
ทุกอย่างไร้ประโยชน์จนกระทั่งมีคนต้องการ
Moesio

3
นี่เป็นการรบกวนทางสายตาน้อยกว่าการบังคับสคอลบาร์เช่นคำตอบที่ได้รับการยอมรับ
สิลาสแฮนเซ่น

4
สิ่งนี้ได้ผลดีที่สุดสำหรับความต้องการของฉันจนถึงตอนนี้ฉันยังได้เพิ่มpadding-left: 34px;หน้าเว็บของฉันให้อยู่กึ่งกลาง
Pat Migliaccio

3
นี่ควรเป็นคำตอบที่ได้รับการยอมรับไม่เหมือนกับคำตอบที่ยอมรับในปัจจุบันซึ่งเป็นคำตอบของคำถาม!
Coz

2
สิ่งนี้จะทำให้เกิดปัญหาหากคุณมีแถบนำทาง / ส่วนหัวที่มีสีแตกต่างจากพื้นหลังของร่างกายหรือเส้นขอบด้านล่างเป็นต้น
Zia Ul Rehman Mughal

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

ตัวอย่าง คลิกปุ่ม "เปลี่ยนความสูงขั้นต่ำ"

ด้วยcalc(100vw - 100%)เราสามารถคำนวณความกว้างของแถบเลื่อน (และถ้ามันไม่ปรากฏก็จะเป็น 0) แนวคิด: โดยใช้ระยะขอบติดลบ - ขวาเราสามารถเพิ่มความกว้างของ<html>ความกว้างนี้ คุณจะเห็นแถบเลื่อนแนวนอน - overflow-x: hiddenมันควรจะถูกซ่อนไว้ใช้


ผมต้องทำให้ร่างกายใน div และใช้อัตรากำไรขั้นต้นที่จะ div สำหรับมันในการทำงาน (คล้ายกับคำตอบของ Rapti .) แต่ลักษณะนี้เพื่อ neater มาก
Touniouk

1
มันใช้งานได้ดีและดูเหมือนจะไม่ส่งผลให้แถบเลื่อนแนวนอนที่ไม่ต้องการใน Chrome หรือ Firefox ทำไมไม่ใช้เพียงแค่calc(100% - 100vw)คูณด้วย-1?
SystemParadox

13

ฉันไม่ทราบว่านี่เป็นโพสต์เก่า แต่ฉันมีปัญหาเดียวกันและหากคุณต้องการเลื่อนในแนวตั้งคุณควรลองเท่านั้น overflow-y:scroll


13

หากเปลี่ยนขนาดหรือหลังจากโหลดข้อมูลบางส่วนมันเป็นการเพิ่มแถบเลื่อนจากนั้นคุณสามารถลองทำตามนี้สร้างคลาสและใช้คลาสนี้

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

3

ฉันได้แก้ไขปัญหาในหนึ่งในเว็บไซต์ของฉันโดยกำหนดความกว้างของเนื้อความใน javascript ตามขนาดวิวพอร์ตลบความกว้างของแถบเลื่อน ฉันใช้ฟังก์ชันตาม jQuery ที่มีเอกสารที่นี่เพื่อกำหนดความกว้างของแถบเลื่อน

<body id="bodyid>

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

10
ฉันไม่สามารถเริ่มอธิบายได้ว่าทำไมถึงเป็นการปฏิบัติที่ไม่ดีเช่นนี้
mythofechelon

20
@BenHooper: ฉันต้องการที่จะรู้ว่าทำไมนี่คือการปฏิบัติที่ไม่ดี
ซาด

1
จะเกิดอะไรขึ้นถ้าคุณปรับขนาดหน้าต่าง
Braden Steffaniak

3

ขยายคำตอบโดยใช้สิ่งนี้:

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

ผู้วิจารณ์คนหนึ่งแนะนำให้เพิ่มการเว้นระยะซ้ายเช่นกันเพื่อรักษาจุดศูนย์กลาง:

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

แต่สิ่งต่าง ๆ จะดูไม่ถูกต้องหากเนื้อหาของคุณกว้างกว่าวิวพอร์ต ในการแก้ไขปัญหานั้นคุณสามารถใช้คิวรีสื่อเช่นนี้:

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

โดยที่ 1058px = ความกว้างของเนื้อหา + 17 * 2

สิ่งนี้ทำให้แถบเลื่อนแนวนอนจัดการกับ x มากเกินและทำให้เนื้อหาอยู่กึ่งกลางอยู่ตรงกลางเมื่อวิวพอร์ตกว้างพอที่จะบรรจุเนื้อหาที่มีความกว้างคงที่ของคุณ


3

การขยายออกไปจากคำตอบของ Raptiสิ่งนี้น่าจะใช้ได้เช่นกัน แต่เพิ่มระยะขอบที่ด้านขวาของbodyและซ่อนด้วยhtmlขอบลบแทนที่จะเพิ่มช่องว่างเพิ่มเติมที่อาจส่งผลต่อเค้าโครงของหน้าเว็บ ด้วยวิธีนี้ไม่มีการเปลี่ยนแปลงในหน้าจริง (ในกรณีส่วนใหญ่) และรหัสยังคงใช้งานได้

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

ฉันพบว่าบนโครเมียมจะเพิ่มการเลื่อนในแนวนอนบนหน้าเว็บที่มีแถบเลื่อนแนวตั้งในเว็บไซต์ bootstrap ของฉัน
กระรอกขิง

คุณลองมองดูว่าทำไม ตรวจสอบองค์ประกอบของผู้ตรวจสอบและดูว่า Bootstrap ยุ่งกับระยะขอบแถบเลื่อนหรืออะไรทำนองนั้น
Grant Gryczan

1
อาจเป็นสิ่งที่เกี่ยวข้องกับระยะขอบ 15px ที่ bootstrap ใส่ทุกอย่างเมื่อตรวจสอบหน้าขอบของคอนเทนเนอร์จะอยู่ใต้แถบเลื่อน ฉันสมัครoverflow-x: hiddenแล้วก็แก้ไขมัน
Ginger Squirrel

3

วิธีการแก้ปัญหาของ @kashesandrทำงานได้สำหรับฉัน แต่เพื่อซ่อนแถบเลื่อนแนวนอนฉันได้เพิ่มสไตล์ให้กับร่างกายอีกหนึ่งรูปแบบ นี่คือทางออกที่สมบูรณ์:

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 (เมื่อ modal ที่ 2 เปิดจาก modal ที่ 1):

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

ผมพยายามที่จะแก้ไขปัญหาเดียวกันมีแนวโน้มที่เกิดจากการบูต Twitter ชั้นนำไปใช้กับ.modal-open bodyการแก้ปัญหาhtml {overflow-y: scroll}ไม่ได้ช่วย ทางออกหนึ่งที่เป็นไปได้ที่ผมพบคือการเพิ่ม{width: 100%; width: 100vw}ไปยังhtmlองค์ประกอบ


1
หรือเปลี่ยนเป็น body {overflow-y: scroll}
Ruben

1
แต่นั่นจะแสดงแถบเลื่อนเสมอแม้ว่าจะไม่จำเป็นก็ตาม
Rapti

คุณควรอธิบายว่าทำไมคุณถึงตั้งค่าความกว้างสองครั้ง html { width: 100vw; }ทำงานให้ฉัน
Hassan Tareq

สำหรับฉันมันสร้างแถบเลื่อนสองอัน
rbansal


2

โซลูชันที่โพสต์โดยใช้ calc (100vw - 100%) อยู่ในเส้นทางที่ถูกต้อง แต่มีปัญหากับสิ่งนี้: คุณจะมีระยะขอบด้านซ้ายเท่ากับขนาดของแถบเลื่อนตลอดแม้ว่าคุณจะปรับขนาดหน้าต่างเพื่อให้ เนื้อหาเติมวิวพอร์ตทั้งหมด

หากคุณพยายามที่จะหลีกเลี่ยงปัญหานี้ด้วยการสืบค้นสื่อคุณจะมีช่วงเวลาที่น่าอึดอัดใจเพราะระยะขอบจะไม่เล็กลงเมื่อคุณปรับขนาดหน้าต่าง

นี่เป็นวิธีแก้ปัญหาที่ได้รับมาและ AFAIK ไม่มีข้อเสีย:

แทนที่จะใช้มาร์จิ้น: อัตโนมัติเพื่อจัดกึ่งกลางเนื้อหาของคุณใช้สิ่งนี้:

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

แทนที่ 500px ด้วยความกว้างสูงสุดของเนื้อหาของคุณครึ่งหนึ่ง (ดังนั้นในตัวอย่างนี้ความกว้างสูงสุดของเนื้อหาคือ 1000px) ตอนนี้เนื้อหาจะอยู่กึ่งกลางและส่วนต่างจะลดลงเรื่อย ๆ จนกว่าเนื้อหาจะเต็มวิวพอร์ต

หากต้องการหยุดกำไรจากการเป็นลบเมื่อวิวพอร์ตมีขนาดเล็กกว่าความกว้างสูงสุดเพียงแค่เพิ่มคิวรีสื่อเช่น:

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

และอื่น ๆ !


2

หากความกว้างของตารางไม่เปลี่ยนแปลงคุณสามารถตั้งค่าความกว้างขององค์ประกอบ (เช่น tbody) ที่มีแถบเลื่อน> 100% (ให้พื้นที่เพิ่มเติมสำหรับแถบเลื่อน) และตั้งค่า overflow-y เป็น "overlay" (เช่น แถบเลื่อนจะคงที่และจะไม่เลื่อนโต๊ะไปทางซ้ายเมื่อมันปรากฏขึ้น) นอกจากนี้ยังตั้งความสูงคงที่สำหรับองค์ประกอบด้วยแถบเลื่อนดังนั้นแถบเลื่อนจะปรากฏขึ้นเมื่อความสูงเกิน ชอบมาก

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

หมายเหตุ: คุณจะต้องปรับความกว้าง% ด้วยตนเองเนื่องจาก% ของพื้นที่ที่แถบเลื่อนใช้จะสัมพันธ์กับความกว้างของตารางของคุณ (เช่น: ความกว้างของตารางที่เล็กลงจำเป็นต้องมี% มากกว่านี้เพื่อให้พอดีกับแถบเลื่อนเนื่องจากขนาดของพิกเซลคงที่ )

ตัวอย่างตารางแบบไดนามิก:

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

เพียงตั้งค่าความกว้างขององค์ประกอบคอนเทนเนอร์ของคุณเช่นนี้จะทำการหลอกลวง

width: 100vw;

สิ่งนี้จะทำให้องค์ประกอบนั้นละเว้นแถบเลื่อนและทำงานได้กับสีพื้นหลังหรือรูปภาพ


-3

ฉันใช้ jQuery เพื่อแก้ปัญหานี้

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

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

3
คุณอาจได้รับการตอบรับที่ไม่ดีเนื่องจากโซลูชันนี้ต้องใช้กรอบงาน JavaScript ทั้งหมด "jQuery ทุกสิ่ง!"
Paul Lammertsma

3
ใช่ jQuery แน่นอนวิธีที่จะไป - doxdesk.com/img/updates/20091116-so-large.gif
annonymous

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

ยินดีต้อนรับสู่ Stack Overflow! ในขณะที่ข้อมูลโค้ดนี้อาจแก้ไขคำถามรวมถึงคำอธิบายช่วยปรับปรุงคุณภาพของโพสต์ของคุณ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและคนเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำรหัสของคุณ โปรดอย่าพยายามทำให้รหัสของคุณแน่นเกินไปด้วยคำอธิบายที่อธิบายซึ่งจะช่วยลดความสามารถในการอ่านของทั้งรหัสและคำอธิบาย!
Andrew Myers

-5

ตรงกันข้ามกับคำตอบที่ยอมรับซึ่งแนะนำแถบเลื่อนแบบถาวรบนหน้าต่างเบราว์เซอร์แม้ว่าเนื้อหาจะไม่ล้นหน้าจอฉันก็อยากใช้:

html{
  height:101%;
}

เพราะนี่คือการปรากฏตัวของแถบเลื่อนทำให้รู้สึกมากขึ้นถ้าเนื้อหาจริงล้น

นี้ทำให้รู้สึกมากขึ้นกว่านี้


1
อย่างน้อยประโยคสุดท้ายนั้นผิดในคำตอบของคุณ มันทำให้รู้สึกคล้ายกับหน้าว่างเกินที่พิมพ์โดยเครื่องพิมพ์
vp_arth
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.