Строим с flexbox
В данной обучающей статье мы разберем некоторые реальные и некогда действительно трудновыполнимые моменты, которые сейчас легко решаются благодаря использованию flexbox.
Некоторое время назад я написал ознакомительную статью про flexbox на сайте SitePoint. В данной статье я постарался выяснить и ответить на вопрос:
В прошлый раз я говорил, что вам следует очень аккуратно использовать данную возможность, но настаивал на том, что нужно обязательно познакомиться с ее синтаксисом и внедрять ее в современные проекты. Сейчас я рад, что могу дать положительный ответ на свой вопрос:
Если вы еще не знакомы с flexbox, то вот небольшое пояснение. CSS модуль построения гибкой разметки — это модуль, позволяющий легко размещать блоки на экране, в пределах выделенного пространства. Это большое достижение по сравнению с классической блочной моделью, т.к. flexbox позволяет вообще не использовать свойство float. Блоки могут быть объединены в строки или разбиты на колонки. Для каждого flexbox-элемента может быть задан определенный порядок. А также можно сразу управлять выравниванием, отступами и размерами этих элементов.
Пожалуй, что в данной статье мне не удастся рассмотреть каждый аспект данного модуля, поэтому я предлагаю вам познакомиться с ним поподробнее, перейдя на сайт MDN. А в данной обучающей статье мы рассмотрим распространенные проблемы с разметкой и увидим, как легко и быстро их можно решить. Каждый шаблон разметки, о котором я расскажу, будет отзывчивым, что еще больше подчеркнет ту легкость, с которой можно создавать разметку с помощью flexbox. Вот что мы рассмотрим:
Хорошо, давайте приступать!
Сегодня сеточные системы присутствуют в большинстве разметок проектов, и классическое поведение блочной модели в CSS вынудило нас прибегнуть к использованию плавающих или inline-block элементов, каждый из которых имеет собственные недостатки. Flexbox позволяет нам легко создавать действительно классную и масштабируемую сеточную систему благодаря написанию всего нескольких строчек в CSS. Давайте рассмотрим это поподробнее.
Представьте, что у нас есть следующая простая разметка:
При традиционном подходе создания сетки нам бы пришлось каким-то образом определить, сколько элементов может помещаться в одну строку, а затем установить ширину для каждого элемента сетки. А с помощью flexbox мы можем добавлять в строку столько элементов, сколько захотим, и их ширина сама будет подстраиваться под общую ширину строки. Другими словами, у нас может быть следующая разметка, и при этом нам не нужно волноваться об указании количества элементов в каждой строке в CSS:
А теперь давайте посмотрим на CSS код. Некоторые свойства я использовал чисто в эстетических целях (например, рамки и внутренние отступы), а в остальном все очень просто:
Вот как-то так! И наша сетка уже готова к использованию. Добавляя display: flex к контейнерам .grid__row, мы создаем, так называемый, flex-контейнер, а каждый дочерний элемент в контейнере сразу становится flex-элементом. Применяя свойство flex: 1 к flex-элементам, мы заставляем их занимать равное количество места относительно общей ширины контейнера. Теперь у вас может быть сколько угодно строк в сетке, а в каждой из них может быть свое собственное количество элементов. И это будет простая полностью отзывчивая сеточная система без всякого дополнительного CSS.
А что можно сказать насчет breakpoint-ов и колоночной разметки? Если мы хотим, чтобы элементы сетки выстраивались в колонки, а не в строки, то мы можем просто объявить свойство flex-direction: column для контейнеров с классом .grid__row. В этом случае мы можем создать очень простую отзывчивую сетку, внеся некоторые изменения. И наша разметка будет выглядеть вот так:
А наш CSS вот так:
И вуа-ля. Супер-простая отзывчивая сеточная система размером всего в несколько CSS строк. Эта система настолько непробиваемая, что вы даже можете вкладывать сетки друг в друга, не заботясь о последствиях:
Посмотрите на это в действии.
Разметка трехколоночного сайта является довольно известной в веб-дизайне, и даже в эпоху веб-приложений и прочего веселья, данный вариант разметки по-прежнему играет важную роль в вебе — такая разметка постоянно используется на сайтах, у которых много контента. Еще в 2006 году трехколоночная разметка была замечательно разобрана и описана на сайте A List Apart. В ней используются float элементы, отрицательные margin и значения min-width, чтобы совмещенные размеры элементов не конфликтовали друг с другом и не ломали разметку. И все это, с учетом нынешней необходимости в создании отзывчивой разметки, означало использование большого количества вычислений, отмены обтекания и других трюков, чтобы это все работало правильно. И если вы решили поменять ширину боковой колонки, то нужно было заново производить все вычисления.
Flexbox позволяет избавиться от существенной головной боли, т.к. мы можем определить колоночную или строчную разметку, а также явно указать порядок следования элементов в CSS, даже если они расположены в другом порядке в нашей разметке. Вот типичный пример создания трехколоночной разметки:
В моем демо-примере разметка находится внутри документа, поэтому в ней нет тегов body или main, как это показано выше. Но в данном случае, нас интересуют имена классов и сами разделы нашей разметки, а не непосредственно сами элементы. В частности, обратите внимание на классы, которые используются для двух боковых колонок, и на тот порядок, в котором они следуют в разметке. Давайте последовательно рассмотрим, что здесь происходит:
Учитывая все вышесказанное, давайте построим разметку:
Это действительно настолько просто! Как я уже упоминал, мы изначально определяем два flex-контейнера (для небольших экранов). Для первого breakpoint-а мы изменяем flex-direction для обертки колонок на строчное, а боковым колонкам задаем ширину 180 px, используя сокращенную запись — свойство flex. Данная запись позволит нам ограничить значения для свойств flex-grow и flex-shrink, а также явно указать ширину. Для контента используется свойство flex: 1, чтобы он заполнял доступное пространство. Расположение flex-элементов в нужном порядке также оказалось пустяком благодаря свойству order. Пожалуй, остались только дополнительные стили, которые вы захотите добавить с эстетической точки зрения…, а в остальном это действительно просто и эффективно. А упомянул ли я о том, что по умолчанию flexbox создает колонки одинаковой высоты? Взгляните на этот демо-пример.
В нашем следующем примере мы будем создавать нечто веселое, включающее красивый переход. Мы создадим резиновую навигацию, которая растягивается на всю ширину, а в ней мы разместим поле поиска, которое будет плавно растягиваться в состоянии фокуса. Используя силу flexbox, мы сможем добавить столько пунктов меню, сколько захотим, не меняя при этом CSS. Я буду использовать некоторые классы для достижения нужного результата. В качестве небольшого бонуса я собираюсь сделать нашу навигацию полностью отзывчивой, добавив для нее кнопку-переключатель! Вот как будет выглядеть HTML:
Давайте разберем данную разметку, прежде чем мы перейдем к CSS. У нас есть основной flex-контейнер с классом .flexy-nav. Кнопка используется в качестве переключателя, в ненумерованном списке содержатся пункты основного меню, а в форме содержится поле поиска. Для небольших экранов нам нужно использовать колоночную разметку для всех трех элементов, а также нам нужно, чтобы каждый пункт меню располагался в отдельной колонке. На широких экранах нам нужно спрятать кнопку-переключатель, выстроить элементы списка в строку и задать для формы фиксированную ширину. Элементы списка будут равномерно распределены среди оставшегося пространства. Когда мы переключаемся на текстовое поле (поле поиска), нам бы хотелось, чтобы оно плавно растягивалось по ширине, а все элементы списка, наоборот, плавно сужались. Вот CSS:
Как и обещал, вот, до смешного простой, кусочек JavaScript кода, который позволит нам показывать/скрывать навигацию на небольших экранах:
Настолько все просто. Мы только что создали красивую и масштабируемую резиновую навигацию с помощью flexbox, а также встроили плавный переход при изменении ширины у поля поиска. Мы можем сколько угодно добавлять или удалять ссылки, а также «на лету» изменять размеры поля поиска. И при этом функциональность нашего меню нисколько не пострадает. Ах, вот они прелести flexbox. Не забудьте посмотреть соответствующий демо-пример.
Давайте признаем тот факт, что вертикальное выравнивание в традиционном CSS просто никуда не годится. Inline-block элементы могут иногда с этим помочь, есть также хаки с абсолютным позиционированием, а еще есть устаревшие табличные разметки (которые на данный момент неприемлемы для многих случаев с семантической точки зрения). У всех этих способов есть свои особенности, и они точно потребуют от вас дополнительных «танцев с бубнов», чтобы все работало, как надо.
Flexboxс легкостью возьмет это на себя. Мы рассмотрим два примера вертикального выравнивания:
Давайте начнем с первого примера. Как уже было сказано, нам нужно расположить пользовательский аватар слева, а описание — справа. И неважно насколько длинным или коротким будет описание. Нам нужно, чтобы оно всегда было идеально выровнено с аватаром. Вот стандартная разметка:
Прежде чем мы перейдем к CSS, обратите внимание на то, что мы будем использовать незнакомое до этого свойство. Это свойство align-items, и оно позволяет нам выравнивать элементы вдоль, так называемой, flex-линии в перпендикулярном направлении. Другими словами, если наша flex-линия расположена горизонтально, то мы можем выравнивать наши элементы в направлении, которое перпендикулярно данной линии. В нашем случае нам нужно выровнять элементы по центру, поэтому мы будем использовать значение align-items: center. Вот CSS:
Вот так просто. Вы можете оформить текст, как вам захочется, сделать описания очень длинными или изменить размеры аватара. Это не имеет значения, функциональность останется прежней. Оцените данную возможность в действии.
Давайте перейдем ко второму примеру. На этот раз представьте, что у нас есть баннер, расположенный в самой верхней части разметки. И мы хотим разместить внутри баннера какой-то заголовок. На маленьких экранах высота баннера будет равна 180 px, и она будет изменяться еще дважды, до значения 480 px. И при всех изменениях высоты баннера нам нужно, чтобы текст внутри был расположен идеально по центру (как по горизонтали, так и по вертикали). Вот стандартная разметка:
На этот раз мы задействовали также свойство justify-content, которое позволит нам распределить пространство вокруг элементов вдоль flex-линии. А вот CSS:
.
Неважно, насколько «высоким» будет баннер. Контент всегда будет идеально отцентрирован по горизонтали и вертикали. Вот в этом и заключается мощь flexbox. Не забудьте посмотреть демо-пример.
Вы должны знать ваш рынок и аудиторию… это ключевой момент. Flexbox поддерживается во всех современных браузерах, включая IE10 и выше. Если вы занимаетесь созданием современных веб-приложений, то flexbox — это мощный инструмент, и я очень рекомендую его использовать. Если вы создаете или переделываете веб-сайт, то проверьте статистику посещаемости, чтобы узнать вашу аудиторию. В настоящее время есть вероятность того, что около 99% вашей аудитории будет использовать современные браузеры.
Что касается вендорных префиксов, то у flexbox их много. Это очень неразумно всерьез использовать flexbox и при этом вручную прописывать все вендорные префиксы. Лично я использую сборщик проектов (Gulp) для автоматической простановки префиксов.
Вот и все! На этом я заканчиваю данную статью. Если вы хотите найти реальный сайт, на котором используется flexbox, то можете даже и не начинать поиски. На новом сайте callmenick.com flexbox используется практически везде! Спасибо, что прочли статью до конца. Не забудьте, что вы можете посмотреть демо-примеры, а также скачать исходники по нижеприведенным ссылкам. Если у вас есть какие-либо вопросы, замечания или пожелания, оставьте их, пожалуйста, в комментариях.
Ссылка на оригинал статьи: http://callmenick.com/post/flexbox-examples
Введение
Некоторое время назад я написал ознакомительную статью про flexbox на сайте SitePoint. В данной статье я постарался выяснить и ответить на вопрос:
А готовы ли мы использовать flexbox?
В прошлый раз я говорил, что вам следует очень аккуратно использовать данную возможность, но настаивал на том, что нужно обязательно познакомиться с ее синтаксисом и внедрять ее в современные проекты. Сейчас я рад, что могу дать положительный ответ на свой вопрос:
Да, мы готовы использовать flexbox!
Если вы еще не знакомы с flexbox, то вот небольшое пояснение. CSS модуль построения гибкой разметки — это модуль, позволяющий легко размещать блоки на экране, в пределах выделенного пространства. Это большое достижение по сравнению с классической блочной моделью, т.к. flexbox позволяет вообще не использовать свойство float. Блоки могут быть объединены в строки или разбиты на колонки. Для каждого flexbox-элемента может быть задан определенный порядок. А также можно сразу управлять выравниванием, отступами и размерами этих элементов.
Пожалуй, что в данной статье мне не удастся рассмотреть каждый аспект данного модуля, поэтому я предлагаю вам познакомиться с ним поподробнее, перейдя на сайт MDN. А в данной обучающей статье мы рассмотрим распространенные проблемы с разметкой и увидим, как легко и быстро их можно решить. Каждый шаблон разметки, о котором я расскажу, будет отзывчивым, что еще больше подчеркнет ту легкость, с которой можно создавать разметку с помощью flexbox. Вот что мы рассмотрим:
- Простая сеточная система
- Разметка трехколоночного сайта
- Резиновая навигация с изменяющейся шириной поля поиска
- Два разных варианта вертикального выравнивания
Хорошо, давайте приступать!
Простая сеточная система
Сегодня сеточные системы присутствуют в большинстве разметок проектов, и классическое поведение блочной модели в CSS вынудило нас прибегнуть к использованию плавающих или inline-block элементов, каждый из которых имеет собственные недостатки. Flexbox позволяет нам легко создавать действительно классную и масштабируемую сеточную систему благодаря написанию всего нескольких строчек в CSS. Давайте рассмотрим это поподробнее.
Представьте, что у нас есть следующая простая разметка:
<div class="grid">
<div class="grid__row">
<div class="grid__item">1div>
<div class="grid__item">2div>
...
div>
div>
При традиционном подходе создания сетки нам бы пришлось каким-то образом определить, сколько элементов может помещаться в одну строку, а затем установить ширину для каждого элемента сетки. А с помощью flexbox мы можем добавлять в строку столько элементов, сколько захотим, и их ширина сама будет подстраиваться под общую ширину строки. Другими словами, у нас может быть следующая разметка, и при этом нам не нужно волноваться об указании количества элементов в каждой строке в CSS:
<div class="grid">
<div class="grid__row">
<div class="grid__item">1div>
<div class="grid__item">2div>
div>
<div class="grid__row">
<div class="grid__item">1div>
<div class="grid__item">2div>
<div class="grid__item">3div>
div>
<div class="grid__row">
<div class="grid__item">1div>
<div class="grid__item">2div>
<div class="grid__item">3div>
<div class="grid__item">4div>
div>
div>
А теперь давайте посмотрим на CSS код. Некоторые свойства я использовал чисто в эстетических целях (например, рамки и внутренние отступы), а в остальном все очень просто:
.grid {
border: solid 1px #e7e7e7;
}
.grid__row {
display: flex;
}
.grid__item {
flex: 1;
padding: 12px;
border: solid 1px #e7e7e7;
}
Вот как-то так! И наша сетка уже готова к использованию. Добавляя display: flex к контейнерам .grid__row, мы создаем, так называемый, flex-контейнер, а каждый дочерний элемент в контейнере сразу становится flex-элементом. Применяя свойство flex: 1 к flex-элементам, мы заставляем их занимать равное количество места относительно общей ширины контейнера. Теперь у вас может быть сколько угодно строк в сетке, а в каждой из них может быть свое собственное количество элементов. И это будет простая полностью отзывчивая сеточная система без всякого дополнительного CSS.
А что можно сказать насчет breakpoint-ов и колоночной разметки? Если мы хотим, чтобы элементы сетки выстраивались в колонки, а не в строки, то мы можем просто объявить свойство flex-direction: column для контейнеров с классом .grid__row. В этом случае мы можем создать очень простую отзывчивую сетку, внеся некоторые изменения. И наша разметка будет выглядеть вот так:
<div class="grid">
<div class="grid__row grid__row--sm">
<div class="grid__item">1div>
...
div>
<div class="grid__row grid__row--md">
<div class="grid__item">1div>
...
div>
<div class="grid__row grid__row--lg">
<div class="grid__item">1div>
...
div>
div>
А наш CSS вот так:
.grid {
border: solid 1px #e7e7e7;
}
.grid__row {
display: flex;
flex-direction: column;
}
.grid__item {
flex: 1;
padding: 12px;
border: solid 1px #e7e7e7;
}
@media all and ( min-width: 480px ) {
.grid__row--sm {
flex-direction: row;
}
}
@media all and ( min-width: 720px ) {
.grid__row--md {
flex-direction: row;
}
}
@media all and ( min-width: 960px ) {
.grid__row--lg {
flex-direction: row;
}
}
И вуа-ля. Супер-простая отзывчивая сеточная система размером всего в несколько CSS строк. Эта система настолько непробиваемая, что вы даже можете вкладывать сетки друг в друга, не заботясь о последствиях:
<div class="grid">
<div class="grid__row grid__row--sm">
<div class="grid__item">
<div class="grid">
<div class="grid__row grid__row--lg">
<div class="grid__item">Nested 1div>
...
div>
div>
div>
<div class="grid__item">2div>
div>
<div class="grid__row grid__row--md">
<div class="grid__item">1div>
...
div>
div>
Посмотрите на это в действии.
Разметка трехколоночного сайта
Разметка трехколоночного сайта является довольно известной в веб-дизайне, и даже в эпоху веб-приложений и прочего веселья, данный вариант разметки по-прежнему играет важную роль в вебе — такая разметка постоянно используется на сайтах, у которых много контента. Еще в 2006 году трехколоночная разметка была замечательно разобрана и описана на сайте A List Apart. В ней используются float элементы, отрицательные margin и значения min-width, чтобы совмещенные размеры элементов не конфликтовали друг с другом и не ломали разметку. И все это, с учетом нынешней необходимости в создании отзывчивой разметки, означало использование большого количества вычислений, отмены обтекания и других трюков, чтобы это все работало правильно. И если вы решили поменять ширину боковой колонки, то нужно было заново производить все вычисления.
Flexbox позволяет избавиться от существенной головной боли, т.к. мы можем определить колоночную или строчную разметку, а также явно указать порядок следования элементов в CSS, даже если они расположены в другом порядке в нашей разметке. Вот типичный пример создания трехколоночной разметки:
<body class="holy-grail">
<header class="holy-grail__header">header>
<main class="holy-grail__body">
<div class="holy-grail__content">div>
<div class="holy-grail__sidebar holy-grail__sidebar--first">div>
<div class="holy-grail__sidebar holy-grail__sidebar--second">div>
div>
<footer class="holy-grail__footer">footer>
body>
В моем демо-примере разметка находится внутри документа, поэтому в ней нет тегов body или main, как это показано выше. Но в данном случае, нас интересуют имена классов и сами разделы нашей разметки, а не непосредственно сами элементы. В частности, обратите внимание на классы, которые используются для двух боковых колонок, и на тот порядок, в котором они следуют в разметке. Давайте последовательно рассмотрим, что здесь происходит:
- У нас есть родительский контейнер, .holy-grail, а в нем у нас находится три flex-элемента. Это элементы с классами .holy-grail__header, holy-grail__body и holy-grail__footer.
- Данные три элемента расположены друг над другом и занимают 100% от ширины экрана. Таким образом, для flex-контейнера должно быть задано колоночное направление.
- Тело нашей разметки, .holy-grail__body, является внутренним flex-контейнером. Его дочерние flex-элементы должны иметь колоночную разметку на небольших экранах и строчную разметку на широких экранах.
Учитывая все вышесказанное, давайте построим разметку:
.holy-grail {
display: flex;
flex-direction: column;
}
.holy-grail__header,
.holy-grail__footer {
flex: 0 0 100%;
}
.holy-grail__body {
display: flex;
}
.holy-grail__sidebar {
/* ничего на небольших экранах */
}
.holy-grail__sidebar--first {
order: 1;
}
.holy-grail__sidebar--second {
order: 3;
}
.holy-grail__content {
order: 2;
}
@media all and ( min-width: 720px ) {
.holy-grail__body {
flex-direction: row;
}
.holy-grail__sidebar {
flex: 0 0 180px;
}
.holy-grail__content {
flex: 1;
}
}
@media all and ( min-width: 960px ) {
.holy-grail__sidebar {
flex: 0 0 240px;
}
}
Это действительно настолько просто! Как я уже упоминал, мы изначально определяем два flex-контейнера (для небольших экранов). Для первого breakpoint-а мы изменяем flex-direction для обертки колонок на строчное, а боковым колонкам задаем ширину 180 px, используя сокращенную запись — свойство flex. Данная запись позволит нам ограничить значения для свойств flex-grow и flex-shrink, а также явно указать ширину. Для контента используется свойство flex: 1, чтобы он заполнял доступное пространство. Расположение flex-элементов в нужном порядке также оказалось пустяком благодаря свойству order. Пожалуй, остались только дополнительные стили, которые вы захотите добавить с эстетической точки зрения…, а в остальном это действительно просто и эффективно. А упомянул ли я о том, что по умолчанию flexbox создает колонки одинаковой высоты? Взгляните на этот демо-пример.
Резиновая навигация с изменяющейся шириной поля поиска
В нашем следующем примере мы будем создавать нечто веселое, включающее красивый переход. Мы создадим резиновую навигацию, которая растягивается на всю ширину, а в ней мы разместим поле поиска, которое будет плавно растягиваться в состоянии фокуса. Используя силу flexbox, мы сможем добавить столько пунктов меню, сколько захотим, не меняя при этом CSS. Я буду использовать некоторые классы для достижения нужного результата. В качестве небольшого бонуса я собираюсь сделать нашу навигацию полностью отзывчивой, добавив для нее кнопку-переключатель! Вот как будет выглядеть HTML:
<nav class="flexy-nav">
<button id="flexy-nav__toggle" class="flexy-nav__toggle">Toggle Navbutton>
<ul id="flexy-nav__items" class="flexy-nav__items">
<li class="flexy-nav__item"><a href="#" class="flexy-nav__link">Item 1a>li>
<li class="flexy-nav__item"><a href="#" class="flexy-nav__link">Item 2a>li>
<li class="flexy-nav__item"><a href="#" class="flexy-nav__link">Item 3a>li>
<li class="flexy-nav__item"><a href="#" class="flexy-nav__link">Item 4a>li>
ul>
<form action="" class="flexy-nav__form">
<input class="flexy-nav__search" type="text" placeholder="Type search terms and hit enter...">
form>
nav>
Давайте разберем данную разметку, прежде чем мы перейдем к CSS. У нас есть основной flex-контейнер с классом .flexy-nav. Кнопка используется в качестве переключателя, в ненумерованном списке содержатся пункты основного меню, а в форме содержится поле поиска. Для небольших экранов нам нужно использовать колоночную разметку для всех трех элементов, а также нам нужно, чтобы каждый пункт меню располагался в отдельной колонке. На широких экранах нам нужно спрятать кнопку-переключатель, выстроить элементы списка в строку и задать для формы фиксированную ширину. Элементы списка будут равномерно распределены среди оставшегося пространства. Когда мы переключаемся на текстовое поле (поле поиска), нам бы хотелось, чтобы оно плавно растягивалось по ширине, а все элементы списка, наоборот, плавно сужались. Вот CSS:
/* сброс стилей */
input,
button {
font: inherit;
border-radius: none;
box-shadow: none;
appearance: none;
}
button {
cursor: pointer;
}
/* контейнер навигации */
.flexy-nav {
display: flex;
flex-direction: column;
}
/* пункты меню */
.flexy-nav__items {
display: none;
flex: 1;
flex-direction: column;
list-style: none;
margin: 0 0 4px 0;
padding: 4px;
text-align: center;
}
.flexy-nav__items--visible {
display: flex;
}
.flexy-nav__item {
background-color: #f1f1f1;
border-bottom: solid 1px #e7e7e7;
}
.flexy-nav__item:last-child {
border-bottom: 0;
}
.flexy-nav__link {
padding: 8px;
display: block;
}
/* переключатель меню */
.flexy-nav__toggle {
margin: 0 0 4px 0;
padding: 4px;
color: #fff;
background-color: #f07850;
border: none;
}
.flexy-nav__toggle:hover,
.flexy-nav__toggle:focus {
outline: none;
background-color: #c93f11;
}
/* форма для поля поиска в навигации */
.flexy-nav__form {
height: 48px;
}
.flexy-nav__search {
display: block;
margin: 0;
padding: 0 4px;
width: 100%;
height: 48px;
color: #6d6d6d;
background-color: #fff;
border: solid 2px #e7e7e7;
}
.flexy-nav__search:focus {
outline: none;
border: solid 2px #6d6d6d;
}
/* медиа-запросы */
@media all and (min-width: 768px) {
.flexy-nav {
flex-direction: row;
}
.flexy-nav__items {
display: flex;
flex-direction: row;
margin: 0;
padding: 0;
height: 48px;
}
.flexy-nav__item {
flex: 1;
margin-right: 4px;
border-bottom: none;
}
.flexy-nav__link {
padding: 0;
line-height: 48px;
}
.flexy-nav__toggle {
display: none;
}
.flexy-nav__form {
flex: none;
}
.flexy-nav__search {
width: 240px;
transition: width 0.3s;
}
.flexy-nav__search:focus {
width: 360px;
}
}
Как и обещал, вот, до смешного простой, кусочек JavaScript кода, который позволит нам показывать/скрывать навигацию на небольших экранах:
(function() {
var toggle = document.querySelector("#flexy-nav__toggle");
var nav = document.querySelector("#flexy-nav__items");
toggle.addEventListener("click", function(e) {
e.preventDefault();
nav.classList.contains("flexy-nav__items--visible") ? nav.classList.remove("flexy-nav__items--visible") : nav.classList.add("flexy-nav__items--visible");
});
})();
Настолько все просто. Мы только что создали красивую и масштабируемую резиновую навигацию с помощью flexbox, а также встроили плавный переход при изменении ширины у поля поиска. Мы можем сколько угодно добавлять или удалять ссылки, а также «на лету» изменять размеры поля поиска. И при этом функциональность нашего меню нисколько не пострадает. Ах, вот они прелести flexbox. Не забудьте посмотреть соответствующий демо-пример.
Вертикальное выравнивание
Давайте признаем тот факт, что вертикальное выравнивание в традиционном CSS просто никуда не годится. Inline-block элементы могут иногда с этим помочь, есть также хаки с абсолютным позиционированием, а еще есть устаревшие табличные разметки (которые на данный момент неприемлемы для многих случаев с семантической точки зрения). У всех этих способов есть свои особенности, и они точно потребуют от вас дополнительных «танцев с бубнов», чтобы все работало, как надо.
Flexboxс легкостью возьмет это на себя. Мы рассмотрим два примера вертикального выравнивания:
- Сначала мы рассмотрим создание, так называемого, «медиа-объекта», в котором используется пользовательский аватар (расположенный слева) и имя пользователя + некоторая информация (расположенные справа). Мы будем использовать flexbox, чтобы изображение и тело медиа-объекта были идеально выровнены по вертикали.
- Затем мы просто рассмотрим вертикальное (горизонтальное) выравнивание элемента фиксированной ширины и переменной высоты внутри контейнера. Элемент будет оставаться расположенным точно по центру, несмотря на увеличение высоты.
Давайте начнем с первого примера. Как уже было сказано, нам нужно расположить пользовательский аватар слева, а описание — справа. И неважно насколько длинным или коротким будет описание. Нам нужно, чтобы оно всегда было идеально выровнено с аватаром. Вот стандартная разметка:
<div class="user">
<div class="user__avatar">div>
<div class="user__description">
<h2 class="user__username">John Doeh2>
<p class="user__excerpt">I'm John Doe...p>
div>
div>
<div class="user">
<div class="user__avatar">div>
<div class="user__description">
<h2 class="user__username">Harry Potterh2>
<p class="user__excerpt">I'm Harry Potter...with a really long description...p>
div>
div>
Прежде чем мы перейдем к CSS, обратите внимание на то, что мы будем использовать незнакомое до этого свойство. Это свойство align-items, и оно позволяет нам выравнивать элементы вдоль, так называемой, flex-линии в перпендикулярном направлении. Другими словами, если наша flex-линия расположена горизонтально, то мы можем выравнивать наши элементы в направлении, которое перпендикулярно данной линии. В нашем случае нам нужно выровнять элементы по центру, поэтому мы будем использовать значение align-items: center. Вот CSS:
.user {
display: flex;
align-items: center;
}
.user:last-child {
margin-bottom: 0;
}
.user__avatar {
flex: 0 0 96px;
width: 96px;
height: 96px;
background-color: #e7e7e7;
}
.user__description {
flex: 1;
margin-left: 24px;
padding: 12px;
border: solid 1px #e7e7e7;
}
Вот так просто. Вы можете оформить текст, как вам захочется, сделать описания очень длинными или изменить размеры аватара. Это не имеет значения, функциональность останется прежней. Оцените данную возможность в действии.
Давайте перейдем ко второму примеру. На этот раз представьте, что у нас есть баннер, расположенный в самой верхней части разметки. И мы хотим разместить внутри баннера какой-то заголовок. На маленьких экранах высота баннера будет равна 180 px, и она будет изменяться еще дважды, до значения 480 px. И при всех изменениях высоты баннера нам нужно, чтобы текст внутри был расположен идеально по центру (как по горизонтали, так и по вертикали). Вот стандартная разметка:
<div class="banner">
<div class="banner__content">
<h2 class="banner__title">Symmetrical Perfectionh2>
<span class="banner__sub">A beautiful sight, achieved with flexbox.span>
div>
div>
На этот раз мы задействовали также свойство justify-content, которое позволит нам распределить пространство вокруг элементов вдоль flex-линии. А вот CSS:
.
banner {
display: flex;
align-items: center;
justify-content: space-around;
height: 180px;
background-color: #e7e7e7;
}
.banner__content {
text-align: center;
}
.banner__title,
.banner__sub {
margin: 0;
padding: 0;
line-height: 1.5;
}
@media all and ( min-width: 480px ) {
.banner {
height: 240px;
}
}
@media all and ( min-width: 768px ) {
.banner {
height: 360px;
}
}
@media all and ( min-width: 960px ) {
.banner {
height: 480px;
}
}
Неважно, насколько «высоким» будет баннер. Контент всегда будет идеально отцентрирован по горизонтали и вертикали. Вот в этом и заключается мощь flexbox. Не забудьте посмотреть демо-пример.
Поддержка и вендорные префиксы
Вы должны знать ваш рынок и аудиторию… это ключевой момент. Flexbox поддерживается во всех современных браузерах, включая IE10 и выше. Если вы занимаетесь созданием современных веб-приложений, то flexbox — это мощный инструмент, и я очень рекомендую его использовать. Если вы создаете или переделываете веб-сайт, то проверьте статистику посещаемости, чтобы узнать вашу аудиторию. В настоящее время есть вероятность того, что около 99% вашей аудитории будет использовать современные браузеры.
Что касается вендорных префиксов, то у flexbox их много. Это очень неразумно всерьез использовать flexbox и при этом вручную прописывать все вендорные префиксы. Лично я использую сборщик проектов (Gulp) для автоматической простановки префиксов.
Заключение
Вот и все! На этом я заканчиваю данную статью. Если вы хотите найти реальный сайт, на котором используется flexbox, то можете даже и не начинать поиски. На новом сайте callmenick.com flexbox используется практически везде! Спасибо, что прочли статью до конца. Не забудьте, что вы можете посмотреть демо-примеры, а также скачать исходники по нижеприведенным ссылкам. Если у вас есть какие-либо вопросы, замечания или пожелания, оставьте их, пожалуйста, в комментариях.
Ссылка на оригинал статьи: http://callmenick.com/post/flexbox-examples