Начните использовать CSS width: 100% вместо width: 100vw и посмотрите, как «единицы окна просмотра» могут вызывать полосы прокрутки.

Горизонтальные полосы прокрутки - признак «горизонтального переполнения» ваших сайтов и приложений. Давай исправим.

Вот вам загадка CSS

Если видимая часть документа (его область просмотра) имеет ширину 100 vw », какова ширина 100vw?

Чтобы поместить это в CSS, width: 100vw должен быть полноэкранным, что эквивалентно width: 100%, верно?

Неправильный.

В модели размера коробки CSS есть странная ошибка, которая на самом деле не является ошибкой, но это важная вещь, о которой нужно знать.

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

Другими словами, CSS width: 100vw должен работать, если вам нужен полноразмерный HTML-элемент на веб-сайте. Но это не из-за какой-то довольно неудачной математики, которую я назову махинациями вьюпорта ».

Ошибка (функция?) Горизонтальных полос прокрутки обычно проявляется, когда кто-то привык использовать 100vw при создании одностраничного приложения, как это часто бывает при использовании React, Next.js или вашего любимого фреймворка.

Давайте сначала поговорим о том, почему 100vw не работает, а затем я покажу вам десять решений, чтобы исправить те горизонтальные полосы прокрутки, которые появлялись без причины, когда вы пытались создать простой полноэкранный веб-сайт.

Оглавление

1) Add Width: 100% to All Parent Containers
2) Use Position: Fixed To Anchor the Content
3) Hide the Scrollbars Using Overflow-X: Hidden
4) Use Width: 100vi Instead of Width: 100vw
5) No Vertical Scrollbars, No Problem (Height: 100vw)
6) Set a Maximum Width With Max-Width: 100%
7) Use a Fixed Width With Max-Width: 100%
8) Tailwind CSS: Use W-Full Instead of W-Screen
9) Tailwind CSS: Use Fixed To Anchor the Content
10) Tailwind CSS: Hide Scrollbars Overflow-X-Hidden

Что такое область просмотра в CSS?

Возможно, вы видели следующий HTML-код практически на каждом современном веб-сайте и задавались вопросом, что именно он делает:

По словам Криса Койера из CSS-Tricks.com, это означает, что браузер (вероятно) будет отображать ширину страницы« на ширине своего собственного экрана ». Мы определяем область просмотра, но что такое область просмотра?

Длина окна просмотра в процентах определяет значение <length> относительно размера« области просмотра , то есть видимой части документа. Длины области просмотра недопустимы в @page блоках объявлений.

vh Равно 1% от высоты начального содержащего блока области просмотра.

vw Равно 1% ширины начального содержащего блока области просмотра. »
- MDN Docs

Для нашего обсуждения достаточно знать, что область просмотра - это видимая часть документа на веб-сайте. Это понятие мы обычно ассоциируем с мобильными устройствами, но у всех браузеров есть область просмотра.

Указывать «полноэкранный» документ с помощью 100vh и 100vw должно быть просто, и это общий подход для одностраничных приложений.

На обычных веб-сайтах мы используем вертикальную прокрутку, но горизонтальная прокрутка не так распространена у пользователей. Это означает, что 100vw должен быть во всю ширину области просмотра, и это так, но нам нужно понять, насколько широкая область просмотра на самом деле.

Понимание модели изменения размеров блока CSS

Одним из фундаментальных аспектов CSS является его «модель размера блока», но это также одна из самых запутанных вещей в CSS.

По умолчанию в« блочной модели CSS width и height, которые вы назначаете элементу, применяются только к блоку содержимого элемента. Если у элемента есть какие-либо границы или отступы, они добавляются к width и height, чтобы получить размер поля, отображаемого на экране ». - MDN Docs

Этот тип вещей лучше всего продемонстрировать визуально, что вы легко можете сделать с помощью DevTools вашего браузера. Вот снимок Chrome с включенной Отладкой CSS, который автоматически рисует блочную модель CSS:

