Какие теги использовать в html flexbox. Flexbox: новый принцип CSS верстки макетов. Flexbox готов к использованию
Современный front-end разработчик активно должен уметь применять на практике различные инструменты, позволяющие автоматизировать процесс верстки макетов и программирования клиентской составляющей проекта. Для этого уже существует множество фреймворков, как больших, так и малых, системы сборки, пакетные менеджеры, целая куча пакетов для задач любого уровня, препроцессоры, шаблонизаторы и прочий "сахар", который создан упростить и повысить производительность работы специалиста в данной области.
К сожалению, начинающим фронтам бывает сложно разобраться в изобилии этих инструментов, так как тут нужно постоянно развиваться и знать основы верстки. И многие по этой причине продолжают верстать «по-дедовски», обычный css, с кучей повторяемых селекторов, верстка без понимания принципа различных сеток, дикие головные боли с различного рода центрированием и т.д.
Если раньше, миллион лет назад, верстали на таблицах, а потом перелезли на дивы, то сейчас уже без применения flexbox в сочетании с сетками или же готовым css-фреймворком, чувствую, что даже простая верстка на дивах скоро будет считаться «моветоном». Пока это еще не так, но насколько я наблюдаю (точнее, даже не успеваю наблюдать) за развитием в данной области различных методик и best practices, то скорее всего, такой вариант имеет место быть.
Конечно в этой маленькой заметке, я не смогу рассмотреть все must-have умения хорошего фронта и инструменты для комфортной работы, но некоторые основные принципы, позволяющие оттолкнуться и пойти дальше все же покажу и прокомментирую на примерах.
Верстаем адаптивно
Начнем с адаптивной верстки, так как это очень популярная тема в связи с бурным развитием мобильного трафика. Для того чтобы понимать, как работают различные сетки, а значит и адаптив, посмотрим со стороны на блочные элементы, составляющие разметку страницы и выступающие вместе с этим как контейнеры для других элементов (текст, иконки, картинки и прочее, что может быть размещено по умолчанию или с применением позиционирования). Традиционная верстка на дивах.
Как известно, любой блочный элемент display: block по умолчанию занимает всю доступную ширину экрана, только если мы не определим его ширину явно (либо в px, либо в %) . Но даже если ему будет задана определенная таким образом ширина, то следующий после него блочный элемент будет идти после него с новой строки (этим, кстати и отличается block от inline, который будет следовать друг за другом). Это важный момент, его нужно просто понять, а для того чтобы понять, это дело легко просмотреть в инспекторе любого браузера.
Если же нам надо, чтобы блочные элементы соседствовали друг с другом, то необходимо обтеакание элементов (float), причем нужно задавать ширину блоков в %, чтобы браузер автоматически вычислял ширину в пикселях. Как распространенный пример, это блок контента, а рядом сайдбар. После обтекания элементов, незабываем использовать clearfix, сброс обтекания, чтобы не сломать верстку в дальнейшем.
Самым первым делом мы должны "уведомить" браузер, что хотим использовать адаптивное представление, в соответствии с которым любой браузер будет открывать страницу в этом режиме, делается это вот таким объявлением между тегами head документа:
Meta name="viewport" content="width=device-width, initial-scale=1"
Иными словами, ширина-устройства в масштабе 1:1. И если у вас верстка сделана не адаптивно, то скорее всего будут проблемы при таком отображении в мобильном представлении (скорее всего весь контент сожмется в "гармошку", если логически представить, что может произойти:). Вот с этих пор можно уже говорить о следующем шаге, который есть в любой grid системе или адаптивном фреймворке.
В любой grid системе есть брейкпоинты, точки перехода. Посмотрим на Bootstrap, когда при изменении ширины экрана (мобильный, планшетный вид, и т.д.), происходит проверка элемента, имеющего текущий колоночный класс (к примеру класс десктопа для колонки, в популярном фреймворке Bootstrap, это col-md-{x}, md - десктоп). Классы в свою очередь задают различную ширину в %, равную (100/12) · x, где x - коэффициент ширины, от 1 до 12.
Колоночные классы описывают поведение обтекания элементов: есть класс (в тоже время класс может быть для различных устройств) - обтекание задано, нет - ширина 100% (типично для представления контента на мобильных устройствах). А реализовано это поведение с помощью медиа-запросов, которые понимают все браузеры. Медиа-запрос - в css это понятие означает правило, при выполнении условия которого, подключаются соответствующие стили, например, ширина стала меньше 600px - подключаем новый блок стилей, переопределяющий старый. Например, колоночный класс col-md-{x} подключается по умолчанию от 992px и выше, и отключается до 992px. Но все брейкпоинты бутстраповские по умолчанию можно переопределить своими при компиляции сетки.
Вот и вся простая механика с дивами, которым нужно задать ширину в %, float:left; и очистить обтекание после колонок (в бутстрап колонки оборачиваются во враппер c классом row в этом случае), которые мы выстраиваем в ряд. Все это с легкостью можно реализовать самому и без всякой сетки, когда есть понятие, как это работает, просто в любой сетке прописаны классы и много кода уже написано, вашей задачей остается прописывать классы элементам, вот и все.
Мы же, немного пойдем дальше и рассмотрим еще один вариант. Использование флексбокс, заодно на практике создадим небольшой скелет адаптивной страницы с использованием этой новой технологии верстки. Вообще, грубо говоря, флексы позволяют избавить нас от головной боли типа центрирования, горизонтального и вертикального выравнивания в контейнере. А вкупе с медиа-запросами, имея ввиду описанную механику выше, можно выстроить очень качественный адаптивный шаблон с любым выравниванием, как по вертикали, так и по горизонтали. Играемся, вообщем, как захотим.
Тут хочется отметить, что ширина, заданная в %, как в случае с зоной контента и сайдбаром (шапка и подвал по умолчанию занимают всю ширину, 100%), при резайзинге (или открытии страницы на малом экране) сразу же автоматически пересчитывается. Это, пожалуй главное правило, задавать все в %, все остальное браузер сделает сам.
В дивах у нас пускай будет просто текст пока что, потренируемся выравнивать текст (по горизонтали/вертикали). Еще хорошая практика футер исключать из общего враппера, задавать html и body, height:100%, врапперу: min-height:100%, чтобы футер всегда был прижат к низу страницы.
Я привык использовать scss, приведу листинг кода на нем:
$grey: #808080;
$h: 50px;
html, body {
margin: 0;
height: 100%;
}
body {
font-family: monospace, sans-serif;
text-transform: uppercase;
}
.row {
display: flex;
}
.vertical-center {
align-items: center;
justify-content: center;
}
.wrap {
min-height: 100%;
header, .content, .sidebar {
border: 1px solid $grey;
}
header {
height: $h;
}
.content {
height: 100px;
padding: 15px 15px 0 15px;
border-top-width: 0;
margin-right: 1%;
width: 75%;
}
.sidebar {
height: 120px;
padding: 15px 15px 0 15px;
border-top-width: 0;
width: 25%;
}
}
footer {
height: $h;
border: 1px solid $grey;
}
display: flex; - вкл. flex-контекст; свойство flex-direction: row; - по умолчанию, если не укажем column явно. Это то что нам позволяет делать многие потрясающие вещи. Нe совсем уверен, но вроде пока что это свойство не везде поддерживается caniuse, но пора бы уже выкинуть все эти старые браузеры и установить современные, не так ли? :)
Еще задаем соотношение для ширины контент - сайдбар, 75% : 25%. Тот же самый эффект получился бы, если бы использовали бутстрап. Только с класами col-md-9 для контента ((100/12 · 9)% - ширина в процентах, 75) и col-md-3 для сайдбара ((100/12 · 3)% - ширина в процентах, 25)
Итак, давайте разберемся, что происходит и как работает флексбокс. Самое первое, это нужно задать display:flex тому контейнеру, в котором нам нужно производить центрирование, к примеру. В разметке у меня это шапка, подвал и контейнер, внутри которого контент и сайдбар. Самое простейшее, что эффетивно делает флексбокс здесь, так это просто берет и выравнивает текст, который в шапке и подвале, при помощи класса.vertical-center:
.vertical-center { align-items: center; // выравниваем по центру, по вертикали justify-content: center; // выравниваем по центру, по горизонтали }
В результате, текст выравнен в двух направлениях, в шапке и подвале. Осталась средняя часть, здесь, если бы мы не задали display:flex, то по умолчанию остался бы display:block, что в итоге с блоками контента и сайдбара, получилось вот так:
Т.е. расположение друг под другом. И не имеет значения, что им задана ширина, пришлось бы делать обтекание. Но даже не в этом удобство флексбокса. Не в том чтобы сократить код на одну инструкцию, а в том, что при помощи еще нескольких замечательных свойств, которые мы можем установить флексбоксу, можно центрировать блоки разной ширины в двух направлениях, также как и текст (по центру, по вертикали/горизонтали, в начале, в конце)!
Но перед тем, как перейти к этому главному вопросу, для которого и создавалась эта заметка, давайте немного улучшим наш простой макет в плане адаптивности. Сейчас при ресайзе, контент и сайдбар не складываются друг под друга. Необходимо исправить это, так как, представьте себе, что весь текст при малых разрешениях будет некрасиво «спрессован» в области контента и сайдбара. Я не говорю уже про картинки. Кстати, изображениям, которые будут адаптивными обязательно надо задавать:
img{ display:block; max-width:100%; height:auto; }
Воспользуемся медиа-запросами. Улучшаем наш css, я его переписывать весь не буду, просто оставлю // ... * там где код тот же остался:
// .. $mobileBreak: 479px; html, body { // ... } body { // ... } .row { // ... } .middle { @media (max-width: $mobileBreak) { display: block; } } .vertical-center { // ... } .wrap { // ... header, .content, .sidebar { // ... } header { // ... } .content { // ... @media (max-width: $mobileBreak) { width: auto; margin-right: 0; } } .sidebar { // ... @media (max-width: $mobileBreak) { width: auto; } } } footer { // ... }
Теперь сайдбар сложится под контент на телефонах (<480px):
Работа с выравниваниями
В качестве теста, создадим в блоке контента, несколько шариков с заливкой разными цветами, так чтобы они были выравнены по горизонтали и по вертикали в области контента, для этого добавляем html:
// ... $mobileBreak: 479px; @mixin wh($w, $h) { width: $w; height: $h; } // ... .content { // ... padding-top: 0; .content-inner { height: 100%; justify-content: space-between; align-items: center; .bounce { -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50%; } .red { background: #D9534F; } .green { background: #6AB181; } .blue { background: #2D8CD3; } .wh50 { @include wh(50px, 50px); } .wh60 { @include wh(60px, 60px); } .wh35 { @include wh(35px, 35px); } } @media (max-width: $mobileBreak) { // ... } } // ...
Опять таки, там где знаки, // ... , код остается тот же самый.
Результат:
Как видим, шарики выровнены идеально. При добавлении новых шариков, выравнивание будет происходит также без всяких проблем. Свойство align-items: center; отвечает за выравнивание по вертикали, а justify-content: space-between; равномерно выравнивает по горизонтали.
align-items: flex-start; делает вот так:
По аналогии, после применения align-items: flex-end; шарики оказываются внизу контейнера, а align-items: baseline; делает вот так:
Есть еще свойство align-items: stretch;, оно вроде как вытягивает каждый элемент в высоту, но у меня по быстрому не получилось реализовать, поэтому скрин не покажу.
Это все относится к расположению по горизонтальной оси (по умолчанию). Но если мы сделаем явно column:
.content-inner { flex-direction: column; }
То шарики станут по вертикали! И опять таки, применяя различные свойства align-items, мы будем добиваться всего того, что и при горизонтальном построении шариков, но только уже по вертикали! Еще есть свойство align-self, оно переопределяет свойство align-items для одного какого нибудь шарика, или группы. Вот таким вот способом можно гибко управлять всеми выравниваниями.
В данной краткой заметке мы рассмотрели основы адаптивной верстки, точнее ту механику, что позволяет элементам на странице подстраиваться под различные разрешения, а также посмотрели основы флексбокс верстки. Надеюсь статья будет полезна в первую очередь тем, кто не захочет, к примеру брать весь громадный бутстрап ради одной только сетки, а возьмет и создаст свою, по материалам данного урока.
Ну и в заключение, все таки, флексбокс - это круто, но использовать его еще надо осторожно, если вам нужна поддержка старых версии браузеров.
В этой cтатье мы с Вами продолжим изучать вопросы, касающиеся современной нативной верстки страниц сайта с помощью каскадных таблиц стилей с использованием модели Flexbox .
В предыдущей статье мы научились работать и производить всевозможные настройки флекс контейнеров с использованием современных CSS свойств, но этого недостаточно для того, чтобы решать многие задачи, связанные с версткой сайта.
Сейчас мы рассмотрим методы работы непосредственно с флекс элементами, научимся определять порядок их отображения в контейнере, научимся вертикально выравнивать конкретный флекс элемент, рассмотрим как указать относительную ширина флекс элемента, ширину флекс элемента по умолчанию и еще некоторые необходимые приемы работы с флекс элементами.
Порядок следования элементов
В этом разделе мы с Вами рассмотрим как с использованием Flexbox верстки задать порядок следования элементов внутри родительского элемента, что позволит простым способом решать сложные казалось бы задачи. CSS свойство order позволяет установлить порядок следования флекс элемента в контейнере относительно остальных.
Если элемент не является флекс элементом (не находится внутри родительского элемента, который является блочным, или строчным флекс контейнером), то свойство , и любые свойства, предназначенные для работы с флекс элементами не окажут на такие элементы никакого эффекта.
Обращаю Ваше внимание, что если вы указываете значение свойства для одного флекс элемента в контейнере, то это не будет являться его порядковым номером , а указывает только на "вес" его позиции по отношению к другим элементам. Допускается применение отрицательных значений (значение -1, например, смещает элемент к левому краю родительского контейнера). Значение по умолчанию 0.
Схематичное отображение работы свойства отображено на следующем изображении:
В этом учебнике мы уже неоднократно сталкивались со свойством , благодаря которому, вы можете управлять видимостью элементов по оси z, принцип указания значений свойства аналогичен. Вы можете использовать в своей работе любые значения, которые будут вам интуитивно понятны, например, 100 , 200 , 300 и тому подобные.
Order: -1;
Order: 1;
Order: 2;
В этом примере мы разместили три пять элементов
Перейдем к рассмотрению примера:
В этом примере мы разместили три блочных флекс контейнера, внутри них мы разместили по три элемента
В первом контейнере второй элемент будет увеличен на 2 по отношению к остальным флекс элементам, во втором контейнере на 3, а в третьем уже на четыре . Обратите внимание, как пропорцианально изменятся ширина элементов, не прибегая с нашей стороны к каким-либо расчетам, или использованию дополнительных функций.
В первом контейнере указали для второго флекс элемента размер по умолчанию 100px , во втором контейнере 100px , а в третьем уже 10000px . Обратите внимание, что в третьем контейнере элемент не смотря на его размеры не вызвал переполнение, а подстроился под оставшееся в родительском контейнере пространство.
Значение, определяющее на сколько будет уменьшен блок по отношению к остальным флекс элементам в контейнере (при недостатке свободного пространства) задается по аналогии со свойством , но при этом значением по умолчанию будет 1, а не 0. Отрицательные значения так же не допускаются (не валидны).
Свойство со значением 0 определяет, что элемент не будет сжиматься, сохраняя при этом необходимую ширину элемента! Если вместе с этим значением указано минимальное значение ширины флекс элемента по умолчанию (свойство ), то элемент не сможет уменьшиться меньше этого значения. Используйте эту возможность осмысленно, так как существует вероятность переполнения содержимого флекс контейнера. Этот момент мы рассмотрим в конце статьи
Перейдем к рассмотрению примера:
В этом примере мы разместили три блочных флекс контейнера, внутри них мы разместили по три элемента
Привет, хабр!
Одним прекрасным вечером, не предвещающим ничего интересного, в наш чатик поступило предложение от автора публикации , написанной им весной 2012 года, написать статью-ремейк, но с применением FlexBox и сопутствующим пояснением что и как работает. После некоторой доли сомнений, интерес глубже разобраться в спецификации все таки победил и я благополучно сел верстать те самые примеры. В ходе погружения в эту область стало выясняться множество нюансов, что переросло в нечто большее чем просто переверстать макетики. В общем в данной статье хочу рассказать о такой чудесной спецификации, под названием «CSS Flexible Box Layout Module» и показать некоторые ее интересные особенности и примеры применения. Всех кому интересно, любезно приглашаю под хабракат.
На что хотелось бы обратить внимание, для верстки лейаута на FlexBox, разработчику потребуется некоторая степень адаптации. На собственном примере почувствовал, что многолетний опыт играет злую шутку. FlexBox требует немного другого представления об выстраивании элементов в потоке.
Техническая часть
Прежде чем переходить к каким-то примерам, стоит разобраться какие свойства входят в данную спецификацию и как они работают. Так как некоторые из них не очень понятны изначально, а некоторые окружены мифами, которые к действительности не имеют ни малейшего отношения.Итак. Во FlexBox есть два основных типа элементов: Гибкий Контейнер (Flex Container) и его дочерние элементы - Гибкие Элементы (Flex Item). Для инициализации контейнера достаточно присвоить, через css, элементу display: flex; или display: inline-flex; . Разница между flex и inline-flex заключается лишь в принципе взаимодействия с окружающими контейнер элементами, подобно display: block; и display: inline-block;, соответственно.
Внутри гибкого контейнера создаются две оси, главная ось (main-axis) и перпендикулярная или кросс ось (cross axis). Преимущественно гибкие элементы выстраиваются именно по главной оси, а потом уже по кросс оси. По умолчанию главная ось горизонтальная и имеет направление слева направо, а кросс ось вертикальна и направлена сверху вниз.
Направлением осей можно управлять с помощью css-свойства flex-direction
. Данное свойство принимает ряд значений:
row
(default): Главная ось гибкого контейнера имеет ту же ориентацию, как и инлайн ось текущего режима направления строк . Начало (main-start) и конец (main-end) направления главной оси соответствуют началу (inline-start) и концу (inline-end) инлайн оси (inline-axis).
row-reverse
: Все то же самое, что и в row только main-start и main-end меняются местами.
column
: так же само как и row, только теперь главная ось направлена сверху вниз.
column-reverse
: так же само как row-reverse, только главная ось направлена снизу вверх.
Как это работает можно посмотреть в примере на jsfiddle .
По умолчанию все гибкие элементы в контейнере укладываются в одну строку, даже если не помещаются в контейнер, они выходят за его границы. Данное поведение переключается с помощью свойства flex-wrap
. У этого свойства есть три состояния:
nowrap
(default): гибкие элементы выстраиваются в одну строку слева направо.
wrap
: гибкие элементы строятся в многострочном режиме, перенос осуществляется по направлению кросс оси, сверху вниз.
wrap-reverse
: так же как и wrap, но перенос происходит снизу вверх.
Смотрим пример .
Для удобства есть дополнительное свойство flex-flow
, в котором можно одновременно указать flex-direction
и flex-wrap
. Выглядит это следующим образом: flex-flow:
Элементы в контейнере поддаются выравниванию при помощи свойства justify-content
вдоль главной оси. Это свойство принимает целых пять разных вариантов значений.
flex-start
(default): гибкие элементы выравниваются по началу главной оси.
flex-end
: элементы выравниваются по концу главной оси
center
: элементы выравниваются по центру главной оси
space-between
: элементы занимают всю доступную ширину в контейнере, крайние элементы вплотную прижимаются к краям контейнера, а свободное пространство равномерно распределяется между элементами.
space-around
: гибкие элементы выравниваются таким образом, что свободное пространство равномерно распределяется между элементами. Но стоит отметить, что пространство межу краем контейнера и крайними элементами будет в два раза меньше чем пространство между элементами в середине ряда.
Конечно же поклацать пример работы этого свойства можно .
Это еще не все, мы так же имеем возможность выравнивания элементов по кросс оси. Применив свойство align-items
, которое принимает также пять разных значений, можно добиться интересного поведения. Это свойство позволяет выравнивать элементы в строке относительно друг друга.
flex-start
: все элементы прижимаются к началу строки
flex-end
: элементы прижимаются к концу строки
center
: элементы выравниваются по центру строки
baseline
: элементы выравниваются по базовой линии текста
stretch
(default): элементы растягиваются заполняя полностью строку.
Еще одно похожее свойство на предыдущее это align-content
. Только оно отвечает за выравнивание целых строк относительно гибкого контейнера. Оно не будет давать эффекта если гибкие элементы занимают одну строку. Свойство принимает шесть разных значений.
flex-start
: все линии прижимаются к началу кросс-оси
flex-end
: все линии прижимаются к концу кросс-оси
center
: Все линии паком выравниваются по центру кросс оси
space-between
: линии распределяются от верхнего края до нижнего оставляя свободное пространство между строками, крайние же строки прижимаются к краям контейнера.
space-around
: линии равномерно распределяются по контейнеру.
stretch
(default): линии растягиваются занимая все доступное пространство.
Попробовать как работают align-items и align-content можно в этом примере . Я специально два этих свойства представил в одном примере, так как они довольно плотно взаимодействуют каждый выполняя свою задачу. Обратите внимание что происходит когда элементы помещаются в одну строку и в несколько.
С параметрами гибкого контейнера разобрались, осталось разобраться со свойствами гибких элементов.
Первое свойство с которым мы познакомимся это order
. Это свойство позволяет менять позицию в потоке конкретному элементу. По умолчанию все гибкие элементы имеют order: 0;
и строятся в порядке естественного потока. В примере можно увидеть как меняются местами элементы если к ним применять разные значения order.
Одно из основных свойств является flex-basis . С помощью этого свойства мы можем указывать базовую ширину гибкого элемента. По умолчанию имеет значение auto . Это свойство тесно связано с flex-grow и flex-shrink , о которых я расскажу чуть позже. Принимает значение ширины в px, %, em и остальных единицах. По сути это не строго ширина гибкого элемента, это своего рода отправная точка. Относительно которой происходит растягивание или усадка элемента. В режиме auto элемент получает базовую ширину относительно контента внутри него.
flex-grow на нескольких ресурсах имеет совершенно некорректное описание. Там говорится о том, что якобы оно задает соотношение размеров элементов в контейнере. На самом деле это не так. Это свойство задает фактор увеличения элемента при наличии свободного места в контейнере. По умолчанию это свойство имеет значение 0. Давайте представим, что у нас есть гибкий контейнер, который имеет ширину 500px, внутри него есть два гибких элемента, каждый из которых имеет базовую ширину 100px. Тем самым в контейнере остается еще 300px свободного места. Если первому элементу укажем flex-grow: 2;, а второму элементу укажем flex-grow: 1;. В результате эти блоки займут всю доступную ширину контейнера, только ширина первого блока будет 300px, а второго только 200px. Что же произошло? А произошло вот что, доступные 300px свободного места в контейнере распределились между элементами в соотношении 2:1, +200px первому и +100px второму. Собственно так это и работает.
Тут мы плавно переходим к другому аналогичному свойству, а именно flex-shrink . По умолчанию имеет значение 1. Оно так же задает фактор на изменение ширины элементов, только в обратную сторону. Если контейнер имеет ширину меньше чем сумма базовой ширины элементов, то начинает действовать это свойство. Например контейнер имеет ширину 600px, а flex-basis элементов по 300px. Первому элементу укажем flex-shrink: 2;, а второму flex-shrink: 1;. Теперь сожмем контейнер на 300px. Следовательно сумма ширины элементов на 300px больше чем контейнер. Эта разница распределяется в соотношении 2:1, получается от первого блока отнимаем 200px, а от второго 100px. Новый размер элементов получается 100px и 200px, у первого и второго элемента, соответственно. Если мы устанавливаем flex-shrink в значение 0, то мы запрещаем сжиматься элементу до размеров меньше чем его базовая ширина.
На самом деле это очень упрощенное описание того как это все работает, дабы было понятен общий принцип. Более подробно, если кому интересно, алгоритм описан в спецификации.
Все три свойства можно записать в сокращенной форме при помощи выражения flex
. Это имеет следующий вид:
flex:
А так же мы можем писать еще два сокращенных варианта, flex: auto;
и flex: none;
, что означает flex: 1 1 auto;
и flex: 0 0 auto;
соответственно.
Последним свойством гибких элементов остался align-self . Тут все просто, это то же самое, что align-items у контейнера, позволяющее переопределять выравнивание для конкретно взятого элемента.
Все, надоел! Примеры давай!
С технической частью разобрались, получилось довольно затянуто, но в это нужно вникнуть. Теперь можно перейти к практическому применению.В ходе верстки тех самых «пяти действительно полезных шаблонов адаптивной разметки», пришлось решать типичные ситуации, с которыми разработчик сталкивается довольно часто. С flexbox реализация этих решений становится проще и гибче.
Возьмем все тот же 4-ый макет, т.к. в нем больше всего интересных элементов.
Для начала обозначим основную ширину страницы, выровняем по центру, прижмем футер к низу страницы. Как всегда в общем.
Html { background: #ccc; min-height: 100%; font-family: sans-serif; display: -webkit-flex; display: flex; flex-direction: column; } body { margin: 0; padding: 0 15px; display: -webkit-flex; 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: -webkit-flex; 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 указали flex-grow: 1; он растягивается на всю доступную высоту, тем самым прижимая футер к низу. Бонусом в этом решении является, то что футер может быть нефиксированной высоты.
Разместим теперь логотип и меню в хедере.
.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: -webkit-flex;
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: -webkit-flex;
display: flex;
justify-content: center;
align-items: center;
}
Поскольку для хедера указано flex-wrap: wrap; и justify-content: space-between; логотип и меню раскидывает по разным сторонам хедера, при этом если места для меню будет не хватать оно элегантно сместится под логотип.
Далее мы видим большой пост или баннер, затрудняюсь сказать что это конкретно, но и не суть. У нас есть картинка справа и текст с заголовком слева. Я лично придерживаюсь идеи, что любые элементы должны быть максимально гибкими, независимо от того адаптиваная это верстка или статика. Итак у нас есть в этом посте сайд-бар в котором размещена картинка, строго говоря мы не можем точно сказать какая ширина нам нужна, ибо сегодня у нас большая картинка, завтра маленькая и каждый раз переделывать элемент с нуля неохота. Значит нам нужно, чтобы сайд-бар занял нужное ему место, а остальное место пошло на контент. Так и сделаем:
Box { font-size: 1.25rem; line-height: 1.5; font-style: italic; margin: 0 0 40px -50px; display: -webkit-flex; 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, там где у нас заголовок и текст, я указал базовую ширину посредством flex-basis: 430px; , а так же запретил усадку блока при помощи flex-shrink: 0; . Этой манипуляцией мы сказали, что контент не может стать меньше чем 430px в ширину. А ввиду того что для.box я указываю flex-wrap: wrap; в тот момент, когда сайд-бар и контент не будут помещаться в контейнер.box, сайд-бар автоматически провалится под контент. И это все без применения @ media ! Я считаю это действительно очень круто.
У нас остался трехколоночный контент. Решений подобной задачи несколько, я покажу один из них, в остальных макетах есть и другой вариант.
Создаем контейнер, назовем его.content и настроим.
.content {
margin-bottom: 30px;
display: -webkit-flex;
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;
}
Задал колонкам базовую ширину 200px, чтобы колонки не сужались прям слишком сильно, пускай лучше они по мере надобности переносятся друг под друга.
По макету, нам с контентом, обойтись без @ media не получится, поэтому еще немного настроим поведение колонок для ширины <800px и <600px.
@media screen and (max-width: 800px) {
.banners {
margin-left: -30px;
display: -webkit-flex;
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-ом макете, конкретно это касается адаптации контента.
Мы видим, как на десктопном разрешении посты построены в сетку по три штуки в ряд. Когда ширина viewport становится меньше 800px, то сетка превращается в колонку с постами, где фото поста выстраивается с левой и правой стороны от контента поста, поочередно. А при ширине меньше 600px фото поста прячется вовсе.
.grid {
display: -webkit-flex;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.grid-itm {
margin-bottom: 30px;
flex-basis: calc(33.33% - 30px * 2/3);
display: -webkit-flex;
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. Спецификация позволяет строить весьма сложные макеты страниц при этом применяя простой код.
О том, как просто работать с Flexbox на примере верстки шаблона новостного сайта.
Поверьте, нет никакой необходимости в детальном разборе всех аспектов работы с Flexbox, если вы хотите начать им пользоваться уже сейчас. В этом руководстве автор собирается познакомить вас с некоторыми свойствами Flexbox и сделать «новостной лейаут» наподобие того, который вы могли видеть на сайте The Guardian .
Причина, по которой автор использует Flexbox – это большое количество возможностей, которые он предоставляет:
- легкость в создании адаптивных столбцов;
- создание столбцов одинаковой высоты;
- возможность прижатия содержимого к низу контейнера.
Ну, поехали!
1. Начинаем с создания двух столбцов
Создание столбцов при помощи CSS всегда влекло за собой определенные трудности. На протяжении длительного времени для выполнения данной задачи широко использовались (и используются) float’ы и / или таблицы, но каждый из этих методов имел (и имеет) свои недостатки.В свою очередь, Flexbox упрощает этот процесс, обладая рядом таких преимуществ, как:
Написание более «чистого» кода: от нас лишь требуется создать контейнер с правилом display: flex;
- гибкость: мы можем изменять размер, растягивать и выравнивать столбцы путем изменения пары строк CSS;
- семантическая разметка;
- кроме того, с использованием Flexbox отпадает необходимость отменять обтекание во избежание непредсказуемого поведения лейаута.
Давайте начнем работу с создания двух столбцов, один из которых будет занимать 2/3 ширины нашего контейнера, а еще один - 1/3 его часть.
Здесь присутствуют два элемента:
Контейнер columns;
- два дочерних элемента column
, один из которых имеет дополнительный класс main-column
, который мы используем позже для того, чтобы сделать столбец шире.
Columns {
display: flex;
}
.column {
flex: 1;
}
.main-column {
flex: 2;
}
Поскольку main-column
имеет значение flex равное 2
, то этот столбец займет в два раза больше места, чем второй.
Добавим немного визуального оформления и, в итоге, получим:
Кликните для просмотра в действии
2. Делаем каждый столбец flexbox-контейнером
Каждый из двух столбцов будет содержать несколько вертикально расположенных статей, поэтому из этих двух элементов мы, в свою очередь, также должны сделать flexbox-контейнеры.Итак, нам необходимо, чтобы статьи:
Располагались вертикально внутри столбца-контейнера;
- занимали все доступное место.
Правило flex-direction: column , указанное для контейнера, вместе с правилом flex: 1 , указанным для дочернего элемента, позволяет статье заполнить все свободное место по вертикали, при этом высота первых двух столбцов останется неизменной.
Кликните для просмотра в действии
3. Делаем контейнер из статьи
Теперь, чтобы еще больше расширить наши возможности, давайте представим каждую статью в виде flexbox-контейнера. Каждый такой контейнер будет содержать:Заголовок;
- параграф;
- информационную панель с именем автора и количеством комментариев;
- какую-нибудь адаптивную картинку.
Здесь мы используем Flexbox для того, чтобы «прижать» информационную панель к низу элемента. Вот, посмотрите, какой результат мы ожидаем получить.
А вот и сам код:
.article {
display: flex;
flex-direction: column;
flex-basis: auto; /* Устанавливает начальный размер элемента в зависимости от его содержимого */
}
.article-body {
display: flex;
flex: 1;
flex-direction: column;
}
.article-content {
flex: 1; /* Содержимое заполняет все оставшееся место, тем самым прижимая информационную панель к нижней части */
}
Элементы внутри статьи расположены вертикально благодаря использованию правила flex-direction: column
.
Также мы применили свойство flex: 1 к элементу article-content , тем самым растянув его на все свободное место и прижав article-info к низу. Высота столбцов в этом случае не имеет значения.
Кликните для просмотра в действии
4. Добавляем несколько вложенных столбцов
На самом деле, нам нужно, чтобы левый столбец включал в себя еще несколько столбцов. Поэтому нам необходимо заменить второй элемент, отвечающий за статью, контейнером columns , который мы использовали ранее.
Поскольку мы хотим, чтобы первый вложенный столбец был шире, добавим к элементу класс nested-column , а в CSS укажем:
Nested-column {
flex: 2;
}
Теперь этот столбец будет вдвое шире второго.
Кликните для просмотра в действии
5. Делаем первую статью с горизонтальным лейаутом
Первая статья у нас на самом деле большая. Дабы эффективно использовать место на экране монитора, давайте изменим ее ориентацию на горизонтальную.First-article {
flex-direction: row;
}
.first-article .article-body {
flex: 1;
}
.first-article .article-image {
height: 300px;
order: 2;
padding-top: 0;
width: 400px;
}
Свойство order
в данном случае играет большую роль, поскольку оно позволяет изменять очередность HTML-элементов без изменения HTML-разметки. В действительности, article-image
в коде идет перед элементом article-body
, но ведет себя так, будто стоит после него.
Кликните для просмотра в действии
6. Делаем адаптивный лейаут
Теперь все выглядит так, как мы хотели, хотя и немного сплющено. Давайте исправим это, добавив нашему лейауту гибкости.Одной из замечательных вещей в Flexbox является то, что достаточно удалить правило display: flex в контейнере для того, чтобы полостью отключить его (Flexbox), в то время, как остальные его свойства (такие, как align-items или flex ) останутся рабочими.
В результате, мы можем активировать адаптивный лейаут, задействовав Flexbox только тогда, когда в этом будет необходимость.
Итак, мы собираемся удалить display: flex из селекторов .columns и .column , вместо этого «запаковав» их в медиа-запрос:
@media screen and (min-width: 800px) {
.columns,
.column {
display: flex;
}
}
Вот и все! На экранах с маленьким разрешением все статьи будут располагаться друг над другом, а на экранах с разрешением свыше 800 пикселей - в два столбца.
7. Добавляем завершающие штрихи
Для того, чтобы лейаут выглядел более привлекательно на больших экранах, давайте добавим кое-какие CSS-твики: @media screen and (min-width: 1000px) {
.first-article {
flex-direction: row;
}
.first-article .article-body {
flex: 1;
}
.first-article .article-image {
height: 300px;
order: 2;
padding-top: 0;
width: 400px;
}
.main-column {
flex: 3;
}
.nested-column {
flex: 2;
}
}
Содержимое первой статьи выровнено по горизонтали: текст расположен по левой стороне, а картинка - по правой. Также, главный столбец теперь стал шире (75%). То же самое касается и вложенного столбца (66%).
А вот и финальный результат!
Кликните для просмотра в действии
Вывод
Теперь вы и сами видите, что использовать Flexbox в своих проектах можно даже не вникая во все его тонкости, и созданный лейаут - наглядный тому пример. По крайней мере, автор очень надеется на это.Я хотел бы рассказать о FlexBox. Модуль Flexbox-верстки (flexible box — «гибкий блок», на данный момент W3C Candidate Recommendation) ставит задачу предложить более эффективный способ верстки, выравнивания и распределения свободного места между элементами в контейнере, даже когда их размер неизвестен и / или динамический (отсюда слово «гибкий»).
Главная задумка flex-верстки в наделении контейнера способностью изменять ширину / высоту (и порядок) своих элементов для лучшего заполнения пространства (в большинстве случаев — для поддержки всех видов дисплеев и размеров экранов). Flex-контейнер растягивает элементы для заполнения свободного места или сжимает их, чтобы предотвратить выход за границы.
Самое важное, flexbox-верстка не зависит от направления в отличие от обычных лейаутов (блоки, располагаются вертикально, и инлайн-элементы, расположенные горизонтально). В то время, как обычный лэйаута отлично подходит для веб-страниц, ему не хватает гибкости для поддержки крупных или сложных приложений (особенно когда дело доходит до изменения ориентации экрана, изменения размера, растяжения, сжатия и т.п.) .
Т.к. flexbox — это целый модуль, а не просто единичное свойство, он объединяет в себе множество свойств. Некоторые из них должны применяться к контейнеру (родительского элемента, так называемом flex-контейнера), в то время как другие свойства применяются к дочерним элементам, или flex-элементам.
Если обычный макет основывается на направлениях потоков блочных и инлайн-элементов, то flex-макет основывается на «направлениях flex-потока».
Flexbox
В основном элементы будут распределяться или вдоль главной оси (от main-start в main-end), или вдоль поперечной оси (от cross-start в cross-end).
main-axis — главная ось, вдоль которого располагаются flex-элементы.
Обратите внимание, она обязательно должна быть горизонтальной, все зависит от качества justify-content.
main-start |
main-end — flex-элементы размещаются в контейнере от позиции main-start позиции main-end.
main size — ширина или высота flex-элемента в зависимости от выбранной основной величины.
Основная величина может быть либо шириной, или высотой элемента.
cross axis — поперечная ось, перпендикулярная главной.
Ее направление зависит о тнаправления главной оси.
cross-start |
cross-end — flex-строки заполняются элементами и размещаются в контейнере от позиции cross-start и позиции cross-end.
cross size — ширина или высота flex-элемента в зависимости от выбранной размерности равна этой величине.
Это свойство совпадает с width или height элемента в зависимости от выбранной размерности.
Свойства
display: flex |
inline-flex;
Определяет flex-контейнер (инлайновий или блочный зависимости от выбранного значения), подключает flex-контекст для всех его непосредственных потомков.
display: other values | flex | inline-flex;
Имейте в виду:
CSS-столбце columns не работают с flex-контейнером float, clear и vertical-align не работают с flex-элементами
flex-direction
Применяется до родительского элемента flex-контейнера.
Устанавливает главную ось main-axis, определяя тем самым направление для flex-элементов, размещаемых в контейнере.
flex-direction: row | row-reverse | column | column-reverse
row (по умолчанию): слева направо для ltr, справа налево для rtl;
row-reverse: справа налево для ltr, слева направо для rtl;
column: аналогично row, сверху вниз;
column-reverse: аналогично row-reverse, снизу вверх.
flex-wrap
Применяется до родительского элемента flex-контейнера.
Определяет, контейнер однострочными или многострочным, а также направление поперечной оси, определяет направление, в котором будут располагаться новые строки.
flex-wrap: nowrap | wrap | wrap-reverse
nowrap (по умолчанию): однострочный / слева направо для ltr, справа налево для rtl;
wrap: многострочный / слева направо для ltr, справа налево для rtl;
wrap-reverse: многострочный / справа налево для ltr, слева направо для rtl.
flex-flow
Применяется до родительского элемента flex-контейнера.
Это сокращение для свойств flex-direction и flex-wrap, вместе определяют главную и поперечную оси. По умолчанию принимает значение row nowrap.
flex-flow < ‘flex-direction’> || < ‘Flex-wrap’>
justify-content
Применяется до родительского элемента flex-контейнера.
Определяет выравнивание относительно главной оси. Помогает распределить свободное место в случае, когда элементы строки не «тянутся», или тянутся, но уже достигли своего максимального размера. Также позволяет в некотором роде управлять выравниванием элементов при выходе за пределы строки.
justify-content: flex-start | flex-end | center | space-between | space-around
flex-start (по умолчанию): элементы сдвигаются к началу строки;
flex-end: элементы сдвигаются до конца строки;
center: элементы выравниваются на середину строки;
space-between: элементы распределяются равномерно (первый элемент в начале строки, последний — в конце)
space-around: элементы распределяются равномерно с равным расстоянием между собой и вне строки.
justify-content
align-items
Применяется до родительского элемента flex-контейнера.
Определяет поведение по умолчанию для того, как flex-элементы располагаются относительно поперечной оси на текущей строке. Считайте это версии justify-content для поперечной оси (перпендикулярной к основной).
align-items: flex-start | flex-end | center | baseline | stretch
flex-start: граница cross-start для элементов расположен позиции cross-start;
flex-end: граница cross-end для элементов расположен позиции cross-end;
center: элементы выравниваются по центру поперечной оси;
baseline: элементы выравниваются по своей базовой линии;
stretch (по умолчанию): элементы растягиваютcя, заполняя контейнер (с учетом min-width / max-width).
align-items
align-content
Применяется до родительского элемента flex-контейнера. Выравнивает строки flex-контейнера при наличии свободного места на поперечной оси аналогично тому, как это делает justify-content на главной оси. Примечание: это свойство не работает с однострочными flexbox.
align-content: flex-start | flex-end | center | space-between | space-around | stretch
flex-start: строки выравниваются относительно начала контейнера;
flex-end: строки выравниваются относительно конца контейнера;
center: строки выравниваются по центру контейнера;
space-between: строки распределяются равномерно (первая строка в начале строки, последняя — в конце)
space-around: строки распределяются равномерно с равным расстоянием между собой;
stretch (по умолчанию): строки растягиваются, заполняя свободное пространство.
align-content
order
По умолчанию flex-элементы располагаются в исходном порядке. Тем не менее, свойство order может управлять порядком их расположения в контейнере.
order 1
flex-grow
Применяется до дочернему элементу / flex-элемента. Определяет для flex-элемента возможность «расти» при необходимости. Принимает безразмерное значение, служит в качестве пропорции. Оно определяет, какую долю свободного места внутри контейнера элемент может занять. Если во всех элементов свойство flex-grow задано как 1, то каждый потомок получит внутри контейнера одинаковый размер. Если вы задали одному из потомков значение 2, то он займет в два раза больше места, чем другие.
flex-grow
flex-shrink
Применяется до дочернему элементу / flex-элемента.
Определяет для flex-элемента возможность сжиматься при необходимости.
flex-shrink
Отрицательные числа не принимаются.
flex-basis
Применяется до дочернему элементу / flex-элемента. Определяет размер по умолчанию для элемента перед распределением пространства в контейнере.
flex-basis
flex
Применяется до дочернему элементу / flex-элемента. Это сокращение для flex-grow, flex-shrink и flex-basis. Второй и третий параметры (flex-shrink, flex-basis) необязательны. Значение по умолчанию — 0 1 auto.
flex: none | [< ‘Flex-grow «> <» flex-shrink’>? || < ‘Flex-basis’>]
align-self
Применяется до дочернему элементу / flex-элемента. Позволяет переопределить выравнивания, заданный по умолчанию или в align-items, для отдельных flex-элементов. Обратитесь к описанию свойства align-items для лучшего понимания доступных значений.
align-self: auto | flex-start | flex-end | center | baseline | stretch
Примеры
Начнем с очень-очень простого примера, встречается практически ежедневно: выравнивание точно по центру.
Нет ничего проще, если использовать flexbox.
Parent { display: flex; height: 300px; } .child { width: 100px; / * Або що завгодно * / height: 100px; / * Або що завгодно * / margin: auto; / * Магія! * / }
Этот пример основывается на том, что margin под flex-контейнере, заданный как auto, поглощает лишнее пространство, поэтому задача отступления таким образом выровняет элемент ровно по центру по обеим осям.Теперь давайте используем какие-то свойства. Представьте набор из 6 элементов фиксированного размера (для красоты), но с возможностью изменения размера контейнера. Мы хотим равномерно распределить их по горизонтали, чтобы при изменении размера окна браузера все выглядело хорошо (без @media-запросов!).
Flex-container {
/ * Сначала создадим flex-контекст * /
display: flex;
/ * Теперь определим направление потока и хотим ли мы, чтобы элементы
переносились на новую строку
* Помните, что это тоже самое, что и:
* Flex-direction: row;
* Flex-wrap: wrap;
* /
flex-flow: row wrap;
/ * Теперь определим, как будет распределяться пространство * /
}
Готово. Все остальное — уже дело оформления. Давайте попробуем что-нибудь еще. Представьте, что нам нужна выровнена по правому краю навигация в самом верху нашего сайта, но мы хотим, чтобы она выравнивалась по центру для экранов среднего размера и превращалась в один столбец на маленьких. Все достаточно просто.
/ * Большие экраны * /
.navigation {
display: flex;
flex-flow: row wrap;
/ * Сдвигает элементы к концу строки по главной оси * /
justify-content: flex-end;
}
media all and (max-width: 800px) {
.navigation {
/ * Для экранов среднего размера мы выравниваем навигацию по центру,
равномерно распредляя свободное место между элементами * /
justify-content: space-around;
}
}
/ * Маленькие экраны * /
media all and (max-width: 500px) {
.navigation {
/ * На маленьких экранах вместо строки мы располагаем элементы в столбце * /
flex-direction: column;
}
}
Давайте поиграем с гибкостью flex-элементов! Как насчет ориентированного на мобильные устройства трёхколоночного макета с полноширинной шапкой и подвалом? И другим порядком расположения.
Wrapper {
display: flex;
flex-flow: row wrap;
}
/ * Задаем всем Элеметы ширину в 100% * /
.header, .main, .nav, .aside, .footer {
flex 1100%;
}
/ * В этом случае мы полагаемся на исходный порядок для ориентации на
* Мобильные устройства:
* 1 header
* 2 nav
* 3 main
* 4 aside
* 5 footer
* /
/ * Экраны среднего размера * /
media all and (min-width: 600px) {
/ * Оба сайдбара располагаются в одной строке * /
.aside {flex: 1 auto;
}
}
/ * Большие экраны * /