В современном мире уже никуда не деться без адаптивных layout-ов. В данной статье разберем создание двух вариантов таких интерфейсов: один попроще, другой посложнее.
Один и тот же графический интерфейс должен и красиво выглядеть, и функционально отображаться на различных устройствах: будь то огромный экран монитора компьютера, средний экран планшета или небольшой экран смартфона. Все нужные блоки должны быть видны, все кнопки должны быть доступны к нажатию, а текст должен быть достаточно крупным для комфортного прочтения. Именно с этой целью и используются различные варианты адаптивного интерфейса, который сам подстраивается, или вовсе перестраивает свою структуру, в зависимости от размера экрана текущего пользователя.
Layout №1 - как из колонок сделать строки
Дано:
- три колонки: одна широкая, две узкие
Задача:
При уменьшении ширины экрана - перебрасывать колонки одну над другой, т.е. чтобы вместо колонок получились строки.
Нам понадобится следующий набор блоков:
- wrapper в качестве контейнера
- широкая колонка для контента
- две узкие колонки
Зададим нашу исходную разметку в HTML:
<div class="wrapper">
<div class="content">
<h3>Content</h3>
Lorem ipsum...
</div>
<div class="sidebar-left">
<h3>Left</h3>
Lorem ipsum...
</div>
<div class="sidebar-right">
<h3>Right</h3>
Lorem ipsum...
</div>
</div>
Теперь займемся описанием стилей стандартного отображения. Возьмем за исходные условия - экран монитора.
Пусть контейнер будет немного отступать от краёв экрана, так что зададим ему ширину 80%, отцентруем и сделаем еще небольшой отступ сверху:
.wrapper {
width: 80%;
margin: 0 auto;
padding-top: 20px;
}
Колонка контента будет занимать большую часть экрана и располагаться слева, а также зададим небольшой отступ до следующей колонки:
.content {
width: 54%;
float: left;
margin-right: 3%;
}
Ширину узких колонок зададим как 20%, и укажем плавающее расположение:
.sidebar-left {
width: 20%;
float: left;
margin-right: 3%;
}
.sidebar-right {
width: 20%;
float: left;
}
В результате получим следующий layout:
Теперь потребуется немного уличной магии
Один из главных компонентов адаптивных layout-ов - применение так называемых CSS-медиазапросов. В сети полно информации о том что это и как это, так что не будем сильно останавливаться на этом пункте. Если коротко - используя оператор @media в описании стилей документа, можно указать размер и тип экрана для которого будут применены специфические правила разметки.
Второй не менее важный компонент адаптивной разметки - это то, как применять эту самую @media, для того чтобы изменять структуру layout'а. Вот об этом поговорим поподробней.
Самое важное, что необходимо понимать - @media используется для описания правил разметки, которые будут применены к нашему лейауту только при определенных условиях (например, размер экрана меньше заданного). Если проще - внутри @media описываем то, как должен выглядеть layout, если экран меньше/больше/и пр.
Итак, допустим, нам уже понятно для чего нужна @media, мы понимаем как должен выглядеть интерфейс для маленького экрана, но как сделать из колонок строки? Очень просто - внутри @media переопределяем стили наших блоков таким образом, чтобы убрать разметку колонками, а строками они станут сами собой, т.к. это стандартное отображение блоков.
Укажем максимальный размер экрана, для которого будет применена новая разметка:
@media (max-width: 767px)
Уменьшим боковые отступы у контейнера, всё-таки это разметка для более маленьких экранов и слишком много пустого пространства нам ни к чему:
.wrapper {
width: 90%;
}
Растянем все наши блоки на всю ширину контейнера, теперь всё-таки это будут строки, а не колонки:
.content,
.sidebar-left,
.sidebar-right {
width: 100%;
}
Теперь, важный момент - удаляем плавающее расположение блоков при помощи clear:
.sidebar-left,
.sidebar-right {
clear: both;
}
И добавляем пару новых стилей, которые улучшают восприятие строчного layout'а - отступ сверху и полоска границы:
.sidebar-left,
.sidebar-right {
margin-top: 20px;
border-top: 1px solid #ccc;
}
В результате, для экранов шириной меньше чем 768px layout будет выглядеть следующим образом:
Живой пример
See the Pen Adaptive layout by Alexey Silichenko (@asilichenko) on CodePen.
Layout №2 - как изменить структуру разметки и порядок блоков
Исходный layout выглядит следующим образом:
необходимо сделать его адаптивным |
Опишем разметку также как в предыдущем примере: один контейнер и несколько блоков внутри него:
- заголовок, для элементов управления или дополнительной информации
- название, например, продукта
- изображение
- описание
- футер, для дополнительной иформации
<div class="wrapper">
<div class="header">Header</div>
<div class="title">Lorem ipsum dolor sit amet</div>
<div class="cover"><img ... /></div>
<div class="descr">Lorem ipsum...</div>
<div class="footer">Footer</div>
</div>
Все блоки внутри контейнера расположены на одном уровне - так ими проще управлять, поскольку мы создаем не статический, а динамический layout, без использования javascript.
Как обычно, всё самое интересное - в CSS
Поскольку нам нужно управлять расположением элементов layout'а и по строками, и по столбцам, то укажем браузеру, что наш контейнер представляет собой grid-layout. Нам потребуется две колонки: ширина первой определяется содержимым (картинка), вторая - должна занимать всю оставшуюся ширину, и укажем небольшой отступ между ними:
.wrapper {
display: grid;
grid-template-columns: min-content auto;
grid-gap: 10px;
}
Если всё так и оставить, то все блоки друг за другом паровозиком сформируют сетку 2x3:
это не совсем то, что нам нужно
Поскольку мы работаем с grid-разметкой, то чтобы заставить блок с картинкой занимать всю левую сторону необходимо чтобы в описании его стиля были указаны номера строк (точнее грид-линий), между которыми должен располагаться блок:
.cover {
grid-row-start: 1;
grid-row-end: 6; /* на 1 строку больше - для создания пустоты */
}
Номер завершающей строки нужно указать на 1 больше, для того, чтобы блоки во второй колонке не растягивались, заполняя всю высоту:
Для того, чтобы размерами картинки было удобнее управлять, конкретные размеры в пикселях задаются блоку-контейнеру, а размеры изображения задаются так, чтобы оно заполняло весь контейнер:
.cover {
height: 225px;
width: 165px;
}
.cover img {
width: 100%;
}
Второй этап - layout для среднего размера экрана
Сделаем так, чтобы для экранов планшетов изображение становилось меньше, блоки заголовка и названия выскакивали над всеми остальными блоками и занимали всю ширину экрана, а футер, в свою очередь, должен проваливаться под картинку и описание, и также занимать всю ширину экрана.
Используем уже привычный @media
@media (max-width: 767px)
внутри которого задаем новые размеры изображения:
.cover {
height: 150px;
width: 110px;
}
и указываем, что теперь, оно должно находиться между 3 и 4 строчными грид-линиями:
.cover {
grid-row-start: 3;
grid-row-end: 4;
}
Далее, необходимо указать, что заголовок, название и футер должны занимать всю ширину грида, то есть располагаться между 1й и 3й вертикальными грид-линиями:
.header,
.title,
.footer {
grid-column-start: 1;
grid-column-end: 3;
}
В результате получим следующий layout на экранах шириной до 768px:
Третий этап - layout для небольшого экрана
Думаю, логика действий уже ясна, так что приступим.
На экране смартфона не так чтоб сильно много места, поэтому переведём все блоки в строчный режим, уберём лишние отступы, а к изображению применим плавающий стиль (спойлер: как это сделать - не так очевидно как кажется).
Укажем в новом @media-блоке ограничение по размеру экрана в 500px:
@media (max-width: 500px)
Стоит учитывать, что в данном случае мы переопределяем не только стили по-умолчанию, но и стили, указанные в @media для среднего экрана, т.е. все что задано в @media (max-width: 767px), очевидно будет применяется и для экранов менее 500px. Таким образом, нет необходимости в дублировании.
Сделаем контейнер картинки плавающим и добавим небольшой отступ до текста:
.cover {
float: left;
margin-right: 10px;
}
Но если так и оставить, то ничего не изменится! Как в принципе и должно быть, ведь мы указали корневому контейнеру отображать свое содержимое в виде грида, т.е. только колонки и только строки, и никаких плавающих блоков. Как же быть в таком случае? Очень просто - отменим корневому контейнеру необходимость отображаться гридом - указав, например, значение block (в любом случае, теперь раскладка блоков в виде таблицы нам уже не нужна):
.wrapper {
display: block;
}
При этом, у нас конечно же удалятся и отступы между блоками, т.е. они были заданы для grid-раскладки.
Теперь, удалим все границы внутренних блоков, удалим закругления углов и заливку фона:
.wrapper div {
border: none;
border-radius: 0;
background-color: transparent;
}
но зададим их корневому контейнеру:
.wrapper {
border: 2px solid #f08c00;
border-radius: 5px;
background-color: #ffec99;
}
Фоновую заливку нужно переназначить корневому контейнеру, чтобы уголки были действительно закругленными, и внутри них не проступал прямой угол:
И вуаля, вот наш результат:
Живой пример
See the Pen Adaptive layout v2 by Alexey Silichenko (@asilichenko) on CodePen.
Вместо послесловия
Давно уже большую популярность имеет отображение графического интерфейса с мобильных устройств, и соответственно своего рода золотым правилом стало определение стилей по методике Mobile First. В данной же статье рассмотрено создание layout'a в обратном порядке, но лишь для упрощения понимания процесса. Для ваших проектов, вероятнее всего, более целесообразно - придеживаться методологии Mobile First. В таком случае, пусть формирование Mobile First layout'a будет вам домашним заданием ;-)
Источники
- Основные понятия Grid Layout
- Реализация стандартных лейаутов, используя CSS grid-layout
- Описание и синтаксис @media
- Адаптивная вёрстка: что это и как использовать
- Использование CSS-медиазапросов
No comments:
Post a Comment