Как изменить масштаб в браузере js
В решении многих задач может понадобиться определить положение, размер окна браузера, или каких-нибудь определенных элементов документа. В этой записи будут перечислены все способы определения этих значений.
Разрешение экрана
Для определения ширины и высоты экрана пользователя используются свойства width и height объекта window.screen . Эти свойства доступны во всех браузерах.
Положение окна браузера
Мнения разработчиков в вопросе какое же свойство должно хранить положение окна относительно верхней левой точки экрана, видимо, разошлись.
В итоге мы получили две пары свойств: window.screenY , window.screenX и window.screenTop , window.screenLeft .
Первые два работают в браузерах Mozilla (например Firefox), вторая пара работает в Internet Explorer и Opera. В браузерах, основанных на движке WebKit (например Safari, Chrome), обе пары работают и их значения равны друг другу соответственно.
Но невозможно абсолютно кросс-браузерно определить положение окна, поскольку в разных браузерах отсчет идет до разных точек. Дело в том, что браузеры Internet Explorer и Opera в значениях screenTop и screenLeft хранят координаты левого верхнего угла документа, а не всего окна, поэтому даже при развертывании на весь экран их значения будут не нулевые.
Напротив, остальные браузеры начинают отсчет от верхней левой точки самого окна, как и ожидается для этих свойств. Стоит отметить, что в Firefox, при развертывании окна на весь экран, значения screenY и screenX могут быть отрицательными.
Странно, но в Opera значения screenY и screenX не undefined , однако я не могу понять, что они значат. При любых перемещениях окна эти значения не меняются и все время отрицательны. Если это не очередной глюк Opera, и я что-то упустил, отпишите, пожалуйста, в комментариях.
Положение окна браузера можно изменить двумя методами:
Размеры окна браузера
Под размерами окна браузера подразумеваются как размер всего окна целиком (вместе с хромом и панелями), так и размер видимой части документа (вьюпорт), или другими словами, размер окна браузера без панелей и хрома.
К сожалению, с получением этих значений больше проблем, чем может показаться на первый взгляд.
Для получения размеров окна браузера целиком во всех браузерах, кроме Internet Explorer, вы можете использовать свойства window.outerWidth и window.outerHeight . И, насколько я понимаю, аналогов для Internet Explorer не существует.
С размерами вьюпорта тоже существуют проблемы. Дело в том, что в зависимости от браузера и типа документа значения будут разные, в частности - не всегда ясно, будет ли размер скроллбара учитываться, или нет.
Во всех браузерах, кроме Internet Explorer, вы можете получить размер вьюпорта с помощью свойств window.innerWidth и window.innerHeight . Эти свойства всегда будут включать ширину, или высоту скроллбара, что в некоторых задачах неуместно.
Другим способом определения размеров вьюпорта могут служить свойства clientWidth и clientHeight объекта document.documentElement , или, другими словами, элемента html текущего документа.
Но это справедливо только для режима следования стандартам (CSS1Compat mode), поэтому приведенный выше код работает верно в этом документе.
Но если у страницы не будет указан doctype, то в некоторых браузерах свойства clientWidth и clientHeight объекта document.documentElement будут иметь значения ширины и высоты всего документа целиком, а не только видимой его части, в то время как document.body.clientWidth и document.body.clientHeight наоборот будут иметь значения размеров вьюпорта.
И учитывая то, что нет возможности узнать, что является размерами вьюпорта - свойства document.documentElement или document.body (поскольку они оба существуют, но смысл значений может быть разный), то получается, что кросс-браузерное определение размеров вьюпорта этим способом - невозможно, если документ отображается не в режиме следования стандартам.
Размеры окна браузера можно изменить двумя методами:
Скролл окна браузера
Сколлбар имеет несколько параметров: ширина, высота, значение прокрутки сверху, значение прокрутки слева.
Первые два параметра определяются свойствами scrollWidth и scrollHeight объекта document.documentElement . Это, опять же, справедливо только для режима следования стандартам.
Значения ширины и высоты прокрутки окна - количество пикселей, которые могут быть прокручены скроллом. Другими словами - прямоугольник, образованный всеми видимыми элементами документа.
Примечание на счет элементов я сделал не просто так: если какой-нибудь абсолютно позиционированный элемент будет "вылезать" за пределы body , то он "растянет" ширину/высоту скролла, но размеры document.body останутся прежними. Напротив, если размеры документа меньше, чем размеры вьюпорта - то значения scrollWidth и scrollHeight будут равны размерам документа, а не всего окна.
Стоит отметить, что как и в случае с размерами вьюпорта, в режиме "quirks mode" не всегда понятно, свойства какого элемента ( documentElement или body ) будут иметь нужные нам значения скролла.
Для того, чтобы определить на сколько пикселей прокручен документ, нужно обратиться к свойствам scrollTop и scrollLeft объекта document.documentElement , если браузер в режиме следования стандартам, или document.body , если браузер в режиме "quirks mode".
В браузерах на движке Mozilla (Firefox) или WebKit (chrome, safari) вы можете воспользоваться свойствами window.scrollY и window.scrollX для определения этих значений. Они будут равны scrollTop и scrollLeft соответственно.
Из скрипта вы можете управлять прокруткой страницы, пользуясь следующими методами (обратите внимание на очередность параметров):
Размеры документа и элементов
Одна из самых часто встречаемых задач - определение размера элемента.
Дело в том, что не всегда достаточно узнать какие значения размеров были установлены через стили элемента и особенно это касается "резиновых" элементов (которые растягиваются в зависимости от размеров их содержания), или элементов с фиксированными размерами, но имеющих внутренние отступы.
Во всех браузерах, независимо от режима, вы можете получить размер элемента с помощью свойств offsetWidth и offsetHeight .
Для демонстрации, небольшой пример:
Точно так же можно определить размер всего документа, точнее размеры элемента body :
Положение элемента на странице
Одна из самых распространенных задач - определение абсолютной позиции элемента относительно левого верхнего угла документа.
Для определения позиции используются следующие свойства элемента:
offsetTop - отступ сверху, измеряется в пикселах относительно родительского элемента.
offsetLeft - отступ слева, измеряется в пикселах относительно родительского элемента.
offsetParent - ближайший родитель, относительно которого делается отсчет. Его значение будет null если текущий элемент невидим ( display: none ) или это корневой элемент документа.
Поскольку значение считается от ближайшего родителя, то абсолютная позиция относительно верхнего левого угла документа обычно считается в цикле, который завершается тогда, когда значение offsetParent будет равно null .
Обычно, функция по определению абсолютной позиции выглядит следующим образом:
Таким способом можно считать позицию как статичных элементов ( position: static ), так и элементов с абсолютной позицией ( position: absolute ).
Заключение
Надеюсь, что данная запись поможет вам лучше разобраться в измерениях документа и его элементов. Буду рад услышать замечания или вопросы в комментариях.
Ожидал увидеть еще способ кросс-браузерного получения координат мыши
Взяв реализацию из jQuery и немного переделав её, получил:
Сам не разбирался еще, что происходит в этом большом выражении, возможно получится упростить
Много полезного, как раз то, что искал. Совсем не то, что ковыряться в Prototype, jQuery или Dojo. Спасибо!
Должен отметить, что функция получения координат элемента относительно верхнего левого угла документа даст неверный результат в IE6, если в цепочке offsetParent попадется элемент с position: relative.
Афтор зачод! Наитолковые статьи в рунете по ЯС! Сразу видно берется за дело с головой. Пишы исчо! Где я только не рылся за этим материалом а оно вот он чо! всё тут и на блюдечге!!
// З.Ы. Илья - ф основную книгу эту статью ИМХО этот каждому пригодится, а в этих блогах фиг нашол, ещё повезло что наткнулся =)
автор пишы исчо это точно:) спс за размеры окна браузера
На основе некоторых идей этой статьи создан основной материал сайта.
Спасибо за статью, Андрей!
Спасибо, всегда путаю, что x (икс) это "left" в переносе на слова.
Классная статья, спасибо!
Но подскажите, как эти полезные свойства применить собственно к элементам страницы: к примеру чтоб таблица, структурирующая GUI, масштабировалась относительно размеров видимой обл-ти? К ее атрибутам не применимы свойства :
Как узнать ширину и высоту элемента div до его отображения, это реально? Заранее спасибо
Для body везде получились различные значения высоты.
В качестве попытки кроссброузерного определения положения и размеры окна, можно попробовать его пробно подвигать и поизменять размеры. В этом случае сразу выяснится что учитывается для возвращаемых значений.
А что вы думаете по поводу такого кроссбраузерного определения размера вьюпорта:
в IE7 не сработал, выдал 0
Я понял. Для IE надо math.max получать. Спасибо
Работает корректно во всех браузерах!
Определяет размер рабочей области окна!
+ размер области документа (с учетом дивов с абсолютным позициониррованием)
+ работает и в ИЕ6 и в Сафари
Ой, чуть не забыл пояснить.
функция возвращает:
ww - window width
wh - window height
dw - document width
dh - document height
wsl - window scroll left
wst - window scroll top
Снова я, уж простите, доработанная функция:
Норм, хотя когда футер прижат надо под ie8 как минимум перерасчитывать все.
Надеюсь кому то помог! Потому как сам перерыл огромную кучу информации пока соорудил это.
Спасибо, но для тех, кто не подключал jQuery эту часть кода
надо заменить на
Спасибо. Долго искал эту информацию и нашел.
А я уже давно забил на попытки сооружать мегауниверсальные функции. Я следую таким правилам:
- верстаю в xhtml со следующим шаблоном пустого дока:
- если страница верстается php, то конечно же в нем шлется заголовок
- если что-то пошло не так, значит накосячил в html-коде и он уже в квирк-моде, открываю в Опере, жму "Соблюдены ли web-стандарты" и добиваюсь успешной проверки на W3C-валидаторе. По-ходу, практически не встречаю в инете страниц, проходящих валидацию. Эта страничка например тоже не проходит - куча досадных ошибок типа не указан тип скрипта, блок стилей вставлен там где нельзя, спаны закрываются, но не открывались перед этим, id дублирующиеся и т.д. Очень распространен подход, когда в js пишут что-то типа
(На этой странице такое есть) Ну а слеш в закрывающем теге кто экранировать будет!? Зачем делить слово SCRIPT на две части, если тут же ошибка потяжелее?
проходит валидацию, ессесно работает и ничего не нужно делить. Нужно просто не забыть указать тип скрипта, вставить в нем коменты-ограничители для XML-парсера и экранировать символы / и ' в строках.
А когда половина страниц валидируются, другие в квирке рисуются, то конечно начинается каша, геморой, бессонные ночи и т.д.
Итак, начинать следует со стандартизации своих проектов и исправления в них ошибок перед каждым релизом (мы ж не роботы, конечно забываем временами и коменты вставлять и < br >вместо < br />на скорую руку пишем) - отправка страницы прямо из браузера на W3C всегда под рукой.
Ну а когда валидация пройдена, то и гемороя меньше. Конечно если речь не идет о совсем старых браузерах, на которые я могу забить. Кто не может, тому мои искренние сожаления и моральная поддержка в тяжбах.
А так, провел небольшой тест на Опера 10.60 (пачка пердыдущих версий скорей всего то же выдаст), IE8 и FF 3.6.6. Создал корректную страницу с длинной таблицей на 100 строк, каждая строка имеет паддинг, прописанный в CSS, что в IE и в Фоксе приводит к увеличению высоты html (т.е. html становится длиннее body), аналогично и при div-верстке, т.е. лично таблицы тут ни при чем. Такая же фича наблюдается и в Опере ИНОГДА. Возможно в квирке - не проследил. В тестовом примере в Опере html не удлинился и не испортил страницу лишним белым куском на 700+ точек.
Результаты таковы (html - это document.documentElement):
1. Виевпорт во всех трех записан и в body, и в html корректно и с вычетом скролбара.
2. Во всех браузерах body.scrollTop равен 0 не зависимо от того, где мы находимся - вверху или внизу. В принципе, логично, у нас же html скролится, а не body.
2. Во всех браузерах offsetWidth и offsetHeight что у body, что у html равны размеру виевпорта.
3. Исходя из вышесказанного и увиденного полная высота именно body записана только в IE, в котором мы можем видеть, что body - 2471 px, а html - 3178 px; в Опере мы можем понадеяться, что лишней простыни после body не добавлено и следовательно его высота равна высоте html, а вот в Фоксе мы понятия не имеем, что body короче html и вообще короче ли или одинаковы.
Если нужно знать высоту именно body, то в ряде случаев можно попробовать запретить скрол html-у и выдать скролл body. Но в ряде случаев такой финт ушами не получится (если получится вообще, т.к. не пробовал еще). Например если у нас дизайн на 100% высоты видимого окна, тогда чтобы размер документа был на всю видимую высоту даже если контент коротковат для этого, нам придется в css выставить высоту 100% для html, body и контейнера, который содержит контент и например футер или бекграунд внизу. А в таком случае когда контента будет больше чем на высоту виевпорта указанные нами 100% для html будут делать его всегда не меньше чем body в нем,который тоже не меньше чем контент в нем. Т.е. фишка с коротким html и скролящимся в нем body - не возможна.
Вот так. Придется обходится высотой html или решать, как обойти проблему его удлинения.
Стоит отметить, что в IE8 (может и других версий) screen.width и window.screen.width возвращают не реальное разрешение экрана, а виртуальное (т.е. при изменении масштаба отображения меняется и разрешение, возвращаемое функциями, например, при помощи Ctrl+колесо мыши).
Доходчиво про ClientX/Y и почему Опера их нормально обрабатывает.
Говорю Спасибо за сайт.
Мне очень помог.
Спасибо за статью! Но нигде не могу найти, как можно (и можно ли вообще) определить расстояние нижней границы элемента до нижней границы окна браузера. Может, кто-нибудь подскажет. Заранее спасибо!
Всем привет, Великолепная фраза
Интересно конечно, но есть много вопросов по теме ИМХО. Давайте обсудим (мыло в подписи) или тут, если не затруднит
"Буду раЗ услышать замечания . "
помог scrollHeight снять с дива высоту динамически
var nextdata = 10; var controlXP = null;
Modalheightobj = (Winmedia.WindowData.scrollHeight - 450);
if ((EvenTop >= Modalheightobj) && (EvenTop > controlXP) && (controlXP < Modalheightobj))
case '415' : case '425' :
Интерестная статья..
подскажите как сделать:
при scrollTop(300) , например, чтоб цвет блока менялся, нужно производить изменения по достижению этой высоты, без кликов и перезагрузок страницы
вот такой вариант покачто получился, но приходится обновлять страницу =( что не есть хорошо.
offetLeft - отступ слева, измеряется в пикселах относительно родительского элемента.
подскажите как можно проверить, до конца ли прокручена страница скроллом?
есть вопрос к хорошей статье, у меня не работает функция offsetHeight в chrome, показывает 0, если принудительно не определен размер diva, что делать? заранее благодарен
пс: хром с 15ой версии, привиос версии не проверял
я конечно догадывался, что проще пролезть в форточку, чем пройти через дверь, но все же вот самый простой способ узнать высоту вьюпорта в любом браузере!=)
абсолютно аналогично для ширины. что проще чем убрать скролы, обрубив все лишнее, что вылезает за окно браузера; измерить высоту и вернуть обратно?=)
коечто подправил. для динамической работы)
Вопрос исключительно для профессионалов. Я хочу узнать реальную ширину текста. Есть стиль для некоего div'а:
Соответственно забиваю текст в нужный div и использую свойство scrollWidth. Получаю реальную ширину, однако это свойство не дает дробной части, которая есть в firefox. отсюда вопрос, как найти эту потерянную дробную часть.
Подскажите, интересует вывод всплывающего окна по средине браузера. Сейчас сделана привязка к координатам родительской ссылки.
Не паримся, определяем размер страницы так используя jquery - $(document).height() - коротко, правильно, кросбраузерно.
Огромное спасибо!
Отличная и полезная статья.
Также - спасибо комментаторам, многие дельные.
не лучше ли сейчас вместо offsetWidth и offsetHeight. всегда использовать getBoundingClientRect?
дело в том, что в chome вычислении высоты выдаёт предупреждение:
SVGElement.offsetWidth' is deprecated and will be removed in M50
Или у getBoundingClientRect есть свои недостатки? (я не нашёл)
Ну, кроме того, что может понадобиться округление для width / height.
Чтобы не использовать тяжеловесные библиотеки, можно написать на чистом JavaScript простое и расширяемое решение для манипуляций с элементами веб-страницы.
Возможность масштабировать элементы страницы и детально рассматривать их – это очень крутой пользовательский опыт. Существует множество готовых библиотек с подобной функциональностью, но сегодня мы напишем собственный велосипед на чистом JavaScript! Зачем?
- Сторонние решения часто предлагают избыточную функциональность, которая вам не нужна, но бандл приложения увеличивает.
- К тому же это замечательный челлендж, который расшевелит ваш мозг и прокачает навыки программирования.
В результате мы получим очень маленькую (всего 69 строчек кода!), простую и удобную библиотечку для масштабирования и панорамирования.
Разметка и стили
Внутри рабочей области находятся несколько элементов, которые не несут никакой смысловой нагрузки, а просто предназначены для демонстрации работы кода.
Добавим также немного стилей для оформления страницы:
Для body устанавливаем overflow: hidden . Это нужно, чтобы избежать переполнения страницы и появления прокрутки при чрезмерном увеличении элемента.
Также добавим рамку для визуального обозначения рабочей области ( .area ) и немного облагородим демо-контент (классы .circle , .rectangle и .text-area ).
Скрипт библиотеки
Код самой библиотеки будет располагаться в файле renderer.js . Экспортируем из модуля главную функцию renderer :
Она принимает базовые параметры:
- minScale – минимальный масштаб;
- maxScale – максимальный масштаб;
- element – DOM-элемент, с которым будут производиться манипуляции;
- scaleSensitivity – коэффициент чувствительность масштабирования, по умолчанию 10.
В замыкании функции создается объект состояния – state , который хранит настройки и совершенные над элементом преобразования (поле transformation ).
Из функции возвращается объект с набором методов. При этом возможности масштабирования и панорамирования разделены на отдельные функции-конструкторы – makeZoom и makePan , которые мы разберем чуть позже. Конструкторы получают общий объект состояния и возвращают отдельный набор методов для взаимодействия с ним.
Такой подход называется композицией и позволяет проще добавлять новую функциональность и легче тестировать приложение.
Трансформации
Все манипуляции с элементом будут производиться через изменение свойства transform . Для этого используем CSS-функцию matrix , которой нужно передать правильные параметры масштаба ( scale ) и сдвига ( translateX и translateY ):
Вспомогательная функция getMatrix просто формирует шаблонную строку правильного формата, которую нужно установить в свойство style.transform элемента.
Панорамирование
При панорамировании должно изменяться положение элемента на странице, то есть производиться его сдвиг. Функция pan принимает текущее состояние элемента ( state ), а также новые координаты. Затем она обновляет состояние, прибавляя новый сдвиг к текущему положению и обновляет свойство style элемента.
Теперь реализуем два метода:
- panBy – простой сдвиг на указанные координаты;
- panTo – сдвиг с одновременным масштабированием.
При сдвиге с масштабированием координаты элемента нужно скорректировать.
Масштабирование
Для изменения размера элемента нам потребуется несколько вспомогательных функций для расчетов:
Метод getScale рассчитывает новый масштаб на основе предыдущего значения, минимального и максимального ограничений ( minScale , maxScale ) и коэффициентов ( scaleSensitivity , deltaScale ).
Метод getTranslate рассчитывает новый сдвиг на основе масштаба и текущей и предыдущей позиции.
А вот и реализация функции makeZoom :
Она возвращает только один метод zoom , предназначенный для масштабирования элемента. Он получает координаты курсора, а также параметр deltaScale – коэффициент, который определяет направление масштабирования ( 1 для увеличения, -1 для уменьшения).
Функция вычисляет новые параметры трансформации и обновляет свойство style элемента.
При масштабировании кроме style.transform нужно изменять также свойство style.transformOrigin , чтобы скорректировать позицию элемента. В качестве эксперимента вы можете закомментировать 14 строчку и посмотреть, что будет.
Главный файл
Кроме того мы сделаем главный файл приложения index.js :
Клиентский код создает экземпляр renderer и передает ему базовую конфигурацию:
- элемент, размер которого будет изменяться;
- минимальный и максимальный масштаб;
- коэффициент чувствительности масштабирования.
Затем устанавливаются слушатели событий мыши и в нужный момент вызываются нужные методы:
- для масштабирования используйте колесико мыши или сенсорную панель, зажав клавишу CTRL.
- для перемещения – перемещайте мышь или используйте тачпад, зажав клавишу SHIFT.
- Двойной щелчок мыши восстановит исходное состояние элемента.
Тестирование
Проверим реализованные функции с помощью библиотеки Mocha:
Перед каждым тестом ( beforeEach ) создается объект _element с дефолтными значениями.
Кейсы тестирования для удобства вынесены в отдельный файл renderer.testCases.js .
В итоге у нас получился очень простой и удобный инструмент для масштабирования и панорамирования на JavaScript, состоящий всего из 69 строк кода. Его можно сократить больше, но не хочется терять читабельность.
Здравствуйте. Я уже давно сижу во вконтакте с масштабом 150% и иначе сайт уже не воспринимаю. Вот так он выглядит в оригинале на fullhd мониторе:
а вот так сайт обычно вижу я
Такой масштаб я получаю, крутя колёсико с зажатым Ctrl.
У меня возник вопрос: а как получить такой же эффект, но используя лишь код?
В голову сразу пришла мысль: сделать
, но в этом случае может что-то поломаться на сайте. В случае с vk: ломается прокрутка левой менюшки. При прокручивании ленты вниз и возвращении обратно - менюшка возвращается только наверху страницы, поэтому вариант с scale - не самый лучший. В идеале хотелось бы инициировать именно масштаб браузера, а не пытаться нагружать ПК лишними перерисовками transform (учтите, что граф. процессор может быть выключен).
Для чего это надо?
А нужно мне это для адаптивности. Порой не хочется делать отдельную версию для fullhd, и ограничиться самым большим макетом в 1000px. На fullHd это выглядит мелко и нелепо. Масштаб бы исправил ситуацию.
Скажите, с помощью каких стилей или скриптов можно организовать грамотный масштаб?
Простой 15 комментариев
А нужно мне это для адаптивности. Порой не хочется делать отдельную версию для fullhd, и ограничиться самым большим макетом в 1000px. На fullHd это выглядит мелко и нелепо. Масштаб бы исправил ситуацию.
Адаптивность так никто не делает. Адаптивность — это не увеличение масштаба элементов в рамках одного класса устройств и настроек ОС. Это приведёт к тому, что на одном телефоне всё будет жутко мелкое, а на другом — жутко большое. И, поверьте, никто на 4К-мониторе не захочет видеть ваш сайт в 400% увеличении, как вы планируете. Вы сломаете визуальное восприятие сайта, пользовательские значения масштаба, пользовательские настройки размера текста и т. д. и т. п. Опять же, если это вас не остановит, то найдите пример адаптивного сайта, у которого бы адаптивность была сделана таким образом. Подсказка: таких нет, потому что так делать нельзя. Есть простое правило: чем выше физическое разрешение экрана и чем меньше его физический размер, тем больше степень масштаба для сохранения адекватных размеров интерфейса.
P. S. Если настолько сильно хочется, LMAO, то у вас два быстрых варианта: transform и zoom.
Не могу утверждать, но, исходя из наблюдений, скейл браузера работает по принципу изменения размера экрана. То есть для сайта размер экрана в пикселях, но реальный размер экрана остаётся прежним.
А такое поведение уже цсс не умеет. Жс тоже не умеет, но можно сымитировать, рассчитывая значения с учётом скейла.
WbICHA, да, по сути так оно и есть. Увеличение браузера работает по принципу изменения степени масштаба ОС и меняет размеры viewport с его виртуальными пикселями, полученными из реального разрешения экрана × масштаб ОС × степень масштаба страницы в настройках браузера.
Сергей ZSA, есть другие варианты быстрого решения проблемы (которой, кстати нет)? Тут вопрос явно не про em, rem и даже не про безумные варианты на vw. Человеку нужно быстро сделать плохо, а не долго и хорошо.
Рустам Байназаров, если человеку просто не хочется смотреть сайт в таком разрешении – значит надо увеличить размер шрифта браузера. Если человеку нужно разработать сайт, который должен быть резиновым – значит тут не должно быть разговора про "быстро" и "дешево". Именно это нужно объяснять как автору поста, так и его заказчику, если там всё так, а не разговоры разговаривать о том, как это сделать "колхозно быстро и дёшево". Иначе у нас так и будет куча необразованных верстальщиков, которые только и умеют, что стряпать на скорую руку посредственные сайты.
Вопрос был изначально не в том, "а можно ли зафигачить адаптивность только через transform". Спрашивается, как сделать грамотный масштаб. А вы развозите про transform и zoom. Человек не глупый и сам понимает, что не прокатит вариант с transform, о чем в вопросе и пишет.
Нет, именно в этом. Человек не хочет делать адаптивность, а хочет просто увеличить масштаб:
Т. е. вы хотите сказать, что постановка задачи в целом верна? И что так в целом стоит делать? Я не про средства, а про конечный итог — изменения масштаба в бóльшую сторону в случае наличия экрана бóльшего, чем контейнер сайта. Т. е. например, это правильно, что человек с 4К монитором и 100% масштабом ОС и браузера должен видеть вписанный в него контейнер сайта, рассчитанный максимум на 1024 px? Нет, конечно же.
Scale и zoom — сломанные костыли, которые никогда не заменят полноценный масштаб viewport даже на 000,1%, как, собственно, например, rem и em, но последние вообще для другого используются — для доступности, а не для решения подобной, неверной в своём корне, задаче. И это нельзя делать вообще никогда и ни с каким подходом, будь то vw, rem/em, scale или zoom.
Человек хочет быстро и неправильно, ломая основы адаптивности, доступности и нормального дизайна, учитывающего вышеуказанное. Так ещё и быстро. Я, предупредив его обо всём этом, указал два пути быстрого и неправильного решения его изначально неправильной задачи. И, как вы и сказали, человек неглупый и сам поймёт свою ошибку и неверность подхода.
А это бред редкостный, который ещё поискать нужно. Давайте начнём с того, что на 4к вы уже сидите с масштабированием (если нет, то тут должен быть мем из 50-и оттенков серого).
Адаптивность так никто не делает. Адаптивность — это не увеличение масштаба элементов в рамках одного класса устройств и настроек ОС. Это приведёт к тому, что на одном телефоне всё будет жутко мелкое, а на другом — жутко большое.
Я даже не знаю, как на ваши комментарии реагировать. Рустам, опять бред! Скажите, в каком месте я написала, что отказываюсь от media? Я просто хочу, чтобы сайт на 1920 выглядел также как и на 1024. И да, Рустам, это адаптивность.
найдите пример адаптивного сайта, у которого бы адаптивность была сделана таким образом. Подсказка: таких нет, потому что так делать нельзя.
и ничего, что сайт мой? Наверное я понимаю, что делаю? Наверное я решаю, как я хочу, чтобы сайт открывался, а не пользователь?
Я понимаю, Рустам, вы молодец, куратор тега, но пожалуйста, не нужно больше ничего писать здесь. Я хочу дождаться утра и почитать ответы других пользователей, не ваши
Вернёмся к вопросу:
Возьмём тот же vk. Первоначальный дизайн - крайне плох, поэтому мне приходится делать масштабирование, чтобы он был чуть более юзабильным. То масштабирование (системное) по-сути полностью решает проблему: ничего не ломается, всё работает, выглядит так, как меня устраивает. Но вызвать я его не могу (хотя я не исключаю, что это как-то возможно. я пока не нашла решение)
Сергей ZSA,
да, я ищу быстрый и дешёвый способ. А если это колхозно, но будет работать, то это уже не колхозно, а действенно
Анастасия, например, у меня 32-дюймовый 4К монитор. Конечно же я сижу без масштаба. Более того, это стандартные параметры ОС Windows мне так сделали автоматом. Как будете решать эту задачу?
Скажите, в каком месте я написала, что отказываюсь от media? Я просто хочу, чтобы сайт на 1920 выглядел также как и на 1024. И да, Рустам, это адаптивность.
А я тоже не сказал, что отказываетесь от них. Я сказал, что вы ломаете принципы адаптивности, ибо у вас не адаптивность будет после 1024px, а масштабирование. Вы хотите скрестить их.
К сожалению, Анастасия, я знаю, как сделать то, что вы хотите. Просто так никто не делает: верстаете всё на rem и em, а на нужных разрешения внезапно увеличиваете базовое значения размера шрифта, что пропорционально, идеально и без поломок увеличивает весь сайт. И да, я так делал, но только то была вёрстка журнала для выставки, а не массовый продукт.
Вас понял. Видимо, вы не занимались большим проектом. Пользователь решает очень многое.
Изменить масштаб окна браузера напрямую невозможно по очевидным причинам. Только в мобильных браузерах, если удалить мета-тег адаптивности, но это далеко не то, что нужно вам. Плюс, это негибко. «Непрямого» и быстрого метода увеличения масштаба всех элементов сайта без поломки системы координат и fixed (scale на body) или поломки вообще много чего (zoom) — нет. Только делать всё через медиазапросы и rem/em, как я сказал выше. Ну или на крайний случай vw (такое безумие тоже возможно).
Справедливости ради Тостер и ВК не видно и на других мониках со 100% масштабом, если пользователю не 18 и он не орел с его зрением. Надеюсь, вы поняли о чем я.
Но было бы странно, если бы отображение увеличилось в 4 раза на 4к.
Куда как приятнее было бы, если бы увеличился только шрифт и только слегка увеличилась ширина блоков.
Ради той же справедливости, я тоже не увеличиваю масштаб в системе. Но есть рабочий браузер со 100% масштабом и браузер для чтения. И было бы хорошо, если бы увеличение размера шрифта в браузере приводило к корректному отображению сайтов, но в большинстве случаев это не так. Поэтому, остается только масштаб в браузере.
Вашим вариантом может быть переход на vw при размере вьюпорта больше ~1200 (подставьте нужное) и calc. Можно и без calc, если считаете, что всякие бордеры-полоски тоже должны увеличиваться.
Правда, это не 1,5 строчки. Хотя, при лаконичной верстке может оказаться, что не так и много нужно переписывать/пересчитывать, особенно при использовании кастомных свойств.
Вариант с rem написали выше.
Но и варианты с масштабом или всё на vw или на rem - нельзя назвать хорошими.
Вы получите резину, но не адаптив. А scale еще и подразмазать может.
Ведь цель-то у людей, обычно, видеть текст и попадать по интерактивным элементам. При этом, им не нужно увеличение картинок и подобных украшалок. (Картинки разумнее увеличивать отдельно, при клике на них.)
А это адаптив с кучкой media, а не резина.
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Как найти ширину окна браузера? Как узнать всю высоту страницы, с учётом прокрутки? Как прокрутить её из JavaScript?
С точки зрения HTML, документ – это document.documentElement . У этого элемента, соответствующего тегу , есть все стандартные свойства и метрики и, в теории, они и должны нам помочь. Однако, на практике есть ряд нюансов, именно их мы рассмотрим в этой главе.
Ширина/высота видимой части окна
Свойства clientWidth/Height для элемента document.documentElement – это как раз ширина/высота видимой области окна.
Например, кнопка ниже выведет размер такой области для этой страницы:
В чём отличие? Оно небольшое, но чрезвычайно важное.
Свойства clientWidth/Height , если есть полоса прокрутки, возвращают именно ширину/высоту внутри неё, доступную для документа, а window.innerWidth/Height – игнорируют её наличие.
Если справа часть страницы занимает полоса прокрутки, то эти строки выведут разное:
Обычно нам нужна именно доступная ширина окна, например, чтобы нарисовать что-либо, то есть за вычетом полосы прокрутки. Поэтому используем documentElement.clientWidth .
Ширина/высота страницы с учётом прокрутки
Теоретически, видимая часть страницы – это documentElement.clientWidth/Height , а полный размер с учётом прокрутки – по аналогии, documentElement.scrollWidth/scrollHeight .
Это верно для обычных элементов.
А вот для страницы с этими свойствами возникает проблема, когда прокрутка то есть, то нет. В этом случае они работают некорректно. В браузерах Chrome/Safari и Opera при отсутствии прокрутки значение documentElement.scrollHeight в этом случае может быть даже меньше, чем documentElement.clientHeight , что, конечно же, выглядит как совершеннейшая чепуха и нонсенс.
Эта проблема возникает именно для documentElement , то есть для всей страницы.
Надёжно определить размер страницы с учётом прокрутки можно, взяв максимум из нескольких свойств:
Почему так? Лучше и не спрашивайте, это одно из редких мест, где просто ошибки в браузерах. Глубокой логики здесь нет.
Получение текущей прокрутки
У обычного элемента текущую прокрутку можно получить в scrollLeft/scrollTop .
Что же со страницей?
Большинство браузеров корректно обработает запрос к documentElement.scrollLeft/Top , однако Safari/Chrome/Opera есть ошибки (к примеру 157855, 106133), из-за которых следует использовать document.body .
Чтобы вообще обойти проблему, можно использовать специальные свойства window.pageXOffset/pageYOffset :
Кросс-браузерный вариант с учётом IE8 предусматривает откат на documentElement :
Изменение прокрутки: scrollTo, scrollBy, scrollIntoView
Чтобы прокрутить страницу при помощи JavaScript, её DOM должен быть полностью загружен.
На обычных элементах свойства scrollTop/scrollLeft можно изменять, и при этом элемент будет прокручиваться.
Никто не мешает точно так же поступать и со страницей. Во всех браузерах, кроме Chrome/Safari/Opera можно осуществить прокрутку установкой document.documentElement.scrollTop , а в указанных – использовать для этого document.body.scrollTop . И будет работать. Можно попробовать прокручивать и так и эдак и проверять, подействовала ли прокрутка, будет кросс-браузерно.
Но есть и другое, простое и универсальное решение – специальные методы прокрутки страницы window.scrollBy(x,y) и window.scrollTo(pageX,pageY).
Метод scrollBy(x,y) прокручивает страницу относительно текущих координат.
Например, кнопка ниже прокрутит страницу на 10px вниз:
Метод scrollTo(pageX,pageY) прокручивает страницу к указанным координатам относительно документа.
Он эквивалентен установке свойств scrollLeft/scrollTop .
Чтобы прокрутить в начало документа, достаточно указать координаты (0,0) .
scrollIntoView
Для полноты картины рассмотрим также метод elem.scrollIntoView(top).
Метод elem.scrollIntoView(top) вызывается на элементе и прокручивает страницу так, чтобы элемент оказался вверху, если параметр top равен true , и внизу, если top равен false . Причём, если параметр top не указан, то он считается равным true .
Кнопка ниже прокрутит страницу так, чтобы кнопка оказалась вверху:
А следующая кнопка прокрутит страницу так, чтобы кнопка оказалась внизу:
Запрет прокрутки
Иногда бывает нужно временно сделать документ «непрокручиваемым». Например, при показе большого диалогового окна над документом – чтобы посетитель мог прокручивать это окно, но не документ.
Чтобы запретить прокрутку страницы, достаточно поставить document.body.style.overflow = "hidden" .
При этом страница замрёт в текущем положении.
При нажатии на верхнюю кнопку страница замрёт на текущем положении прокрутки. После нажатия на нижнюю – прокрутка возобновится.
Вместо document.body может быть любой элемент, прокрутку которого необходимо запретить.
Недостатком этого способа является то, что сама полоса прокрутки исчезает. Если она занимала некоторую ширину, то теперь эта ширина освободится, и содержимое страницы расширится, текст «прыгнет», заняв освободившееся место.
Это может быть не очень красиво, но легко обходится, если вычислить размер прокрутки и добавить такой же по размеру padding .
Итого
Для получения размеров видимой части окна: document.documentElement.clientWidth/Height
Для получения размеров страницы с учётом прокрутки:
Прокрутка окна:
На всякий случай – вот самый кросс-браузерный способ, учитывающий IE7- в том числе:
Установить прокрутку можно при помощи специальных методов:
- window.scrollTo(pageX,pageY) – абсолютные координаты,
- window.scrollBy(x,y) – прокрутить относительно текущего места.
- elem.scrollIntoView(top) – прокрутить, чтобы элемент elem стал виден.
Задачи
Полифилл для pageYOffset в IE8
Обычно в IE8 не поддерживается свойство pageYOffset . Напишите полифилл для него.
При подключённом полифилле такой код должен работать в IE8:
В стандартном режиме IE8 можно получить текущую прокрутку так:
Самым простым, но неверным было бы такое решение:
Код выше не учитывает текущую прокрутку. Он присваивает window.pageYOffset текущую прокрутку, но при её изменении – не обновляет это свойство автоматически, а поэтому – бесполезен.
Более правильное решение – сделать это свойство геттером. При этом в IE8 для DOM-объектов работает Object.defineProperty :
Как узнать ширину и высоту окна браузера? Как получить полную ширину и высоту документа, включая прокрученную часть? Как прокрутить страницу с помощью JavaScript?
Для большинства таких запросов мы можем использовать корневой элемент документа document.documentElement , который соответствует тегу . Однако есть дополнительные методы и особенности, которые необходимо учитывать.
Ширина/высота окна
Чтобы получить ширину/высоту окна, можно взять свойства clientWidth/clientHeight из document.documentElement :
Например, эта кнопка показывает высоту вашего окна:
Браузеры также поддерживают свойства window.innerWidth/innerHeight . Вроде бы, похоже на то, что нам нужно. Почему же не использовать их?
Если есть полоса прокрутки, и она занимает какое-то место, то свойства clientWidth/clientHeight указывают на ширину/высоту документа без неё (за её вычетом). Иными словами, они возвращают высоту/ширину видимой части документа, доступной для содержимого.
А window.innerWidth/innerHeight включают в себя полосу прокрутки.
Если полоса прокрутки занимает некоторое место, то эти две строки выведут разные значения:
В большинстве случаев нам нужна доступная ширина окна: для рисования или позиционирования. Полоса прокрутки «отъедает» её часть. Поэтому следует использовать documentElement.clientHeight/Width .
Обратите внимание, что геометрические свойства верхнего уровня могут работать немного иначе, если в 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 должен быть полностью построен.
Например, если мы попытаемся прокрутить страницу из скрипта в , это не сработает.
Обычные элементы можно прокручивать, изменяя 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 .
Недостатком этого способа является то, что сама полоса прокрутки исчезает. Если она занимала некоторую ширину, то теперь эта ширина освободится, и содержимое страницы расширится, текст «прыгнет», заняв освободившееся место.
Это выглядит немного странно, но это можно обойти, если сравнить clientWidth до и после остановки, и если clientWidth увеличится (значит полоса прокрутки исчезла), то добавить padding в document.body вместо полосы прокрутки, чтобы оставить ширину содержимого прежней.
Итого
Ширина/высота видимой части документа (ширина/высота области содержимого): document.documentElement.clientWidth/Height
Читайте также: