Привет, хабр! В один прекрасный вечер, без признаков чего-либо интересного, в наш чат поступило предложение от автора публикации.
«Мы переводим 5 действительно полезных шаблонов адаптивной разметки в код» , написанный им весной 2012 года, написать статью-переделку, но с использованием FlexBox и сопутствующего объяснения, что и как работает. После некоторых сомнений интерес к более глубокому пониманию спецификации всё же победил и я с радостью сел печатать те самые примеры.
По мере погружения в эту область стали проясняться многие нюансы, которые переросли в нечто большее, чем просто редизайн макетов.
В общем, в этой статье я хочу рассказать о такой замечательной спецификации под названием «Модуль CSS Flexible Box Layout» и показать некоторые ее интересные особенности и примеры применения.
Приглашаю всех желающих присоединиться к взлому.
На что хотелось бы обратить внимание, что для создания макета на FlexBox разработчику потребуется определенная степень адаптации.
На своем примере я почувствовал, что многолетний опыт сыграл злую шутку.
FlexBox требует несколько иного подхода к выстраиванию элементов в потоке.
Техническая часть
Прежде чем переходить к каким-либо примерам, стоит понять, какие свойства включены в эту спецификацию и как они работают. Так как некоторые из них изначально не очень понятны, а некоторые окружены мифами, не имеющими ничего общего с реальностью.Так.
Во FlexBox есть два основных типа элементов: Flex Container и его дочерние элементы — Flex Items. Чтобы инициализировать контейнер, просто назначьте элементу через CSS дисплей: гибкий; или дисплей: встроенный гибкий; .
Разница между flex и inline-flex заключается лишь в принципе взаимодействия с элементами, окружающими контейнер, аналогично display:block; и display: inline-block; соответственно.
Внутри гибкого контейнера создаются две оси: главная ось и перпендикулярная или поперечная ось.
Преимущественно гибкие элементы выравниваются по главной оси, а затем по поперечной оси.
По умолчанию главная ось горизонтальна и направлена слева направо, а поперечная ось вертикальна и направлена сверху вниз.
Направление осей можно контролировать с помощью свойства CSS. гибкое направление .
Это свойство принимает несколько значений: ряд (по умолчанию): главная ось гибкого контейнера имеет ту же ориентацию, что и линейная ось текущий режим направления линии .
Начало (main-start) и конец (main-end) направления главной оси соответствуют началу (inline-start) и концу (inline-end) линейной оси.
обратная строка : Все то же самое, что и в ряду, только поменяны местами главное-начало и главное-конец.
столбец : то же, что и row, только теперь главная ось направлена сверху вниз.
обратная колонка : то же, что и row-reverse, только главная ось направлена снизу вверх.
Вы можете увидеть, как это работает, на примере jsfiddle .
По умолчанию все flex-элементы в контейнере размещаются на одной строке, даже если они не помещаются в контейнер, а выходят за его границы.
Это поведение переключается с помощью свойства гибкая упаковка .
Это свойство имеет три состояния: сейчасрап (по умолчанию): гибкие элементы выстраиваются в одну строку слева направо.
сворачивать : гибкие элементы строятся в многолинейном режиме, перенос осуществляется по направлению поперечной оси, сверху вниз.
обратная упаковка : то же, что и обертывание, но обертывание снизу вверх.
Давайте посмотрим пример .
Для удобства имеется дополнительное свойство гибкий поток , в котором можно одновременно указать гибкое направление И гибкая упаковка .
Это выглядит так: гибкий поток: ?Элементы в контейнере можно выровнять с помощью свойства оправдание-содержание вдоль главной оси.
Это свойство принимает до пяти различных значений.
гибкий старт (по умолчанию): элементы Flex выравниваются по началу главной оси.
гибкий конец : элементы выравниваются по концу главной оси центр : Элементы выравниваются по центру главной оси.
пространство-между : элементы занимают всю доступную ширину в контейнере, самые крайние элементы плотно прижимаются к краям контейнера, а свободное пространство между элементами распределяется равномерно.
пространство вокруг : Гибкие элементы выравниваются таким образом, чтобы свободное пространство распределялось между ними равномерно.
Но стоит отметить, что пространство между краем контейнера и внешними элементами будет вдвое меньше, чем пространство между элементами в середине ряда.
Конечно, вы можете нажать на пример того, как работает это свойство.
здесь .
Это еще не все, у нас также есть возможность выравнивать элементы по поперечной оси.
Применяя свойство выравнивание элементов , который также принимает пять разных значений, можно добиться интересного поведения.
Это свойство позволяет выравнивать элементы в строке относительно друг друга.
гибкий старт : все элементы перемещаются в начало строки гибкий конец : элементы перемещаются в конец строки центр : элементы выравниваются по центру строки базовый уровень : элементы выравниваются по базовой линии текста.
потягиваться (по умолчанию): элементы растягиваются на всю строку.
Еще одно свойство, похожее на предыдущее: выравнивание-контент .
Он единственный отвечает за выравнивание целых строк относительно гибкого контейнера.
Это не будет иметь никакого эффекта, если гибкие элементы занимают одну строку.
Свойство принимает шесть различных значений.
гибкий старт : все линии прижаты к началу поперечной оси гибкий конец : все линии прижаты к концу поперечной оси центр : Все линии упаковки выровнены по центру поперечной оси.
пространство-между : строки распределяются от верхнего края к нижнему, оставляя между строками свободное пространство, при этом самые крайние строки прижимаются к краям контейнера.
пространство вокруг : Линии равномерно распределены по контейнеру.
потягиваться (по умолчанию): строки растягиваются, занимая все доступное пространство.
Вы можете попробовать, как работают align-items и align-content в этот пример .
Я специально представил эти два свойства на одном примере, так как они достаточно тесно взаимодействуют, выполняя каждое свою задачу.
Обратите внимание, что происходит, когда элементы размещаются в одной или нескольких строках.
С параметрами гибкого контейнера мы разобрались, осталось разобраться со свойствами гибких элементов.
Первое свойство, с которым мы познакомимся, это заказ .
Это свойство позволяет изменить положение определенного элемента в потоке.
По умолчанию все гибкие элементы имеют порядок: 0; и построены в порядке естественного потока.
В пример вы можете увидеть, как элементы меняются местами, если к ним применены разные значения порядка.
Одним из основных свойств является гибкая основа .
С помощью этого свойства мы можем указать базовую ширину гибкого элемента.
Значение по умолчанию: авто .
Это свойство тесно связано с гибкий рост И гибкая термоусадка , о котором я расскажу чуть позже.
Принимает значение ширины в пикселях, %, em и других единицах измерения.
По сути, это не совсем ширина гибкого элемента, это своего рода отправная точка.
Относительно которого элемент растягивается или сжимается.
В автоматическом режиме элемент получает базовую ширину относительно содержимого внутри него.
гибкий рост на нескольких ресурсах у него совершенно неверное описание.
Там написано, что он якобы задает соотношение размеров элементов в контейнере.
На самом деле это не так.
Это свойство определяет коэффициент увеличения элемента при наличии свободного места в контейнере.
По умолчанию это свойство имеет значение 0. Представим, что у нас есть flex-контейнер шириной 500 пикселей, внутри него находятся два flex-элемента, каждый с базовой шириной 100 пикселей.
Это оставляет еще 300 пикселей свободного места в контейнере.
Если мы укажем flex-grow: 2; для первого элемента и flex-grow: 1; для второго элемента.
В результате эти блоки займут всю доступную ширину контейнера, только ширина первого блока будет 300px, а второго только 200px. Что случилось? Произошло следующее: доступные 300 пикселей свободного пространства в контейнере были распределены между элементами в соотношении 2:1, +200 пикселей для первого и +100 пикселей для второго.
Вот как это работает на самом деле.
Здесь мы плавно переходим к другому аналогичному свойству, а именно гибкая термоусадка .
Значение по умолчанию — 1. Оно также задает коэффициент изменения ширины элементов, только в обратную сторону.
Если контейнер имеет ширину меньше чем сумма базовой ширины элементов, то это свойство вступает в силу.
Например, контейнер имеет ширину 600 пикселей, а flex-basis элементов — 300 пикселей.
Присвойте первому элементу flex-shrink: 2; и второму элементу flex-shrink: 1;.
Теперь давайте уменьшим контейнер на 300 пикселей.
Следовательно, сумма ширин элементов на 300 пикселей больше ширины контейнера.
Эта разница распределяется в соотношении 2:1, получается, что мы отнимаем 200px от первого блока, и 100px от второго.
Новый размер элементов составляет 100 пикселей и 200 пикселей для первого и второго элемента соответственно.
Если мы установим flex-shrink равным 0, мы не позволим элементу сжиматься до размера, меньшего, чем его базовая ширина.
На самом деле это очень упрощенное описание того, как все это работает, чтобы был понятен общий принцип.
Более подробно, если кому интересно, алгоритм описан в спецификации.
Все три свойства можно записать сокращенно с помощью выражения гибкий .
Это выглядит следующим образом: гибкий: ; А еще можно написать еще две сокращенные версии, гибкость: авто; И гибкость: нет; , что значит гибкий: 1 1 авто; И гибкий: 0 0 авто; соответственно.
Последнее свойство гибких элементов сохраняется выровнять-самостоятельно .
Здесь все просто, это то же самое, что align-items для контейнера, который позволяет переопределить выравнивание для конкретного элемента.
Всё, мне это надоело! Приведи примеры!
С технической частью мы разобрались, она оказалась довольно длинной, но вникнуть нужно.Теперь можно перейти к практическому применению.
В ходе разработки этих «пяти действительно полезных шаблонов адаптивного макета» нам пришлось решать типичные ситуации, с которыми разработчики сталкиваются довольно часто.
Благодаря flexbox реализация этих решений становится проще и гибче.
Возьмем тот же 4-й макет, потому что.
в нем самые интересные элементы.
Для начала обозначим основную ширину страницы, выровняем ее по центру и прижмем футер к низу страницы.
Как всегда в общем.
В связи с тем, что мы указали flex-grow:1 для .html { background: #ccc; min-height: 100%; font-family: sans-serif; display: flex; flex-direction: column; } body { margin: 0; padding: 0 15px; display: flex; flex-direction: column; flex: auto; } .
header { width: 100%; max-width: 960px; min-width: 430px; margin: 0 auto 30px; padding: 30px 0 10px; display: flex; flex-wrap: wrap; justify-content: space-between; box-sizing: border-box; } .
main { width: 100%; max-width: 960px; min-width: 430px; margin: auto; flex-grow: 1; box-sizing: border-box; } .
footer { background: #222; width: 100%; max-width: 960px; min-width: 430px; color: #eee; margin: auto; padding: 15px; box-sizing: border-box; }
main; он растягивается на всю доступную высоту, тем самым прижимая нижний колонтитул к низу.
Бонусом этого решения является то, что нижний колонтитул может иметь нефиксированную высоту.
Теперь разместим логотип и меню в шапке.
.
logo { font-size: 0; margin: -10px 10px 10px 0; display: flex; flex: none; align-items: center; } .
logo:before, .
logo:after { content: ''; display: block; } .
logo:before { background: #222; width: 50px; height: 50px; margin: 0 10px 0 20px; border-radius: 50%; } .
logo:after { background: #222; width: 90px; height: 30px; } .
nav { margin: -5px 0 0 -5px; display: flex; flex-wrap: wrap; } .
nav-itm {
background: #222;
width: 130px;
height: 50px;
font-size: 1.5rem;
color: #eee;
text-decoration: none;
margin: 5px 0 0 5px;
display: flex;
justify-content: center;
align-items: center;
}
Поскольку заголовок имеет flex-wrap: wrap; и оправдать-содержание: пространство-между; Логотип и меню разбросаны по разным сторонам шапки, и если для меню недостаточно места, оно элегантно переместится под логотип.
Дальше мы видим большой пост или баннер, сложно сказать, что конкретно, но дело не в этом.
У нас есть изображение справа и текст с заголовком слева.
Лично я придерживаюсь идеи, что любые элементы должны быть максимально гибкими, вне зависимости от того, адаптивный макет или статический.
Итак, в этом посте у нас есть боковая панель, на которой размещено изображение; Строго говоря, мы не можем точно сказать, какая ширина нам нужна, потому что сегодня у нас большая картинка, завтра маленькая, и нам не хочется каждый раз переделывать элемент с нуля.
Это значит, что нам нужно, чтобы боковая панель заняла нужное ей место, а остальное пространство отошло под контент. Давай сделаем это: .
box { font-size: 1.25rem; line-height: 1.5; font-style: italic; margin: 0 0 40px -50px; display: flex; flex-wrap: wrap; justify-content: center; } .
box-base { margin-left: 50px; flex: 1 0 430px; } .
box-side { margin-left: 50px; flex: none; } .
box-img {
max-width: 100%;
height: auto;
}
Как вы можете видеть для .
box-base, где у нас есть заголовок и текст, я указал базовую ширину с помощью гибкая основа: 430 пикселей; , а также запрещена усадка блока с помощью гибкое сжатие: 0; .
С помощью этой манипуляции мы сказали, что контент не может стать шириной менее 430 пикселей.
А в связи с тем, что для .
box я указываю flex-wrap: обертка; в тот момент, когда боковая панель и контент не помещаются в контейнер .
box, боковая панель автоматически попадает под контент. И все это без приложения @ СМИ ! Я думаю, это действительно очень круто.
У нас остался контент в три колонки.
Есть несколько решений этой проблемы, я покажу одно из них; в других планировках есть другой вариант. Давайте создадим контейнер, назовем его .
content и настроим.
.
content {
margin-bottom: 30px;
display: flex;
flex-wrap: wrap;
}
Контейнер имеет три столбца: .
banners, .
posts, .
comments. .
banners { flex: 1 1 200px; } .
posts { margin: 0 0 30px 30px; flex: 1 1 200px; } .
comments {
margin: 0 0 30px 30px;
flex: 1 1 200px;
}
Я задал столбцам базовую ширину 200 пикселей, чтобы столбцы не сужались слишком сильно, но было бы лучше, если бы они перемещались друг под друга по мере необходимости.
По верстке без @media с контентом не обойтись, поэтому еще немного подкорректируем поведение колонок по ширине <800px and <600px. @media screen and (max-width: 800px) {
.
banners { margin-left: -30px; display: flex; flex-basis: 100%; } .
posts { margin-left: 0; } } @media screen and (max-width: 600px) { .
content { display: block; } .
banners { margin: 0; display: block; } .
comments {
margin: 0;
}
}
Вот и вся магия создания макета во FlexBox. Еще одна задача, которая мне понравилась, есть в 5-м макете, конкретно она касается адаптации контента.
Видим, как на десктопном разрешении посты выстраиваются в сетку по три в ряд. Когда ширина области просмотра становится меньше 800 пикселей, сетка превращается в столбец с публикациями, где фотография публикации выстраивается поочередно слева и справа от содержимого публикации.
А если ширина меньше 600 пикселей, фотография поста полностью скрыта.
.
grid { display: flex; flex-wrap: wrap; justify-content: space-between; } .
grid-itm { margin-bottom: 30px; flex-basis: calc(33.33% - 30px * 2/3); display: flex; flex-wrap: wrap; } .
grid-img { margin: 0 auto 20px; flex: 0 1 80%; } .
grid-cont{ flex: 0 1 100%; } .
grid-title { text-align: center; } @media screen and (max-width: 800px) { .
grid-itm { flex-wrap: nowrap; flex-basis: 100%; } .
grid-img { flex: 0 0 auto; } .
grid-itm:nth-child(even) .
grid-img { margin: 0 0 0 30px; order: 2; } .
grid-itm:nth-child(odd) .
grid-img { margin: 0 30px 0 0; } .
grid-cont { flex: 1 1 auto; } .
grid-title { text-align: left; } } @media screen and (max-width: 600px) { .
grid-img {
display: none;
}
}
На самом деле, это лишь малая часть того, что можно реализовать с помощью FlexBox. Спецификация позволяет создавать очень сложные макеты страниц с использованием простого кода.
Некоторые ссылки
Примеры шаблонов можно посмотреть на сайте ссылка на гитхаб .Поглощенные знания отсюда .
Надеюсь, мой пост кому-то поможет и позволит быстро использовать новые технологии в полную силу.
Это все для меня.
Спасибо за внимание! Теги: #css3 #flexbox #адаптивный макет #адаптивный дизайн #разработка сайтов #CSS
-
Trolltech Greenphone (Анонс)
19 Oct, 24 -
Зон-Е-Вег: Солнечная Дорога
19 Oct, 24 -
Литва Также Внедряет Цифровую Демократию
19 Oct, 24