Если вы когда-либо включали свойство границы CSS, чтобы увидеть, как браузер размещает ваш контент, вы знакомы с блочной моделью. Инструмент «Отладка CSS» просто делает все поля видимыми одновременно.

Мы можем получить подробную информацию о расчете блочной модели CSS в Chrome DevTools, найдя раздел Вычисленные:

Это модель блока CSS для серого блока кода на снимке экрана выше, который является элементом <pre> в HTML-коде веб-сайта.

Мы видим, что коробка имеет ширину 660 пикселей и высоту 44 пикселя, с 20 пикселями отступа со всех четырех сторон. Отступ сверху всего в 43 пикселя. Отступ считается шириной и сдвигает границу, в то время как поле не считается частью ширины элемента.

Чтобы связать область просмотра с блочной моделью CSS, мы должны ввести концепцию полос прокрутки для обработки «визуального переполнения».

Горизонтальные полосы прокрутки = горизонтальное переполнение

Когда у нас появляются полосы прокрутки на веб-сайте, это происходит потому, что размер контента больше, чем видимая область. Это называется переполнение, термин похож на печать без полей с полем обрезки ».

Как и при печати визитных карточек, вы можете вырезать карточку из листа бумаги большего размера; дополнительно - это переполнение. Это печать без полей, и я думаю, что это полезная метафора для понимания переполнения CSS.

Переполнение, с которым нам иногда приходится справляться в CSS, описывается как переполнение с возможностью прокрутки. Это контент, появляющийся за пределами коробки, для которого должны быть предусмотрены механизмы прокрутки. Свойства переполнения - это то, как мы можем контролировать, что происходит, когда содержимое выходит за пределы поля . - MDN Docs

Это имеет смысл - если вы укажете фиксированную ширину 3000 пикселей в CSS, кто-то с разрешением 1920x1080 увидит только 1920 пикселей слева от содержимого на веб-сайте. С правой стороны есть «горизонтальное переполнение», поэтому вы увидите горизонтальные полосы прокрутки.

Мобильные дисплеи могут быть менее 400 пикселей в ширину, в то время как настольные дисплеи могут быть очень большими (у меня 2560x1440). Вот почему современные разработчики создают сайты и приложения в первую очередь для мобильных, используя адаптивный веб-дизайн.

Подключение области просмотра и прокручиваемого переполнения

Мы определили область просмотра как видимую часть сайта или приложения в браузере, так почему же мы получаем горизонтальные полосы прокрутки с width: 100vw? Как и в случае с блочной моделью CSS, нам необходимо учитывать дополнительное пространство.

Хотя пользовательский интерфейс браузера не считается частью области просмотра, полосы прокрутки на самом деле учитываются. Так что, если вы установите и width: 100vw, и height: 100vh, как для одностраничного приложения, он будет работать нормально.

Однако, если вам нужна полная ширина и нормальная высота, как почти на каждом веб-сайте в Интернете, у вас будет вертикальная полоса прокрутки. Это повлияет на ширину области просмотра.

Доступное только для чтения свойство« Window innerWidth возвращает внутреннюю ширину окна в пикселях. Сюда входит ширина вертикальной полосы прокрутки, если таковая имеется.

Точнее, innerWidth возвращает ширину визуального окна просмотра. Внутреннюю высоту окна - высоту области просмотра макета - можно получить из свойства innerHeight ». - MDN Docs

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

Расчет ширины области просмотра - это не совсем то же самое, что и блочная модель CSS, но принципы аналогичны, поскольку наша реальная ширина на самом деле шире, чем мы ожидали.

При вычислении области просмотра полоса прокрутки считается шириной. Сравните это с блочной моделью CSS, где ширина включает padding и border.

(Свойство height ведет себя так же, как width в обеих моделях.)

