Ширина 50 от ширины окна браузера
В прошлых уроках вы уже узнали о единицах измерения px. Можно заметить, что стоит указать где-то 20px и это значение будет зафиксировано. Неважно что вокруг элемента с таким значением, какое разрешение экрана или какое устройство используется. 20 пикселей всегда будут 20 пикселей.
Пиксель является абсолютной единицей измерения. Как уже было сказано выше, такая единица измерения строго фиксирована и не меняется от внешних факторов. Изменить размер можно только переопределением.
В противовес абсолютным единицам измерения существуют относительные единицы измерения. По их названию видно, что они зависят «от чего-то». А вот от чего они зависят мы рассмотрим в конце урока.
В этом уроке будут рассмотрены все основные единицы измерения. На самом деле их достаточно много, но не все используются постоянно. Если у вас возникнет желание познакомиться со всеми доступными единицами измерения, то в конце урока будет ссылка на официальную спецификацию.
Абсолютные единицы
Абсолютные единицы измерения можно считать самыми простыми. Достаточно получить немного опыта и вы уже на глаз сможете определять, какой размер имеет тот или иной элемент внутри документа.
Самой распространённой единицей является пиксель. С ней вы уже знакомы по другим урокам. Но что же такое пиксель? Если не вдаваться в электронику, то пиксель — это всего лишь минимальный элемент, из которого состоит изображение на экране. Значит, мы указываем, сколько таких элементов должно быть занято на экране устройства.
При этом стоит понимать, что 100 пикселей на одном экране могут быть не равны 100 пикселям на другом экране. Всё зависит от размера пикселей в мониторе. А это, в свою очередь, зависит от характеристик экрана и его разрешения.
По этим причинам можно назвать пиксель как относительной, так и абсолютной единицей измерения. Всё зависит от того, с какой точки зрения мы смотрим. Для нас важен пиксель в контексте CSS, где он является абсолютной единицей.
Другие абсолютные единицы почти не используются в разработке для веб-устройств. Стоит их перечислить, но есть вероятность, что вы никогда не будете их использовать.
- cm — сантиметры
- mm — миллиметры
- Q — четверть миллиметра
- in — дюйм
- pc — пайка/пика. Термин из типографики
- pt — пункт
Заметьте, что среди этих единиц есть знакомые в реальной жизни. При вёрстке для печати это может быть полезно.
Относительные единицы
Самая запутанная часть урока. Относительные единицы берут своё значение от других значений. Самой универсальной такой единицей являются проценты. Они всегда берут свои значения от ближайшего родительского элемента. Остальные единицы можно разделить на две группы:
- Относительные единицы, рассчитывающиеся от размера шрифта.
- Относительные единицы, рассчитывающиеся от размера экрана. Это немного грубое сравнение — на самом деле расчёт ведётся от размера viewport. О том, что это такое, вы узнаете из курса по адаптивности.
Проценты
Как уже было сказано, проценты рассчитываются от значения того же свойства ближайшего родителя. Родитель — элемент, внутри которого находится текущий блок. Например:
Рассмотрим на примере ширины и размера шрифта.
Что же здесь происходит? Разберёмся по шагам:
- Для основного родительского <section> установлены размеры в абсолютных единицах измерения. Ширина 400 пикселей и размер шрифта 50 пикселей.
- Вложенный <div> имеет размер 50%. Этот размер относительный и высчитывается относительно ближайшего родителя. У этого родителя размер 400 пикселей. Следовательно, размер блока будет 200 пикселей.
- Параграф текста имеет размер шрифта 70%. Ближайший родитель с установленным размером шрифта — <section> . Параграфу установится размер шрифта в 70% от 50 пикселей. То есть 35px.
Интересным примером является установка процентов для тега или класса, который предполагает вложение друг в друга. Взгляните на следующий пример:
Перед тем, как идти дальше, попробуйте проанализировать эту разметку и посчитать, какие размеры шрифта будут у каждого элемента списка. Не пугайтесь, если вы запутаетесь. Это может быть сложно.
Поразмыслили? Молодцы! Теперь посмотрим, как это выглядит:
- Размер шрифта самого первого элемента <ul> — 30 пикселей.
- Все элементы <li> имеют размер шрифта 70%. Это значит, что чем глубже список, тем меньше размер шрифта:
- Элементы 1, 2, 3, 4 будут иметь размер 21 пиксель.
- Элементы 1.1 и 1.2 лежат внутри элемент 1. Размер шрифта этого элемента 21 пиксель. Это следует из прошлого пункта. Теперь размер шрифта считается именно от 21 пикселя.
- Элементы 1.1 и 1.2 будут иметь размер 14.7 пикселя.
- Элементы 1.2.1 и 1.2.2 лежат внутри элемент 1.2. Размер шрифта этого элемента 14.7 пикселей. Это следует из прошлого пункта.
- Элементы 1.2.1 и 1.2.2 будут иметь размер шрифта 10.29 пикселя.
Относительные единицы, рассчитывающиеся от размера шрифта
Выдохните — самое сложное уже позади. Если вы внимательно изучили работу процентов, то другие относительные единицы не вызовут сложностей. Есть две основные относительные единицы измерения, которые зависят от размера шрифта: em и rem.
Значение em очень похоже на использование процентов. Оно показывает во сколько раз размер будет больше, чем у ближайшего вычисленого значения font-size . Если в прошлом примере со списками заменить 70% на 0.7em, то результат будет тот же самый.
Тогда в чём смысл em? Эту единицу измерения можно использовать не только для шрифта, но и для любых других свойств, которые принимают числовое значение. Например, в следующем коде размер нижнего внешнего отступа будет 60px:
Но если у параграфа выставить своё значение font-size , то единица em будет высчитываться именно от него. В этом и кроется смысл формулировки «чем у ближайшего вычисленого значения font-size ».
Второй такой единицей является rem. Её способ работы точно такой же, как у em. Но есть одно громадное отличие: rem отсчитывается от размера шрифта корневого элемента. Корневым элементом является <html> . Именно размер шрифта у этого элемента и учитывается при расчёте единицы rem.
Вернёмся к примеру со списком. Заменив em на rem получим совершенно другой результат. 0.7rem высчитываются из одного и того же места, без учёта вложенности. Итого, каждый элемент будет иметь размер шрифта 11.2px. Это связано со стандартным значением размера шрифта в 16 пикселей у большинства браузеров.
Вы можете заметить, что размер шрифта в 30 пикселей у элемента <ul> не играет, в данном случае, никакой роли.
Относительные единицы, рассчитывающиеся от размера экрана
CSS позволяет задавать размеры относительно текущего размера viewport — размера окна браузера, доступного без прокрутки. Основными двумя единицами являются vw — ширина viewport и vh — высота viewport. Вы можете рассматривать это как процент от размера viewport.
Частый «кейс» с использованием таких единиц — создание секции на всю доступную область браузера.
Попробуйте изменять размер окна браузера с примером из CodePen. Какую бы ширину вы не ставили, размер секции будет автоматически меняться. Следовательно, горизонтальная или вертикальная прокрутка никогда не появится.
Дополнительные материалы
Вам ответят команда поддержки Хекслета или другие студенты.
Нашли опечатку или неточность?
Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.
Что-то не получается или материал кажется сложным?
- задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
- расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
- изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Урок «Как эффективно учиться на Хекслете»
- Вебинар «Как самостоятельно учиться»
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.
Знаю, что у многих появится вопрос о том, почему у этой статьи такой необычный заголовок. Как связаны «отзывчивый веб-дизайн» и «высота окна браузера»? Пожалуй, этот заголовок кажется необычным из-за того, что под «отзывчивым дизайном», как правило, понимают проектирование страниц таким образом, чтобы они подстраивались бы под ширину области просмотра, чтобы они хорошо бы выглядели на разных устройствах. Сайты всегда тестируют, уменьшая ширину браузера и наблюдая за происходящим. Но я практически никогда не сталкивался с некими указаниями по тестированию какого-то проекта, в которых сказано, что страницы исследуют путём уменьшения высоты окна браузера. Возможно, вы когда-нибудь ловили себя на такой мысли: «Надо ли проверять страницы в окнах браузера разной высоты?». Я полагаю, что делать это надо, и собираюсь убедить в этом всех, кто прочитает эту статью.
При работе над веб-сайтом не очень правильно делать некие предположения, не опираясь на реальные данные. Поэтому очень важно брать на себя ответственность по проверке сайтов в окнах браузеров разной ширины и разной высоты.
Зачем проверять страницы в окнах браузеров разной высоты?
Хороший вопрос. Прежде чем переходить к примерам и к сценариям использования таких проверок, мне хотелось бы рассказать о проблемах, которые случаются с сайтами, не приспособленными к работе в областях просмотра разной высоты. Это поможет вам лучше понять то, о чём речь пойдёт дальше.
Неправильные предположения о том, как будут пользоваться сайтом, — это один из важнейших факторов, негативно влияющих на работу веб-дизайнера. Например, неправильно будет рассчитывать на то, что сайтом будут пользоваться, разворачивая браузер на весь экран. Вместо этого нужно рассчитывать на худшее.
Предположения и реальность
Выше приведена иллюстрация моих слов. В реальности далеко не все пользователи работают с браузерами так, как предполагает дизайнер. Я сам сталкивался с сайтами, которые плохо выглядели в окнах браузеров уменьшенной высоты.
Инструменты разработчика браузера
Изменение размеров браузера по вертикали — это не единственный способ воздействия на высоту области просмотра. Так, например, когда открывают панель инструментов разработчика, она тоже отнимает часть вертикального пространства.
Панель инструментов разработчика занимает часть окна браузера
Открытие инструментов разработчика может «поломать» дизайн сайта или пролить свет на проблемы, возможность появления которых никто не ожидал. Выделенная область рисунка представляет текущую высоту области просмотра. Если открыть инструменты разработчика, просматривая сайт на маленьком экране ноутбука, это приведёт к тому, что видимой окажется лишь небольшая область страницы.
Подумаем над одним важным вопросом: «Можно ли улучшить впечатления пользователя от работы с сайтом в то время, когда его просматривают в окне браузера небольшой высоты?». Я могу дать положительный ответ на этот вопрос. Полагаю, теории нам хватит. Давайте учиться «вертикальному» подходу к стилизации страниц.
«Вертикальный» 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 . Первое нужно для того чтобы элемент выглядел бы хорошо даже в тех случаях, когда он выводит короткий текст. А второе позволяет ограничить его высоту заданным значением вместо того, чтобы задавать ему неизменную высоту.Модальный элемент, подходящий для вывода длинных текстов
Итоги
Проектируя сайты с учётом тех впечатлений, которые вызовет работа с ними у пользователей, лучше всего строить их дизайн, опираясь на ширину и высоту окна браузера. Может, кому-то покажется странным тестирование страниц в окнах разной высоты, но такое тестирование себя оправдывает. Здесь я рассказал о важности «вертикального» подхода к дизайну сайтов, о том, как проектировать страницы в расчёте на их правильный вывод в областях просмотра разной высоты, рассмотрел примеры. Надеюсь, вам всё это пригодится.
Обращаете ли вы внимание на то, как создаваемые вами веб-страницы выглядят в окнах браузера разной высоты?
В этой статье вы узнаете про единицы вьюпорта в CSS и варианты их применения.
Viewport единицы уже существуют несколько лет и со временем я вижу рост их применения другими разработчиками. Их полезность заключается в том, что они дают нам возможность выставлять размеры гибким и динамическим образом, без прямого использования JavaScript. Также, для них легко сделать фоллбэк в случае отсутствия поддержки браузером.
Интро
В соответствии со спецификацией CSS, процентные вьюпорт единицы относительны размеру изначального блок контейнера, который сам по себе является корневым элементом страницы.
Viewport единицы это vw , vh , vmin и vmax .
Viewport ширина
Единица vw представляет собой процентное измерение ширины корневого элемента. Один vw равен 1% ширины вьюпорта.
Тут у нас есть элемент с таким CSS:
Когда ширина вьюпорта равна 500px , то 50vw будут высчитаны таким образом:
Viewport высота
Единица vh представляет собой процентное измерение высоты корневого элемента. Один vh равен 1% высоты вьюпорта.
У нас есть элемент с таким CSS:
Если высота вьюпорта равна 290px , то 70vh будет высчитано следующим образом:
Вот и всё! Теперь давайте взглянем на другие единицы.
Vmin
Эта единица является минимумом ширины или высоты вьюпорта. Если ширина вьюпорта больше его высоты, то значение единицы будет высчитано, основываясь на высоте.
Давайте посмотрим на пример ниже.
У нас есть мобильный телефон в лэндскейп режиме и у элемента на странице есть такая единица как vmin . В этом случае, значение будет высчитано по высоте вьюпорта, так как оно меньше ширины.
Вот как она будет считаться:
Как вы уже могли предположить, результат будет считаться таким образом:
Vmax
Это прямая противоположность vmin . Значение считается основываясь на максимальной ширине и высоте.
Давайте посмотрим на пример:
Результат бы был высчитан таким образом:
Как viewport единицы отличаются от процентов?
Они берут за основу корневой элемент страницы, в то время как проценты основаны на размере своего контейнера. Поэтому они и отличаются друг от друга и каждый имеет свойственные себе примеры использования.
Примеры использования viewport единиц
В следующих секциях мы посмотрим на некоторые примеры использования единиц viewport и на то, как их применять в ваших рабочих проектах.
Размер шрифта
Единицы вьюпорта идеальны для адаптивной типографики. Для примера, мы можем использовать следующий код для заголовка статьи:
Размер заголовка будет увеличиваться или уменьшаться в зависимости от ширины вьюпорта. Это как будто бы мы выдали размеру шрифта 5% ширины страницы. Однако, как бы не хотелось, а надо протестировать и смотрим, что получается.
Обратите внимание, что шрифт стал очень мелким при мобильных размерах, это очень плохо в плане доступности и UX. Насколько я знаю, минимальный размер шрифта на мобильных устройствах не должен быть ниже 14px . А там у нас выходит уже ниже 10px .
Чтобы решить эту проблему, нам надо дать заголовку минимальный размер шрифта, который не может быть меньше положенной нормы. И тут CSS calc() спешит на помощь!
У функции calc() будет основное значение и оно добавит к нему 2vw . Учитывая это, размер шрифта точно не будет слишком маленьким.
Ещё стоит рассмотреть то, как себя будет вести размер шрифта на больших экранах, к примеру на 27” аймаках. Что будет? Ну вы уже наверное предположили. Размер шрифта бахнет аж в 95px , что само по себе уже кошмар. Чтобы предохраниться от этой ситуации мы можем использовать медиа запросы на определённых брейкпоинтах и менять размеры шрифтов.
Сбрасывая font-size мы можем быть уверены в том, что размер шрифта не будет слишком большим. Тут возможно вам понадобится несколько медиа запросов, но это сугубо ваше личное дело когда и как их использовать в контексте проекта.
Полноэкранные секции
Иногда нам надо, чтобы секция забирала 100% высоты виюпорта. Это так называемые полноэкранные секции. Для их создания мы можем использовать вьюпорт единицу высоты.
Добавив height: 100vh , мы можем точно убедиться в том, высота секции будет в 100% высоту вьюпорта. Также, тут я добавил немного флексбокса, чтобы отцентровать контент вертикально и горизонтально.
Прилипающий футер
На больших экранах вы могли уже обратить внимание на то, что футер не прилипает к концу страницы. Ну и это нормально. Это даже не рассматривается как плохая практика. Однако, тут у нас есть пространство для улучшений. Давайте рассмотрим следующий кейс, в котором и происходит эта ошибка.
Чтобы её решить, нам нужно отдать основному контенту высоту, равную разнице между высотой вьюпорта и суммой хедера и футера. Динамически это довольно хитрая операция, но с помощью единиц вьюпорта всё становится довольно быстро и понятно.
Первое решение: calc и единицы вьюпорта
Если высота хедера и футера фиксированны, то их можно совместить с помощью функции calc() :
Это решение не гарантирует того, что оно будет всегда работать, особенно для футера. За всю свою карьеру я никогда не использовал футер с фиксированной высотой, потому что это просто непрактично, особенно на разных размерах экранов.
Второе решение: Flexbox и вьюпорт единицы (рекомендуемое)
Добавляя 100vh как высоту для body элемента, мы можем использовать флексы для того, чтобы основной контент занимал всё оставшееся место.
С учетом этого, наша проблема решена и у нас есть прилипающий футер вне зависимости от длины контента.
Адаптивные элементы
Занимаясь подготовкой материала я наткнулся на эту статью и она мне реально понравилась. Так что я возьму пример использования оттуда и объясню его своим способом.
Предположим, что у нас есть портфолио для того, чтобы показать свои адаптивные работы и у нас имеется три типа устройства (мобильные, планшеты и ноутбук). В каждом устройстве есть по изображению. Суть в том, чтобы сделать этот контент 100% отзывчивым на CSS.
Используя гриды и единицы вьюпорта, мы можем сделать это адаптивным и динамическим.
Обратите внимание, что вьюпорт единицы используются в grid-* свойствах. Они также используются для border , border-radius и других свойств. Всё это приведет к флюидному дизайну.
Выходим за пределы контейнера
Я обратил внимание на случай, который больше всего подходит для редакторских шаблонов. А именно когда дочерний элемент забирает 100% ширины вьюпорта, хотя его родитель ограничен в ней. Давайте рассмотрим пример ниже:
Чтобы достигнуть такого же эффекта, мы можем использовать вьюпорт единицы и свойства позиционирования. Вот наш CSS:
Давайте разберем всё по полочкам и поймём как это работает.
Добавляем width: 100vw
Самый важный шаг, который даст изображению ширину равную 100% вьюпорта.
Добавляем margin-left: -50vw
Чтобы отцентровать изображение, нам понадобится выдать отрицательный маргин с половиной ширины вьюпорта.
Добавляем left: 50%
И наконец, мы отодвинем изображение в правую сторону со значением 50% от ширины его родителя.
Вертикальный и горизонтальный спейсинг
Ещё один интересный пример, а именно использование вьюпорт единиц для спейсинга между элементами. Его можно использовать с таким значениями как margin , top , bottom и grid-gap . Применяя его, спейсинг будет основываться на ширине вьюпорта и его высоте, что может быть крайне полезным для создания динамических шаблонов.
Модалка
В случае с модалками нам надо отталкивать их с самого верха вьюпорта. Зачастую я делал это с помощью свойства top и процентов с пикселями. Однако, с единицами вьюпорта, мы можем добавить спейсинг, который может меняться, основываясь на высоте самого вьюпорта.
Посмотрите это видео, чтобы посмотреть на результат.
Шапка
Шапка это секция, которая показывает нам общую картину на странице или сайте. Часто там есть заголовок и описание, и среди этого всего есть фиксированная высота и падинги для верха и подвала страницы. Тут нам интересны падинги.
Для примера, вот как выглядит CSS:
Вертикальный паддинг довольно мал на мобильных устройствах и он становится больше на больших вьюпортах. Как насчет использования единиц вьюпорта? Давайте посмотрим на это.
Я использовал vh для паддинга в шапке и маргина под заголовком. Обратите внимание как меняется спейсинг!
Сетка из нескольких элементов
Ещё один пример динамического спейсинга можно применить в сетке из нескольких элементов. Тут может быть всё: статьи, секции контента, услуги и тп. В нашем примере мы посмотрим на то, как можно использовать вьюпорт единицы для сетки из статей.
Используя их в grid-gap , мы можем получить желаемый результат. Обратите внимание, что я применял функцию calc() . Суть использования calc() в том, чтобы у нас уже был базис для вертикального и горизонтального промежутков.
Vmin и Vmax — примеры использования
Изучая примеры использования для этих двух единиц, я не нашёл ничего, только этот пример из CSS-tricks.
Этот пример показывает возможность работы с верхним и нижним паддингом в шапке элемента. Паддинг зачастую слишком сокращен, когда вьюпорт довольно мал. Используя vmin , мы можем иметь флюидные верхние и нижние паддинги, которые основываются на вьюпорте с маленькими размерами.
Вертикальные медиа запросы и единицы вьюпорта
Несколько лет назад я написал статью о вертикальных медиа запросах.
Сейчас я хочу пролить свет на эту тему, так как она имеет прямое отношение к статье, которую вы сейчас читаете.
Секции на всю высоту экрана в Landscape режиме
Используя вертикальные медиа запросы мы можем проверять находится ли девайс пользователя в лэндскэйп режиме. Если так, то тогда не будет смысла иметь секцию, занимающую всю высоту вьюпорта, применяя height: 100vh .
Чтобы решить эту проблему, мы можем сделать следующее.
Или мы можем использовать orientation в медиа запросах:
Соотношение сторон
Мы можем использовать vh для создания адаптивных элементов, которые поддерживают актуальное состояние соотношения сторон вне зависимости от размера вьюпорта. Давайте на это посмотрим.
Нам нужно решить, какое соотношение сторон нам нужно. Для примера, 9/16.
Используем единицы вьюпорта для графических элементов
Я не уверен правильно ли я назвал это, но надеюсь, что вы поймете суть следующих графических примеров.
Довольно популярный подход с верхним бордером
Вы знали, что верхний бордер один из самых используемых элементов на веб сайтах к сегодняшнему дню? В основном его цвет, это такой же как и основной цвет страницы.
Давайте сделаем изначальным значением бордера 3px . Как конвертировать это фиксированное значение в вьюпорт единицу? Вот как можно это посчитать:
Ширина вьюпорта используется для расчета отношения между пикселями и vw единицей.
Для примера, вот как добавлен верхний бордер:
В моём случае ширина вьюпорта равна 1440.
И вот такой CSS мы получим:
Даже лучше, мы можем использовать основное значение в пикселях и единицу вьюпорта.
Нумерация секций
Для элементов секций с каунтером или иконкой, мы можем тоже применить единицы вьюпорта. Посмотрите на макет ниже:
Viewport Units Watcher
Я сделал инструмент, которые помогает мне в проверке высчитанного значения элементов у единиц вьюпорта. Посмотрите ниже:
Я добавил имя класса и свойство для каждого элемента и при смене размеров вьюпорта, значение будут динамически обновляться. Это куда лучше, чем использование DevTools и высчитывание каждого отдельного элемента.
Проблема со скроллом на мобильных устройствах
Есть распространенная проблема на мобильных устройствах, которая касается скролла, даже если используется 100vh . Проблема тут в том, что адресная строка находится во вьюхе. Луис Хобрегс написал статью об этом и показал простое и легкое её решение.
Использование 100vw как антипаттерн
Применяя 100vw для того, чтобы выдать элементу полную ширину вьюпорта, всё у вас будет отлично работать на Mac OS, так как вертикальный скроллбар там спрятан по-дефолту. Как результат, ширина скроллбара добавлена полной ширине.
Однако, пользователи Windows обратят внимание на то, что появился горизонтальный скроллинг. Почему? Потому что ширина скроллбара была добавлена ширине экрана. Скажем, что вы добавили такой CSS:
На Windows, высчитанная ширина .element будет равна 100vw + 8.5px , где 8.5px это ширина вертикального скроллбара.
Насколько я знаю, то пока что нет конкретного решения этой проблемы без использования JavaScript, применение которого тут я не советую. Лучше избегать 100vw и использовать альтернативу. Для примера, мы можем применить CSS Grid, чтобы элемент вышел за пределы контейнера, посмотрите на решение в этой статье.
Спасибо Крису Моргану и Килиану Валкхофу за то, что предупредили меня об этой проблеме.
Доступность это важно
Используя единицы вьюпорта довольно часто на вашем проекте, например для создание всего макета, доступность становится очень важной. Когда шаблон зумится ближе или отдаляется, элементы с единицами вьюпорат не будут увеличиваться или уменьшаться как вы ожидали. Это станет проблемой для пользователей, которые полагались на зум в браузере.
По словам Сары Суейдан, использование единиц вьюпорта для размеров шрифтов это плохая практика в плане доступности. Лучше комбинировать их с фиксированными значениями, как описано ниже:
Даже лучше, мы можем использовать CSS единицы em и rem , вместо px . Таким образом у нас будет больше контроля при изменении размера шрифта.
И это будет хорошо. Пожалуйста, убедитесь в том, что использование единиц вьюпорта подходит для того, что вы делаете и не забывайте хорошо тестировать.
Полезные инструменты
Я нашёл этот полезный конвертер из px в vw , который может помочь вам в вашем проекте.
Мы тут рассказывали про размеры текста в вёрстке. Но что, если задавать размеры не только текста, но вообще всего? В CSS это делается так же легко, как и в случае с текстом.
Как задаются размеры
У большинства элементов в CSS есть такие параметры для работы с размером:
height, width — высота и ширина;
max-height, max-width — высота и ширина, больше которых элемент не может быть (а меньше — может);
min-height, min-width — минимальная высота и ширина;
margin — размер поля вокруг элемента. Другие элементы не должны влезать в это поле;
padding — отступы внутри элемента, например, если внутри будет написан текст.
Например, нам нужно нарисовать кнопку, внутри которой будет текст. Описание стиля кнопки может быть таким:
.button width:75%;
max-width:600px;
min-width:300px;
padding: 15px 15px 19px 15px;
margin: 20px auto 50px auto;
>Перевод: кнопка должна занимать от 300 до 600 пикселей в ширину, а в этом диапазоне быть 75% ширины от содержащего ее контейнера; внутри кнопки отступи сверху 15 пикселей, справа 15, снизу 19, слева 15 (по часовой стрелке). Саму кнопку от ближайшего элемента сверху отодвинь на 20 пикселей, слева и справа отодвинь одинаково, чтобы она встала по центру, а снизу отступи еще 50 пикселей до следующего элемента.
Запись в стиле padding: 15px 15px 19px 15px — это короткий способ задать отступы по часовой стрелке. Первое значение — отступ сверху, второе — справа, третье — снизу, четвёртое — слева. Вместо короткой записи можно ещё так:
Но так обычно не пишут, потому что много текста.
Размеры в пикселях — жёстко, но точно
Самый простой способ задать размер элемента — указать его в пикселях. Например, если нам нужна ширина элемента 100 пикселей, то можно написать:
В пикселях можно задавать размеры почти чему угодно, потому что пиксели есть везде:
- HTML-вёрстка предполагает, что содержимое будет отображаться на каком-то экране;
- у каждого экрана, даже у виртуального, есть размер в пикселях по высоте и ширине экрана;
- получается, браузер всегда сможет понять, сколько пикселей какую часть экрана занимают, и от этого он нарисует элемент нужного нам размера.
С пикселями есть только одна проблема: так как размеры и плотность пикселей на разных экранах разные, то может получиться так:
- на экране 5-дюймового телефона с разрешением 1920 на 1080 пикселей баннер шириной 200 пикселей получит размер в 5 сантиметров;
- а на мониторе с диагональю 24 дюйма, но с тем же разрешением 1920 на 1080 те же 200 пикселей будут иметь длину 10 сантиметров.
Чтобы было нагляднее, сделаем тестовую страницу с тремя блоками одинаковой высоты, но с шириной 100 пикселей.
Справедливости ради, браузеры понимают эту проблему, поэтому умеют пересчитывать пиксели так, чтобы сайты не ломались. Например, если у вас есть современный экран с разрешением 288 точек на дюйм и тут же рядом старый экран с разрешением 72 точки на дюйм, то браузер поймёт, что надо пересчитать одни пиксели в другие. Если поставить два сайта рядом на этих экранах, они будут не один в один, но похожи.
В зависимости от размеров экрана — гибко, но надо перепроверять на разных экранах
Чтобы не зависеть от размера пикселей, а масштабировать элементы в зависимости от размера экрана, придумали другие единицы измерения:
- vh — это 1% от высоты окна;
- vw — это 1% от ширины окна.
Получается, программисту уже не надо думать, сколько пикселей надо сделать картинку, чтобы она занимала половину ширины экрана на разных экранах. Вместо этого достаточно указать так:
В этом случае браузер сделает так:
- Посмотрит, что за единица измерения — vw, значит нужна ширина экрана.
- Узнает, какой ширины в пикселях окно, в котором открывается эта страница.
- Поделит её на 100, чтобы узнать размер одного vw в пикселях.
- Умножит это значиние на 50, чтобы понять размер в пикселях нужного нам элемента.
- Установит это значение в пикселях при вёрстке.
- Если в процессе просмотра у браузера поменяется размер экрана — он сам всё пересчитает и отрисует заново.
Используем страницу из предыдущего раздела и немного переделаем её — установим такой размер блоков:
- первый блок — 10vw
- второй блок — 20vw
- третий — 50vw
Если нам нужно, чтобы блоки по высоте занимали всю высоту экрана, то для этого достаточно указать в стилях div такой параметр:
Ещё есть vmin и vmax, которые работают так:
- vmin находит минимальное значение из пары (vh, vw);
- а vmax находит максимальное значение из пары (vh, vw).
Это нужно, например, для адаптивной вёрстки, когда вам требуется привязаться к короткой стороне экрана и в зависимости от её размеров построить всю остальную страницу.
Проценты — очень гибко, но всегда нужен родительский элемент
Кажется, что vh и vw — это и есть те самые проценты от ширины экрана и что можно обойтись без обычных процентов. Но на самом деле просто проценты в вёрстке тоже используются, но с одним важным моментом:
👉 Чтобы использовать проценты, нужен родительский элемент, от которого эти проценты будут считаться.
Родительский элемент — тот, внутри которого находятся другие наши элементы. Например, мы хотим сделать на странице блок шириной 500 пикселей:
У этого блока есть точный размер, который браузер может взять или посчитать. Теперь внутри этого блока мы легко можем расположить свои блоки в тех же процентах, что и в предыдущем примере:
- первый блок — 10%;
- второй блок — 20%;
- третий — 50%.
Если мы явно не указали размер родительского элемента, то браузер постарается угадать его или посчитать самостоятельно. Но получится это не всегда.
Нужно ли в этом разбираться?
Вообще в современном мире взрослые фронтендеры верстают с помощью css-grid и готовых верстальных фреймворков: в них все размеры стандартизированы и прописаны под капотом, а верстальщики просто говорят «большое», «среднее», «сбоку», «на три четверти», «на всю ширину» и т. д. А уже как это интерпретировать и какие конкретно там размеры — этим занимается фреймворк.
Читайте также: