Не позволяйте перемещаться по центру по центру, когда появляется полоса прокрутки

Мой макет страницы выглядит что-то вроде этого:

<style type="text/css">
#content-wrap
{
    margin: 0 auto;
    width: 800px;
}
</style>

<div id="content-wrap">
</div>

Вы заметите, что div-обтекатель содержимого смещает свою позицию чуть позже, когда появляется вертикальная полоса прокрутки. Один из сценариев - это когда браузер начинает постепенно выводить страницу без отображения вертикальной полосы прокрутки, а затем определяет, что требуется полоса прокрутки, потому что контент выше, чем "сгиб". Это сдвигает div примерно на 10 пикселей влево.

Каков наилучший способ решить эту проблему , не заставляя браузер всегда отображать полосу прокрутки?

Ответ 1

Я боюсь, что лучший способ решить эту проблему - заставить панель прокрутки постоянно быть видимой с помощью html {overflow-y: scroll;}. Проблема заключается в том, что "доступная область" сжимается, скажем, 10 пикселей при появлении полосы прокрутки. Это приведет к тому, что расчетная маржа на левой стороне уменьшится с половиной ширины полосы прокрутки, таким образом, перемещая центрированное содержимое несколько влево.

Возможное решение может заключаться в том, чтобы вычислить маржу с JavaScript вместо использования margin: 0 auto; и как-то компенсировать "потерянные" пиксели при появлении полосы прокрутки, но я боюсь, что это будет грязно, и контент, вероятно, будет перемещаться немного в любом случае, пока вы вычисляете и применяете новый запас.

Ответ 2

Используйте jquery и поместите это в начало вашего тега:

<script type="text/javascript">
function checkheight(){
 if ($(document).height() > $(window).height()) {
 //that is if there is vertical scrollbar
 document.getElementById('yourcenteredcontainer').style.paddingLeft='8px'; 
 //8px because the scrollbars are (?always?) 16px
 }else{
 document.getElementById('yourcenteredcontainer').style.paddingLeft='0px';
 }
}
</script>

и вызовите функцию checkheight(); в конце вашего тега плюс везде, где у вас есть onclick (или другие) события, которые делают страницу более длинной или меньшей по высоте.

Ответ 3

Если ваш сайт "реагирует" (реагирует на ширину):

Шаг 1: Добавьте width: 100vw в обертку div. Это делает его столь же широким, как и окно просмотра, игнорируя появление полосы прокрутки.

Шаг 2: Добавить overflow-x: hidden в тело. Это приведет к удалению горизонтальной полосы прокрутки (созданной при появлении вертикальной полосы прокрутки, позволяющей пользователю "смотреть под" ).

"wrapper div" ссылается на другой div вокруг вашего #content-wrap

Будет ли работать для вашего дела, проверено:

<style type="text/css">
body {
    overflow-x: hidden;
}
#wrap-wrap {
    width: 100vw;
}
#content-wrap
{
    margin: 0 auto;
    width: 800px;
}
</style>
<div id="wrap-wrap">
    <div id="content-wrap">
    </div>
</div>

Убедитесь, что на вашей странице ничего не достаточно, чтобы попасть под полосу прокрутки.


Если ваш сайт имеет фиксированную ширину + центрированную (ваш случай):

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

Это добавит левое поле, равное ширине, к полосе прокрутки, когда оно появится. Который 0, когда это не так. Взято из здесь, но протестировано.

Ответ 4

Если вы можете использовать Javascript, вы можете установить ширину content-wrap на внутреннюю ширину окна за вычетом стандартной ширины полосы прокрутки.

У вас возникнут некоторые проблемы.

  • Пользователь должен включить Javascript
  • Вы не знаете, что такое ширина вертикальной полосы прокрутки, особенно если полосы прокрутки там нет! Поэтому вам придется угадать. 20px кажется хорошим догадкой.
  • В разных браузерах есть разные способы сказать, что вам нужна внутренняя ширина окна.

Итак, если вы можете жить со всем этим, вы можете сделать что-то вроде этого (в псевдокоде)

if window.innerWidth is defined :
   set the width of the div to window.innerWidth-20px
else if we're running on Internet Explorer :
   set the width to document.documentElement.offsetWidth-20px
otherwise :
   we're out of luck and we best leave the width as is.

Ответ 5

Сначала я бы рекомендовал оптимизировать HTML, чтобы он не занимал много времени для загрузки/рендеринга. Если загрузка/рендеринг выполняется быстро, полоса прокрутки не будет отображаться "слишком поздно". Что это занимает много времени для загрузки/рендеринга? Проверьте вкладку сети в хром-инструментах отладки (F12). Сделайте аудит в инструментах отладки Chrome.

Есть несколько вещей, которые могли бы сделать документ " reflow", и полоса прокрутки появится, хотя браузер мог бы знать необходимые измерения с самого начала. Вы используете таблицы для макета - не надо! Им может потребоваться несколько проходов рендеринга. У вас есть изображения без указания ширины/высоты? Затем документ должен быть перезаписан, когда каждое изображение загружается. Укажите <img ... style="width: ..px; height: ..px">. Является CSS разумным и эффективным?

Если вы не можете получить скорость загрузки/рендеринга, я думаю, что лучше всего не использовать панель прокрутки браузера, если включен javascript. Таким образом, вы можете управлять им и поместить его абсолютно в положение, чтобы оно не повлияло на горизонтальное позиционирование.

Пусть ваш слайдер начнет с display: none. Мониторинг событий в режиме готовности, а также событий загрузки изображений, а также событий изменения размера окна. Когда страница загружена, изображения загружены, и когда окно изменяется, просто запускается одна и та же функция каждый раз. Он будет определять, нужна ли полоса прокрутки и отображать ее или скрывать.

Вы можете использовать JQuery UI Slider и установить maxValue на $(document).height() - $(window).height(), отслеживать событие изменения слайдера, а затем прокручивать тело до значение ползунка и т.д.

Если javascript отключен, резервным будет обычная полоса прокрутки, и вы ничего не сможете сделать с небольшим горизонтальным сдвигом.

Но на самом деле я думаю, что проблема горизонтального сдвига слишком мала, чтобы тратить время на создание специальной полосы прокрутки и проверять, что она действительно хорошо работает на всех платформах и т.д. Сначала оптимизируйте HTML/CSS.