Существует множество решений для удаления этих нежелательных горизонтальных полос прокрутки на полноразмерных веб-сайтах, от отключения overflow до изменения того, как мы определяем width в CSS.

Давайте рассмотрим десять различных исправлений, чтобы найти то, которое лучше всего подойдет вам и вашему адаптивному веб-сайту.

1) Добавьте ширину: 100% ко всем родительским контейнерам

Во-первых, давайте просто заменим width: 100vw на width: 100%. Последний, который не относится к области просмотра браузера, никогда не будет отображать горизонтальные полосы прокрутки. Проблема решена, да?

Свойство width CSS устанавливает ширину элемента. По умолчанию он устанавливает ширину «области содержимого, но если для box-sizing установлено значение border-box, он устанавливает ширину области границы ». - MDN Docs

По умолчанию width для всех элементов - auto, что означает, что браузер автоматически рассчитает и выберет ширину для указанного элемента. Это означает, что здесь есть небольшая загвоздка.

Загвоздка в том, что используемое нами значение width: 100% основано на размере родительского контейнера. Это означает, что если вы пытаетесь создать элемент во всю ширину, но его родительский элемент имеет меньший размер, вы не сможете использовать все 100% width области просмотра.

Чтобы исправить это, вам нужно исследовать ширину каждого родительского контейнера, чтобы убедиться, что все имеет ширину 100%, а не меньше.

Однако в целом замена 100vw на 100% - отличное решение. Однако это не единственное решение, так что давайте продолжим.

2) Использовать положение: исправлено для привязки содержимого

Я обнаружил ошибку горизонтальных полос прокрутки, когда пытался создать полноразмерное адаптивное изображение при создании приложения Next.js с помощью React. В моем HTML-коде я пытался «вырваться» из родительского контейнера, для которого в CSS была определена max-width (максимальная ширина).

Обычно вы хотите выйти из контейнера, когда у вас есть фиксированное навигационное меню или нижний колонтитул, который вы хотите прикрепить к верхней или нижней части экрана. Обычно этого эффекта можно добиться, используя position: fixed, хотя есть и более новые position: sticky.

Переполнение элемента с фиксированной позицией будет автоматически скрыто и недоступно для прокрутки, хотя 100vw по-прежнему будет включать вертикальную полосу прокрутки. На скриншоте ниже я добавил большую красную рамку, чтобы вы могли видеть, что элемент очень широкий, хотя у нас больше нет полосы прокрутки.

Свойство CSS Box-sizing: Border-box

Здесь уместно упомянуть, что изменение модели размера блока CSS с помощью свойства CSS box-sizing: border-box не решит проблему с окном просмотра, но об этом следует знать.

border-box указывает браузеру учитывать любые границы и отступы в значениях, которые вы указываете для ширины и высоты элемента. Если вы установите ширину элемента на 100 пикселей, эти 100 пикселей будут включать любую границу или отступ, которые вы добавили, а поле содержимого сократится, чтобы поглотить эту дополнительную ширину. Обычно это значительно упрощает размер элементов . - MDN Docs

В отличие от значения по умолчанию box-sizing: content-box, border-box не учитывает отступы и границу как часть ширины элемента. Это полезно для определенных проблем с шириной, но не исправляет горизонтальные полосы прокрутки, связанные с шириной области просмотра.

content-box дает вам поведение CSS по умолчанию при изменении размера окна. Если вы установите ширину элемента на 100 пикселей, тогда ширина поля содержимого элемента будет 100 пикселей, а ширина любой границы или отступа будет добавлена ​​к окончательной ширине отрисовки, что сделает элемент шире 100 пикселей . - MDN Docs

Я думал, что box-sizing: border-box должен работать, потому что иногда можно удалить горизонтальные полосы прокрутки, установив * { margin: 0; }. Этот фрагмент CSS удалит поле по умолчанию для всех элементов HTML, включая <body>, у которого поле по умолчанию составляет 8 пикселей. (Часто разработчики используют такой инструмент, как Normalize.CSS, чтобы удалить все стили по умолчанию.)

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

