Ширина окна браузера без полосы прокрутки css
Как узнать ширину и высоту окна браузера? Как получить полную ширину и высоту документа, включая прокрученную часть? Как прокрутить страницу с помощью JavaScript?
Для большинства таких запросов мы можем использовать корневой элемент документа document.documentElement , который соответствует тегу <html> . Однако есть дополнительные методы и особенности, которые необходимо учитывать.
Ширина/высота окна
Чтобы получить ширину/высоту окна, можно взять свойства clientWidth/clientHeight из document.documentElement :
Например, эта кнопка показывает высоту вашего окна:
Браузеры также поддерживают свойства window.innerWidth/innerHeight . Вроде бы, похоже на то, что нам нужно. Почему же не использовать их?
Если есть полоса прокрутки, и она занимает какое-то место, то свойства clientWidth/clientHeight указывают на ширину/высоту документа без неё (за её вычетом). Иными словами, они возвращают высоту/ширину видимой части документа, доступной для содержимого.
А window.innerWidth/innerHeight включают в себя полосу прокрутки.
Если полоса прокрутки занимает некоторое место, то эти две строки выведут разные значения:
В большинстве случаев нам нужна доступная ширина окна: для рисования или позиционирования. Полоса прокрутки «отъедает» её часть. Поэтому следует использовать documentElement.clientHeight/Width .
Обратите внимание, что геометрические свойства верхнего уровня могут работать немного иначе, если в HTML нет <!DOCTYPE HTML> . Возможны странности.
В современном HTML мы всегда должны указывать DOCTYPE .
Ширина/высота документа
Теоретически, т.к. корневым элементом документа является documentElement , и он включает в себя всё содержимое, мы можем получить полный размер документа как documentElement.scrollWidth/scrollHeight .
Но именно на этом элементе, для страницы в целом, эти свойства работают не так, как предполагается. В Chrome/Safari/Opera, если нет прокрутки, то documentElement.scrollHeight может быть даже меньше, чем documentElement.clientHeight ! С точки зрения элемента это невозможная ситуация.
Чтобы надёжно получить полную высоту документа, нам следует взять максимальное из этих свойств:
Почему? Лучше не спрашивайте. Эти несоответствия идут с древних времён. Глубокой логики здесь нет.
Получение текущей прокрутки
Обычные элементы хранят текущее состояние прокрутки в elem.scrollLeft/scrollTop .
Что же со страницей? В большинстве браузеров мы можем обратиться к documentElement.scrollLeft/Top , за исключением основанных на старом WebKit (Safari), где есть ошибка (5991), и там нужно использовать document.body вместо document.documentElement .
К счастью, нам совсем не обязательно запоминать эти особенности, потому что текущую прокрутку можно прочитать из свойств window.pageXOffset/pageYOffset :
Эти свойства доступны только для чтения.
Прокрутка: scrollTo, scrollBy, scrollIntoView
Для прокрутки страницы из JavaScript её DOM должен быть полностью построен.
Например, если мы попытаемся прокрутить страницу из скрипта в <head> , это не сработает.
Обычные элементы можно прокручивать, изменяя scrollTop/scrollLeft .
Мы можем сделать то же самое для страницы в целом, используя document.documentElement.scrollTop/Left (кроме основанных на старом WebKit (Safari), где, как сказано выше, document.body.scrollTop/Left ).
Есть и другие способы, в которых подобных несовместимостей нет: специальные методы window.scrollBy(x,y) и window.scrollTo(pageX,pageY) .
Метод scrollBy(x,y) прокручивает страницу относительно её текущего положения. Например, scrollBy(0,10) прокручивает страницу на 10px вниз.
Кнопка ниже демонстрирует это:
Метод scrollTo(pageX,pageY) прокручивает страницу на абсолютные координаты (pageX,pageY) . То есть, чтобы левый-верхний угол видимой части страницы имел данные координаты относительно левого верхнего угла документа. Это всё равно, что поставить scrollLeft/scrollTop . Для прокрутки в самое начало мы можем использовать scrollTo(0,0) .
Эти методы одинаково работают для всех браузеров.
scrollIntoView
Для полноты картины давайте рассмотрим ещё один метод: elem.scrollIntoView(top).
Вызов elem.scrollIntoView(top) прокручивает страницу, чтобы elem оказался вверху. У него есть один аргумент:
- если top=true (по умолчанию), то страница будет прокручена, чтобы elem появился в верхней части окна. Верхний край элемента совмещён с верхней частью окна.
- если top=false , то страница будет прокручена, чтобы elem появился внизу. Нижний край элемента будет совмещён с нижним краем окна.
Кнопка ниже прокрутит страницу так, что она сама окажется вверху:
А следующая кнопка прокрутит страницу так, что она сама окажется внизу
Запретить прокрутку
Иногда нам нужно сделать документ «непрокручиваемым». Например, при показе большого диалогового окна над документом – чтобы посетитель мог прокручивать это окно, но не документ.
Чтобы запретить прокрутку страницы, достаточно установить document.body.style.overflow = "hidden" .
Первая кнопка останавливает прокрутку, вторая возобновляет её.
Аналогичным образом мы можем «заморозить» прокрутку для других элементов, а не только для document.body .
Недостатком этого способа является то, что сама полоса прокрутки исчезает. Если она занимала некоторую ширину, то теперь эта ширина освободится, и содержимое страницы расширится, текст «прыгнет», заняв освободившееся место.
Знаю, что у многих появится вопрос о том, почему у этой статьи такой необычный заголовок. Как связаны «отзывчивый веб-дизайн» и «высота окна браузера»? Пожалуй, этот заголовок кажется необычным из-за того, что под «отзывчивым дизайном», как правило, понимают проектирование страниц таким образом, чтобы они подстраивались бы под ширину области просмотра, чтобы они хорошо бы выглядели на разных устройствах. Сайты всегда тестируют, уменьшая ширину браузера и наблюдая за происходящим. Но я практически никогда не сталкивался с некими указаниями по тестированию какого-то проекта, в которых сказано, что страницы исследуют путём уменьшения высоты окна браузера. Возможно, вы когда-нибудь ловили себя на такой мысли: «Надо ли проверять страницы в окнах браузера разной высоты?». Я полагаю, что делать это надо, и собираюсь убедить в этом всех, кто прочитает эту статью.
При работе над веб-сайтом не очень правильно делать некие предположения, не опираясь на реальные данные. Поэтому очень важно брать на себя ответственность по проверке сайтов в окнах браузеров разной ширины и разной высоты.
Зачем проверять страницы в окнах браузеров разной высоты?
Хороший вопрос. Прежде чем переходить к примерам и к сценариям использования таких проверок, мне хотелось бы рассказать о проблемах, которые случаются с сайтами, не приспособленными к работе в областях просмотра разной высоты. Это поможет вам лучше понять то, о чём речь пойдёт дальше.
Неправильные предположения о том, как будут пользоваться сайтом, — это один из важнейших факторов, негативно влияющих на работу веб-дизайнера. Например, неправильно будет рассчитывать на то, что сайтом будут пользоваться, разворачивая браузер на весь экран. Вместо этого нужно рассчитывать на худшее.
Предположения и реальность
Выше приведена иллюстрация моих слов. В реальности далеко не все пользователи работают с браузерами так, как предполагает дизайнер. Я сам сталкивался с сайтами, которые плохо выглядели в окнах браузеров уменьшенной высоты.
Инструменты разработчика браузера
Изменение размеров браузера по вертикали — это не единственный способ воздействия на высоту области просмотра. Так, например, когда открывают панель инструментов разработчика, она тоже отнимает часть вертикального пространства.
Панель инструментов разработчика занимает часть окна браузера
Открытие инструментов разработчика может «поломать» дизайн сайта или пролить свет на проблемы, возможность появления которых никто не ожидал. Выделенная область рисунка представляет текущую высоту области просмотра. Если открыть инструменты разработчика, просматривая сайт на маленьком экране ноутбука, это приведёт к тому, что видимой окажется лишь небольшая область страницы.
Подумаем над одним важным вопросом: «Можно ли улучшить впечатления пользователя от работы с сайтом в то время, когда его просматривают в окне браузера небольшой высоты?». Я могу дать положительный ответ на этот вопрос. Полагаю, теории нам хватит. Давайте учиться «вертикальному» подходу к стилизации страниц.
«Вертикальный» CSS
Некоторые дизайнеры и разработчики уделяют основное внимание внешнему виду страницы, который она принимает в окнах разной ширины. При этом они отодвигают на второй план исследование поведения страницы в окнах разной высоты. А это — очень важно. Например, некто работает над дизайном страницы и ему дали инструкции относительно того, как некий компонент должен выглядеть в окнах браузера разной ширины. А как насчёт окон разной высоты?
На большом телефоне навигационные элементы заполняют доступное вертикальное пространство. На телефоне среднего размера уменьшается размер шрифта и расстояние между элементами. На маленьком телефоне вертикального пространства недостаточно для вывода всех элементов. Поэтому они размещаются в 2 колонки.
На этом рисунке показано навигационное меню, внешний вид которого подстраивается под высоту области просмотра. Цель дизайнера заключается в том, чтобы меню заполнило бы всё доступное ему пространство. На небольших экранах уменьшается размер шрифта и расстояние между элементами меню. Если же экран телефона совсем мал (например, как у iPhone 5), элементы выводятся в двух колонках. Подобные сценарии использования сайтов часто упускают из виду. В результате сайты или совсем не приспосабливают к работе на экранах разной высоты, или оптимизируют их лишь тогда, когда какой-нибудь посетитель сайта сообщит о проблеме.
В деле подстройки сайта под области просмотра разной высоты нам может помочь CSS. А именно, речь идёт о двух основных техниках:
- Медиазапросы, учитывающие высоту области просмотра.
- Единицы измерения, имеющие отношение к области просмотра.
Медиазапросы, учитывающие высоту области просмотра
Как вы, наверняка, уже знаете, в CSS можно использовать медиазапросы, учитывающие ширину области просмотра:
А вот медиазапросы, учитывающие высоту окон браузеров, используются гораздо реже:
Единицы измерения, имеющие отношение к области просмотра
Использование единиц измерения, имеющих отношение к размерам области просмотра, может помочь в деле улучшения впечатлений пользователей от работы с сайтами. Например, с учётом высоты области просмотра можно регулировать расстояние между элементами по вертикали.
Чем выше окно браузера — тем больше расстояние между элементами
Всё это может показаться приятной мелочью, ни на что особо не влияющей, но лишь до тех пор, пока не взглянуть на подобную страницу на большом мониторе — вроде 27-дюймового дисплея iMac. Тогда окажется, что высота области просмотра слишком велика. Но у нас, к счастью, есть способ ограничить размеры margin-bottom . Сделать это можно, например, следующими способами:
- С помощью медиазапросов.
- С использованием CSS-функций сравнения.
Второй способ заключается в использовании CSS-функции clamp() . При подборе значений, передаваемых этой функции, мы, в данном случае, задаём минимальный размер отступа, равный 10px , максимальный — 50px , а значения, находящиеся между этими двумя, зависят от размеров окна браузера.
Если вам эта тема интересна — взгляните на мои статьи о единицах измерения, зависящих от размеров области просмотра страницы и о CSS-функциях.
Ниже мы поговорим о различных способах использования «вертикальных» медиазапросов.
Примеры и сценарии
▍Элементы страниц, накладывающиеся друг на друга при изменении высоты окна браузера
В этом примере рассматривается страница, в верхнем разделе которой имеется заголовок и иллюстрация. Высота этой части страницы составляет 100vh , что равносильно 100% высоты области просмотра.
Верхняя часть страницы высотой 100vh
Выглядит всё это очень хорошо, но лишь до тех пор, пока не уменьшится высота окна браузера. Высоты верхней части страницы не хватит для того чтобы вместить иллюстрацию и текст. В результате элементы верхней части страницы перекроют содержимое других её разделов.
Уменьшение высоты окна браузера «ломает» дизайн
Обратите внимание на то, как изображения накладываются на раздел страницы, расположенный под её верхней частью. Происходит это из-за того, что им не хватает места. Взглянем на код к этому примеру.
Рассмотрим несколько вариантов решения подобных проблем:
- Можно задать изображению фиксированные размеры (свойства width и height ), а не только его ширину ( width ). Отсутствие свойства height — это одна из причин нашей проблемы.
- Можно применять к верхнему разделу страницы свойство height: 100vh только в том случае, если высота области просмотра больше 700px (понятно, что конкретные значения, используемые в медиазапросе, будут зависеть от каждой конкретной ситуации).
Итак, мы решили, что «вертикальные» медиазапросы — это стабильный и полезный механизм. Но использование значения 100vh — дело рискованное, так как, если даже можно ограничить размеры изображения, может случиться так, что размеры текста ограничить не получится. Например, если текст в верхнем разделе страницы окажется длиннее, то мы столкнёмся с новым вариантом уже знакомой нам проблемы.
Текст перекрывает раздел сайта, в котором его быть не должно
Для исправления этой проблемы можно, вместо свойства height , использовать свойство min-height . При таком подходе, в том случае, если содержимое раздела окажется больше, чем он способен вместить, его размеры увеличатся и его содержимое не перекроет следующий раздел.
▍Фиксированный заголовок страницы
Нет ничего плохого в том, чтобы заголовок страницы оставался бы на одном месте при её прокрутке. Но нужно сделать так, чтобы этот заголовок имел бы фиксированную позицию только в том случае, если на экране достаточно вертикального пространства.
Фиксированный заголовок страницы
Тут показан сайт, который просматривают в ландшафтном режиме. Обратите внимание на то, что заголовок занимает слишком много вертикального пространства. Важно ли это для пользователя? В большинстве случаев — нет. Но улучшить ощущения пользователя от работы с сайтом можно, прибегнув к следующему медиазапросу:
При таком подходе в ландшафтном режиме заголовок фиксироваться не будет.
▍Скрытие элементов, которые менее важны, чем другие
Я заметил это в навигационном меню Twitter. А именно, речь идёт о комбинации «вертикальных» медиазапросов и паттерна Priority+.
Выделенные элементы будут скрыты в том случае, если им не хватит места
Когда меняется высота области просмотра, менее важные элементы (пункты меню Bookmarks и Lists ) становятся подпунктами пункта More . Это — хороший пример использования «вертикальных» медиазапросов.
А вот — мой твит, в котором анализируется применение этого подхода в Twitter.
▍Навигационные элементы и изменение высоты области просмотра
Следующий пример связан с предыдущим. Имеется вертикальная навигационная панель (боковая панель, сайдбар). Если высота области просмотра невелика — можно немного уменьшить вертикальное расстояние между навигационными элементами, что слегка улучшит внешний вид страницы.
Расстояние между элементами и высота области просмотра
Вот стили к этому примеру:
А тут можно посмотреть видео к нему.
Кроме того, можно отметить, что в подобной ситуации модификации можно подвергнуть и размер шрифта, что, при уменьшении высоты окна браузера, даст ещё больше места для элементов.
▍Верхний раздел страницы и высота области просмотра
Верхнему разделу страницы нужно некоторое свободное вертикальное пространство, дающее ему немного «воздуха». Размеры этого пространства могут зависеть от высоты области просмотра.
Чем выше страница — тем больше «воздуха».
Так выглядят стили к этому примеру:
▍Модальные компоненты
Как вы, возможно, уже знаете, от модальных компонентов ожидается, как минимум, горизонтальное выравнивание по центру. Но может понадобиться выровнять подобный элемент и по вертикали. Это возможно, но приводит к неприятностям при изменении объёмов данных, выводимых такими элементами.
Если модальный элемент содержит правильный объём данных, то выглядит он, как показано ниже, очень хорошо.
Правильный модальный элемент
Вот стили для этого элемента:
А вот если в таком же элементе нужно будет вывести больше текста — всё уже будет далеко не так хорошо. А именно, элемент заполнит экран по вертикали и пользователь не сможет прокручивать его содержимое.
Слишком высокий модальный элемент
Эта проблема возникает по следующим причинам:
- У модального элемента не задана высота.
- Элемент центрован по вертикали (это ускорит появление проблемы).
Обратите внимание на то, что тут использованы свойства min-height и min-width . Первое нужно для того чтобы элемент выглядел бы хорошо даже в тех случаях, когда он выводит короткий текст. А второе позволяет ограничить его высоту заданным значением вместо того, чтобы задавать ему неизменную высоту.
Модальный элемент, подходящий для вывода длинных текстов
Итоги
Проектируя сайты с учётом тех впечатлений, которые вызовет работа с ними у пользователей, лучше всего строить их дизайн, опираясь на ширину и высоту окна браузера. Может, кому-то покажется странным тестирование страниц в окнах разной высоты, но такое тестирование себя оправдывает. Здесь я рассказал о важности «вертикального» подхода к дизайну сайтов, о том, как проектировать страницы в расчёте на их правильный вывод в областях просмотра разной высоты, рассмотрел примеры. Надеюсь, вам всё это пригодится.
Обращаете ли вы внимание на то, как создаваемые вами веб-страницы выглядят в окнах браузера разной высоты?
У меня есть элемент и нужна его ширина без(!) вертикальная полоса прокрутки.
Firebug говорит мне, что ширина тела составляет 1280px.
любой из них отлично работает в Firefox:
они все вернутся 1263px, который является значением, которое я ищу.
однако все остальные браузеры дают мне 1280 пикселей.
есть ли кросс-браузер способ получить полноэкранную ширину без(!) вертикальная полоса прокрутки?
.prop("clientWidth") и .prop("scrollWidth")
in JavaScript:
P. S: обратите внимание, что использовать scrollWidth надежно ваш элемент не должен переполняться по горизонтали
демо jsBin
вы также можете использовать .innerWidth() эта будет работать только на body элемент
вы можете использовать ванильный javascript, просто написав:
вы также можете использовать это, чтобы получить ширину документа следующим образом:
источник: MDN
вы также можете получить ширину окна, включая полосы прокрутки, как показано ниже:
однако это не поддерживается всеми браузерами, так что в качестве запасного варианта, вы можете использовать docWidth как указано выше, и добавить на скроллбара ширина.
источник: MDN
вот несколько примеров, которые предполагают $element это jQuery элемент:
попробуйте это :
вы можете получить ширину экрана с помощью и без полосы прокрутки с помощью этого кода. Здесь я изменил значение переполнения body и получить ширину С и без полосы прокрутки.
самое безопасное место для получения правильной ширины и высоты без полос прокрутки-это элемент HTML. Попробуйте это:
поддержка браузера довольно приличная, с IE 9 и выше поддерживает это. Для старого IE используйте один из многих резервных вариантов, упомянутых здесь.
Я испытал подобную проблему и делает width:100%; решил это за меня. Я пришел к этому решению после того, как попробовал ответить на этот вопрос и понял, что сама природа <iframe> сделает эти инструменты измерения javascript неточными без использования какой-либо сложной функции. Выполнение 100% - это простой способ позаботиться об этом в iframe. Я не знаю о вашей проблеме, так как я не уверен, какие элементы HTML вы манипулируете.
С нуля напишем простой, но полезный вспомогательный плагин для отображения корректных размеров окна браузера с учетом и без учета полос прокрутки.
Подключил плагин к этой статье, справа внизу отображается результат работы плагина
Опубликовал репозиторий на GitHub
Если не знакомы с GitHub, можно почитать отдельную статью - Установка GitHub Desktop и его базовое использование
Зачем писать этот плагин?
Зачем писать данный плагин, если существуют расширения для браузеров с аналогичным функционалом и для чего он вообще нужен?
Во-первых, это хорошая практика по JavaScript - писать простые, но полезные для себя инструменты
Во-вторых, в некоторых браузерах, особенно в мобильных, нет возможности устанавливать расширения
В-третьих, мы напишем плагин, который можем настроить под свои требования как функционально, так и визуально
Этот плагин будет помогать при разработке и тестировании адаптивной верстки
При адаптивной верстке необходимо постоянно следить за размерами окна браузера в зависимости от контрольных точек @media запросов
Если только изучаете адаптивную верстку, возникают проблемы с пониманием размеров окна браузера, в частности ситуация, когда появляется полоса прокрутки (scrollbar).
Полоса прокрутки бывает невидимой, как на мобильных устройствах - она никак не влияет на контент. Но в браузерах на компьютере или ноутбуке полоса прокрутки занимает часть окна. Это нужно учитывать при адаптивной вёрстке
@media запросы основаны на полной ширине окна браузера, включая полосы прокрутки.
@media запрос @media (max-width: 1199.98px) взят из Bootstrap. В примере выше, если ширина меньше 1200px, то .container меняет цвет фона на синий
@media запрос срабатывает на полную ширину окна, и пока нет полос прокрутки ширина окна и ширина контента совпадают
Но такое на практике встречается редко. Обычно контентная часть намного больше. Для примера просто назначим высоту .content больше, чем высота окна браузера
Теперь появилась полоса прокрутки. @media запрос сработает как и раньше при полной ширине окна браузера, включая ширину полосы прокрутки, но теперь полоса прокрутки отнимает место у контентной части. При полной ширине окна 1200px, контенту остается около 1183px.
Предположим, в шапке макета много элементов, которые мы хотим при адаптивной верстке плотно уместить в 1200px. Ставим @media (max-width: 1199.98px) , настраиваем ширину браузера на 1200px, но элементы не умещаются из-за того, что полоса прокрутки отняла часть ширины, что на первый взгляд не совсем очевидно
Плагин, который мы напишем, будет отображать полные размеры окна браузера включая размеры полос прокрутки, а также размеры контентной части, без учета размеров полос прокрутки
Подробнее про адаптивную верстку будет отдельная статья
Создаем файл плагина и подключаем
Создадим файл wSizes.js в папке с проектом и сразу подключим его в HTML файле перед закрывающим тегом </body>
После разработки и тестирования адаптивной верстки отключаем и удаляем плагин из проекта
Пишем JavaScript код
В результате, созданный файл wSizes.js будет содержать следующий код (ниже рассмотрим код чуть подробнее)
Код с комментариями
Рассмотрим код пошагово
Перед запуском плагина необходимо убедиться, что страница полностью загружена, включая ресурсы, такие как изображения, стили и тд
Объявляем основную функцию wSizes и вызываем ее, чтобы сразу видеть результат
Создаем элемент meta, который будет предотвращать масштабирование на мобильных устройствах для корректной работы плагина. Устанавливаем ему необходимые атрибуты. Вставляем его перед закрывающим тегом </head>
Создаем элемент wSize, который будет отвечать за отображение размеров. Добавляем ему класс w-size. Назначаем инлайн стили и вставляем элемент перед закрывающим тегом </body>
Далее создаем функцию wResize, которая будет добавлять в элемент wSize замеряемые значения. Вызываем созданную функцию при загрузке страницы и при изменении размеров окна браузера.
Window Width - полная ширина окна, включая ширину полосы прокрутки
Window Height - полная высота окна, включая высоту полосы прокрутки
Content Width - ширина отображаемого контента, не включая ширину полосы прокрутки
Content Height - высота отображаемого контента, не включая высоту полосы прокрутки
Итоги
В данной статье мы написали простой, но полезный плагин отображения размеров окна для разработки и тестирования адаптивной верстки, который будет работать и на мобильных устройствах
Посмотрели как создать элемент через JavaScript, добавить ему класс, стили, контент и динамически вставить его в документ.
При желании плагин можно визуально настроить под себя и добавить ему дополнительную функциональность
Читайте также: