100vw вызывает горизонтальное переполнение, но только если их больше одного?

97

Скажем, у вас есть это:

html, body {margin: 0; padding: 0}
.box {width: 100vw; height: 100vh}

<div class="box">Screen 1</div>

Вы получите то, что заполняет экран, без полос прокрутки. Но добавьте еще:

<div class="box">Screen 1</div>
<div class="box">Screen 2</div>

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

Я понимаю, что вы можете опустить ширину или установить ее на width: 100%, но мне любопытно, почему это происходит. Разве 100vw не должно быть "100% ширины области просмотра"?

rdoyle720
источник
избежать переполнения, скрытого в html и теле, это не лучшее решение, если вы хотите использовать фиксированное положение для любого из его дочерних элементов ... max-width кажется хорошим способом !!!
NeueDeutsche,

Ответы:

149

Как уже объяснялось в wf4, горизонтальная прокрутка присутствует из-за вертикальной прокрутки. которую вы можете решить, дав max-width: 100%.

.box {
    width: 100vw;
    height: 100vh;
    max-width:100%;  /* added */
}

Рабочая скрипка

Мистер Грин
источник
3
Спасибо, это хорошо помогает решить проблему, но я все еще думаю, что это немного неинтуитивное поведение по умолчанию.
Phocks
2
Насчет неинтуитивности: согласно caniuse.com, это ошибка браузера. caniuse.com/#feat=viewport-units -> Известная проблема 8. В настоящее время все браузеры, кроме Firefox, ошибочно считают 100vw всей шириной страницы, включая вертикальную полосу прокрутки, которая может вызвать горизонтальную полосу прокрутки при переполнении: установлено auto .
Якоб ван Линген
47
Если max-width: 100%это ширина области просмотра без полос прокрутки, тогда вам 100vwв первую очередь не нужно :-) Вы могли бы просто использовать, width: 100%потому что элемент не имеет позиционированного предка, поэтому его ссылкой является тело.
Capsule,
8
Это ничего не решает! max-width работает только потому, что элемент является прямым потомком тела! В любом реальном случае, когда вы использовали бы 100vw вместо 100% (например, элемент внутри контейнера), это не сработает.
Элиэзер Берлин
2
Я не могу использовать ширину 100%, потому что мой div находится в контейнере, ширина или заполнение которого я не знаю. В этом вся причина использовать 100vw вместо 100%, поэтому этот ответ бессмысленен. И это также происходит на Mac, если вы настроили всегда показывать полосы прокрутки, даже если полосы прокрутки нет.
Curtis
37

Полосы прокрутки будут включены в, vwпоэтому будет добавлена ​​горизонтальная прокрутка, чтобы вы могли видеть под вертикальной прокруткой.

Когда у вас всего 1 коробка, она имеет ширину 100% и высоту 100%. Когда вы добавляете 2, его ширина 100% и высота 200%, поэтому срабатывает вертикальная полоса прокрутки. Когда срабатывает вертикальная полоса прокрутки, она затем запускает горизонтальную полосу прокрутки.

Вы можете добавить overflow-x:hiddenкbody

html, body {margin: 0; padding: 0; overflow-x:hidden;}
.box {width: 100vw; height: 100vh; background-color:#ff0000}
.box2 {width: 100vw; height: 100vh; background-color:#ffff00}

http://jsfiddle.net/NBzVV/

wf4
источник
1
В результате содержимое отображается под полосой прокрутки. jsfiddle.net/NBzVV/1 Чтобы это было подходящим решением, вам нужно добавить правильные отступы.
Джеймс Доннелли
1
Ага, хорошо подмечено. Добавление max-width:100%к .boxпредотвратит это.
wf4
4
«так что горизонтальная прокрутка будет добавлена, чтобы вы могли видеть под вертикальной прокруткой» <- это предложение помогло моему мозгу осознать, что на самом деле происходит. +1
Иван Дерст
Просто примечание о том, что overflowдаже если вы добавите его к этому, xничего не postition: stickyбудет работать.
Т.Чмелевский
9

У меня была аналогичная проблема, и я предложил следующее решение с использованием переменных JS и CSS.

JS:

function setVw() {
  let vw = document.documentElement.clientWidth / 100;
  document.documentElement.style.setProperty('--vw', `${vw}px`);
}

setVw();
window.addEventListener('resize', setVw);

CSS:

width: calc((var(--vw, 1vw) * 100);

1vw - запасное значение.

Степан Шатковский
источник
1
Люблю это. довольно элегантно
andrevenancio
Это идеально, потому что тогда он доступен по всему миру. Спасибо.
fvaldez421
2

Обновление: Начиная с версии Chrome 66, я больше не могу воспроизвести поведение, указанное в вопросе. Никакого обходного пути не требуется.


Оригинальный ответ

На самом деле это ошибка, о которой сообщается в этом ответе и комментариях выше.

Хотя обходной путь в принятом ответе (добавление .box {max-width: 100%;}) в целом работает, я считаю примечательно, что он в настоящее время не работает display:table(проверено в Chrome). В этом случае я нашел единственный обходной путь - использовать width:100%вместо него.

Корнфлекс
источник
Гм, принятый ответ изменился? Вы предлагаете то же, что и принятый ответ. Вот почему ответы должны быть полными.
Киссаки 02
В принятом ответе предлагается добавить max-width: 100%. Я предложил перейти width: 100vwна width: 100%. Я обновил свой ответ, сделав его самодостаточным.
Cornflex 03
Помимо Chrome, существуют и другие браузеры, и некоторые по-другому работают с полосой прокрутки.
LocalPCGuy
1

чтобы избавиться от ширины полосы прокрутки, включенной в vw, мне пришлось сделать это:

html, body {
    overflow-x: hidden;
    height: 100vh;
}
мануэль-84
источник
1
*,
html,
body {
  margin: 0;
  padding: 0;
  overflow: hidden;/*add This*/ 
}
/*and enjoy ^_^ */
user13149444
источник
6
Скрытие проблемы не решает ее. Хотя ваш подход действительно устраняет переполнение, он просто скрывает его. Это может вызвать проблемы, когда контент должен отображаться снаружи (по какой-либо причине)
Даниэль Штайнер,
3
Привет, user13149444! Ответы только на код могут решить проблему, но они будут гораздо полезнее, если вы объясните, как они ее решают. Сообщество требует как теории, так и кода, чтобы полностью понять ваш ответ.
RBT