При поведении по умолчанию (box-sizing: content-box) граница и отступы считаются шириной, но мы можем игнорировать границу и отступы с помощью box-sizing: border-box. Свойство не влияет на маржу.

3) Скрыть полосы прокрутки с помощью overflow-x: Hidden

Если вы не хотите устранять проблему с горизонтальной полосой прокрутки, просто игнорируйте ее! Хотя это не обязательно лучшее решение, вам обязательно нужно знать об этом в CSS.

Сокращенное свойство overflow« CSS устанавливает желаемое поведение для переполнения элемента - т.е. когда содержимое элемента слишком велико, чтобы поместиться в его контекст форматирования блока - в обоих направлениях». - MDN Docs

Технически нас заботит только горизонтальное переполнение, так что это свойство overflow-x в CSS. Поставил overflow-x: hidden и вуаля, проблема решена… вроде. Достаточно хорошо, правда?

Вам нужно будет отключить переполнение в элементе <body>, потому что именно он вызывает горизонтальное переполнение. Другой элемент HTML, который создает полосы прокрутки, - это скромный <iframe>, который гораздо чаще задают overflow: hidden.

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

4) Используйте ширину: 100vi вместо ширины: 100vw.

Есть еще один набор единиц измерения CSS в стиле окна просмотра, который на самом деле ведет себя совсем не так, как vw и vh.

vi Равно 1% от размера начального« содержащего блока в направлении встроенной оси корневого элемента.

vb Равно 1% от размера начального содержащего блока в направлении оси блока корневого элемента. » - MDN Docs

Что это значит в аду святом? Боже, CSS уже достаточно запутал, не так ли? Я чувствую тебя. Эти новомодные длины зависят от того, написан ли язык по горизонтали или по вертикали.

«Размер блока: размер, перпендикулярный потоку текста в строке, т. Е. Размер по вертикали в режимах горизонтального письма и размер по горизонтали в режимах вертикального письма. Для стандартного английского текста это размер по вертикали.

Встроенный размер: размер, параллельный потоку текста в строке, т. е. горизонтальный размер в режимах горизонтального письма и вертикальный размер в режимах вертикального письма. Для стандартного английского текста это горизонтальный размер ». - MDN Docs

Вы правы, отметив, что практически все современные языки допускают горизонтальные сценарии. Тем не менее, на некоторых языках можно писать вертикально, в том числе на китайском, японском и корейском.

Если мы заменим vw эквивалентом vi на странице, написанной горизонтально (например, на английском языке), мы удалим горизонтальные полосы прокрутки. Контент будет во всю ширину без переполнения.

Это немного похоже на приманку и переключение, потому что vi основан на своем родительском контейнере, а не на области просмотра. Другими словами, width: 100vi это то же самое, что width: 100%, а не width: 100vw.

5) Нет вертикальных полос прокрутки, нет проблем (высота: 100 см)

Если вы создаете настоящее одностраничное приложение (SPA), которое должно занимать весь размер области просмотра, у вас может возникнуть соблазн сохранить width: 100vw.

В конце концов, имеет смысл использовать область просмотра, если вы создаете прогрессивное веб-приложение, предназначенное для установки на устройство.

Если вы также добавите height: 100vh, у вас никогда не должно быть вертикальных полос прокрутки. (Не забудьте изменить единицу измерения с vw для ширины на vh для высоты.) В этом случае HTML-код должен занимать всю область просмотра.

Это один из тех случаев, когда нам действительно нужно удалить эти встроенные поля. Добавление набора правил CSS * { margin: 0; } сработало для меня, хотя вы можете предпочесть что-нибудь более мощное для нормализации CSS. Tailwind CSS, например, использует собственный инструмент под названием предварительная проверка для установки стилей по умолчанию, улучшая при этом кроссбраузерность.

В качестве альтернативы вы можете комбинировать width: 100% и height: 100% вместо width: 100vw и height: 100vw. Однако поведение будет другим, поэтому обязательно протестируйте оба подхода. Вы можете использовать мой CodePen, указанный на следующем снимке экрана, чтобы попробовать его самостоятельно.

6) Установите максимальную ширину с max-width: 100%

Если width: 100vw слишком широкий, мы можем ограничить его с помощью свойства CSS max-width. В частности, если мы добавим max-width: 100% рядом с width: 100vw, у нас не будет горизонтальных полос прокрутки.

Это то же самое, что просто использовать width: 100%, но это также решение, которое имеет большой интуитивный смысл.

На скриншоте я сделал фон <body> желтым, чтобы вы могли видеть разницу по краю за пределами фиолетового <section>.

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

В своей работе по веб-разработке я обнаружил несколько случаев, когда max-width: 100% неправильно ограничивал width: 100vw и приводил к появлению горизонтальных полос прокрутки. Этого не должно происходить, то есть у меня, вероятно, был установлен width: 100vw в родительском контейнере, но я подумал, что должен упомянуть об этом.

7) Используйте фиксированную ширину с max-width: 100%

Что касается последнего примера, мы можем использовать свойство max-width независимо от того, как мы определили ширину. Например, у вас может быть элемент фиксированной ширины, размер которого вы хотите уменьшить на экране меньшего размера без создания горизонтальных полос прокрутки.

На самом деле это реалистичный пример, поскольку многие адаптивные дизайны сайтов используют максимальную ширину, которая изменяется в зависимости от размера экрана, с использованием так называемых медиа-запросов CSS. Например, вы можете отобразить столбец шириной 1024 пикселя на экране размером от 1024 до 1920 пикселей.

На скриншоте ниже я установил width: 3000px и max-width: 100%. Как и в последнем примере, результат таков, что мы эффективно используем width: 100%, несмотря на большую фиксированную ширину.

В этом примере котенок будет уменьшаться без горизонтальной полосы прокрутки на мобильных устройствах. Однако масштабирование векторного изображения SVG может быть непростым делом, особенно если вам нужна кроссбраузерная поддержка. К счастью, эксперт по SVG Амелия Беллами-Ройдс написала о масштабировании SVG для CSS-Tricks.

В обход: давайте поговорим о попутном ветре CSS и области просмотра

Поскольку я уже рассмотрел так много методов удаления этих надоедливых горизонтальных полос прокрутки из области просмотра, я хотел охватить общие решения с помощью моего любимого инструмента CSS, Tailwind CSS.

Почему попутный ветер фантастический? Это потому, что Tailwind на самом деле * дизайн-система, маскирующаяся под CSS-фреймворк. Однако, в отличие от Bootstrap и Material Design, вы на самом деле пишете CSS в Tailwind.

(* Хорошо, чтобы получить действительно техническую информацию, Bootstrap и Material Design - это библиотеки шаблонов, которые вы затем используете для создания своей собственной системы дизайна. Tailwind можно использовать для создания системы дизайна с нуля , или вы можете приобрести компоненты из библиотеки паттернов Tailwind, которая называется Tailwind UI. Вы можете назвать создателя страниц на основе Tailwind Tails библиотекой дизайна, но мы несем за голову.)

Что такого хорошего в попутном ветре? Лично мне нравится ремонтопригодность - мне никогда не нужно беспокоиться об удалении по ошибке критически важного CSS.

Ключом к популярности Tailwind является кропотливая система проектных токенов, лежащая в основе фреймворка. Тщательно подобранные ограничения системы дают разработчикам только правильные ограждения. Они делают очевидным, хороший или плохой выбор, предлагая лишь отдельные шаги .
- Макс Стойбер в своем блоге

Еще одним преимуществом является то, что Tailwind использует значения по умолчанию, которые имеют смысл для таких вещей, как border-radius, max-width, font-size и отзывчивый дизайн.

По умолчанию Tailwind включает пропорциональные значения, поэтому 16 - это вдвое больший интервал, чем, например, 8. - Зухайр Майзуб в UX Collective

Пропорция - это язык дизайна, поэтому Tailwind CSS выигрывает в этом отношении - вам не нужно делать никаких математических расчетов, чтобы иметь пропорциональную, адаптивную систему дизайна, которая будет работать при любом уровне масштабирования или размере экрана.

В любом случае, вам стоит попробовать Tailwind, если вы никогда не пробовали. Все три последних примера используют Tailwind CSS. Моя любимая причина использовать Tailwind - это на самом деле намного проще набрать max-w-full, чем max-width: 100%.

Можете называть меня новичком, но мне в миллион раз проще склеить несколько классов Tailwind, чем писать классы CSS в соответствии с моделью блочных элементов (БЭМ) ». Итак, вот несколько решений Tailwind!

8) Tailwind CSS: используйте w-Full вместо w-Screen

Давайте вспомним первый пример с попутным ветром. На этот раз w-full (width: 100%) заменит w-screen (width: 100vw).

Как и раньше, здесь следует помнить, что вы хотите w-full во всех родительских контейнерах, поскольку w-screen будет вызывать горизонтальные полосы прокрутки.

Давайте быстро взглянем на код, чтобы увидеть, как Tailwind CSS для этого примера выглядит внутри макета HTML.

Конечно, мы обсуждаем только использование w-full, но я считаю, что этот код намного легче понять, чем соответствующий CSS.

Если вам интересно, я использую Tailwind CSS через CDN (сеть доставки контента), что определенно не так, как вам следует использовать. К вашему сведению.

9) Попутный ветер CSS: используйте фиксированный для привязки контента

Как мы подробно рассмотрели ранее, блочная модель CSS означает, что добавление position: fixed позволит вам использовать 100vw без переполнения.

В терминологии попутного ветра это означает, что мы объединяем fixed (для position) с w-screen для ширины 100vw.

Такое использование fixed может пригодиться, потому что обычно 100vw используется для создания баннера cookie вверху или внизу страницы.

Пока мы говорим о попутном ветре, я получаю массу пользы от двух расширений VS Code: Headwind (для сортировки) и Tailwind CSS IntelliSense.

10) Попутный ветер CSS: Скрыть полосы прокрутки overflow-x-hidden

Когда вы создаете настоящее одностраничное приложение с React и множеством SCREAMING_SNAKE_CASE, вы всегда можете скрыть полосы прокрутки.

Мы будем использовать утилиту overflow-x-hidden в Tailwind CSS, чтобы скрыть горизонтальные полосы прокрутки из поля зрения.

Конечно, здесь могут возникнуть проблемы с доступностью и визуальной согласованностью - обратите внимание, как граница выше исчезает за пределами экрана.

Вам действительно нужно убедиться, что ваше одностраничное приложение не становится недоступным, если вы скрываете переполнение.

Я бы порекомендовал протестировать различные уровни масштабирования и размеры шрифта, если вы настаиваете на сочетании 100vw с 100vh. Береженого Бог бережет.

Вывод: используйте 100% ширину на своих сайтах и ​​в приложениях

Должен заметить, что когда вы экспериментируете с CodePen, некоторые результаты могут быть странными. Иногда CSS, примененный через <iframe>, не вел себя так, как я ожидал.

Но на самом деле это CSS для вас, не так ли?

В основном эта статья должна служить напоминанием о том, что вам следует тестировать свою веб-разработку на мобильных устройствах и с различными уровнями масштабирования.

Мне также нравится запускать в браузере Большой размер шрифта на рабочем столе, чтобы уловить миллионы визуальных несоответствий, которые могут вызвать.

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

Удачного кодирования!

Дальнейшее чтение