Примеры использования флексбоксов — Блог Академии — HTML Academy
Это заключительная часть серии статей про флексы от Рейчел Эндрю в Smashing Magazine.
В этот раз я собираюсь немного поразмышлять, для чего на самом деле стоит применять флексы, учитывая существование гридов. Также я выскажу предположения о том, как определиться, что и когда использовать.
Ранее в этой серии
Если вы ещё не читали предыдущие статьи, лучше начните с них — это заключительная часть. Я начала с описания того, что именно происходит, когда вы создаёте флекс-контейнер. Во второй статье я обратила внимание на выравнивание и на то, как мы выравниваем элементы по главной и поперечной осям во флексах. В третьей статье я разобралась с тем, как работает определение размеров и как браузер вычисляет какого размера должен быть флекс-элемент. Теперь поразмышлять о том, как применять флексы наилучшим образом, так как мы уже знаем, как именно они работают.
Стоит использовать гриды или флексы?
Это всё ещё ключевой вопрос, который мне задают, когда я обучаю раскладке. Думаю, что чем больше люди привыкают к работе с новыми методами раскладки, тем реже они задают себе этот вопрос. Чем больше компонентов вы создаёте, тем лучше вы чувствуете, какой метод раскладки лучше использовать.
Однако, если вы только осваиваете эти технологии, нужно помнить о том, что раскладка и на гридах, и на флексах — это всё CSS. Обозначили ли вы display: grid
или display: flex
вы чаще используете их схожие свойства, чем отличающиеся.
И гриды, и флексы используют свойства, которые являются частью спецификации Box Alignment
— выравнивания блоков, и обе эти раскладки опираются на концепции, описанные в разделе CSS Intrinsic and Extrinsic Sizing
— размерности в CSS.
Задавать вопрос о том, нужно ли в вашем интерфейсе использовать гриды или флексы — почти как спрашивать: «Что использовать: размер шрифта или его цвет?»
Вероятно, нужно использовать оба свойства, если потребуется. И никто не собирается преследовать вас, если вы используете неверный вариант.
Таким образом, мы не выбираем между Vue.js и React, Bootstrap или Foundation. Мы используем CSS для создания раскладки и нам нужно использовать те части CSS, которые наиболее целесообразны для этого конкретного блока макета, над которым мы работаем. Рассмотрите каждый компонент и решите, что лучше всего подойдёт для него, какая комбинация технологий лучше сработает.
Это могут быть гриды, а могут быть флексы. Это может быть внешний грид-контейнер, с некоторыми его элементами, которые вы превратите во флексы, или наоборот. Нет никакой проблемы внедрить грид внутри флекс-элемента, если это именно то, чего требует ваш дизайн.
Для чего действительно нужны флексы?
Раскладка на флексах c первого взгляда похожа на блочную раскладку. Ей не хватает многих более сложных свойств, ориентированных на тексты и документы, которые могут быть использованы в блочной раскладке, таких как флоаты или колонки.
В свою очередь, она обладает простыми и мощными инструментами распределения места и выравнивания контента такими способами, которые наиболее востребованы в веб-приложениях и сложных веб-страницах.
Так описывает спецификация этот метод раскладки.
Думаю, ключевая фраза здесь — «распределение места и выравнивание контента». Флексы в целом о том, как взять несколько элементов, которые различаются по размеру, и подстроить их в контейнер, который сам тоже может изменяться по размеру. Флексы гибкие. Они стараются создать наилучшую возможную раскладку для наших элементов, давая большим элементам больше места и меньшим — меньше, сохраняя читабельность контента.
Когда говорят, что флексы жёсткие и странные, это часто потому, что они пытаются использовать флексы как сеточную систему, стараясь вернуть контроль над размером и распределением места. Когда вы делаете это, флексы могут казаться странными и жёсткими, поскольку вы боретесь против их природы — их врождённой гибкостью.
Следовательно, паттерны, которые отлично подходят для флексов — это те, где мы не так сильно заинтересованы в идеальном соответствии размеров для каждого элемента. Мы просто хотим, чтобы эти элементы хорошо отображались относительно друг друга.
See the Pen Smashing Flexbox Series 4: Items sharing space by rachelandrew (@rachelandrew) on CodePen.
Есть также паттерны, где вы хотите видеть переносы строк, однако не хотите строгую сетку. Сравним гриды со значением
и флексы с переносом строк. Разница между этими двумя методами будет видна сразу же.
В примере с гридами элементы выравниваются в строки и колонки. Пока число полос колонок изменяется (в зависимости от места), элементы всегда идут в следующую грид-ячейку, которая доступна. В действительности, нет способа попросить грид-элемент захватить грид-полосу, если есть некоторые пустые ячейки, которые заполняются в этом сценарии автоматического потока.
В примере с флексом последние элементы делят всё доступное оставшееся пространство между собой, таким образом, у нас нет выравнивания по горизонтали или вертикали.
See the Pen Smashing Flexbox Series 4: wrapped flex items flex-basis 150px; by rachelandrew (@rachelandrew) on CodePen.
Если flex-basis
равен auto
и любой из флекс-элементов больше, им также будет дано больше места, так что выравнивание может различаться от строки к строке.
See the Pen Smashing Flexbox Series 4: Wrapped items by rachelandrew (@rachelandrew) on CodePen.
Вот очень понятный пример того, когда мы хотим использовать раскладку на флексах вместо гридов. Если мы хотим, чтобы элементы переносились, но занимали всё место на строке, которое им нужно от строки к строке.
Это очень сильно отличается от раскладки на гридах. Пример подобного паттерна — это набор тегов — элементов из одного или двух слов, которые вы хотите красиво отобразить как набор элементов, которые занимают то место, которое им необходимо и при этом не строго определены в жёсткую сетку.
See the Pen Smashing Flexbox Series 4: tags example by rachelandrew (@rachelandrew) on CodePen.
В настоящее время флексы — также наилучший способ для вертикального и горизонтального центрирования элемента внутри контейнера.
See the Pen Smashing Flexbox Series 4: centered by rachelandrew (@rachelandrew) on CodePen.
В будущем, когда в браузерах появится поддержка свойств выравнивания блоков вне флексов, мы сможем делать это без добавления display: flex
к контейнеру. Но сегодня это нужно сделать, хотя эта лишняя строка в CSS, на самом деле, не проблема.
Флексы хороши в работе с маленькими, одномерными компонентами. Наборы полей форм, иконки или другая информация может быть легко выстроена и ей можно позволить быть гибкой, не задавая размеры каждому из элементов.
Также стоит выбрать флексы в том случае, если всё, что вам нужно сделать — это заставить контент внизу раскладки прилипать к низу контейнера, а не подпрыгивать вверх. В этом примере я сделала контейнер флексовым, отобразив содержание как колонки, затем позволила середине расти, прижимая футер к низу компонента.
See the Pen Smashing Flexbox Series 4: sticky footer card by rachelandrew (@rachelandrew) on CodePen.
Я считаю, что флекс полезен в реальных проектах для множества маленьких задач и даёт уверенность, что элементы выровнены подходящим образом, и место распределяется равномерно между элементами. Вы можете использовать одномерный грид-контейнер для этого и не переживать, сделав это.
Но лучше всего, как мне кажется, флексы справляются, когда нужно добавить дополнительные элементы, которые я не ожидала в своём дизайне.
Например, если есть компонент навигации с использованием гридов, я буду создавать достаточное количество полос для всех элементов, так как не хочу, чтобы создавался новый ряд, если будет «слишком много» элементов. С флексами, до тех пор, пока я разрешаю элементам быть гибкими с
или auto
, элементы позволят новым соседям стать с ними в ряд и оставят для них место.
Когда не стоит использовать флексы?
Мы рассмотрели некоторые причины, по которым думаю, cтоит выбирать флексы вместо раскладки на гридах, поэтому можем посмотреть на некоторые случаи, когда флекс — не лучший вариант. Мы уже посмотрели на пример с флексом против грида, где элементы выровнены по горизонтали и вертикали в отличие от элементов, которые занимают место построчно. И это различие стоит учитывать в первую очередь.
Вот пример грида с двумерной раскладкой. Раскладка одновременно и в строках, и в колонках. Пример на флексах — это одномерная раскладка. Мы позволили перенос флекс-строк, но распределение места на строке ведётся построчно. Каждая строка естественно ведёт себя как новый флекс-контейнер по направлению главной оси.
Следовательно, если компоненту нужна двумерная раскладка, лучше будет использовать гриды вместо флексов. Неважно, большой или маленький у вас компонент. Если запомните из этой статьи только одно, пусть это будет следующее: выкиньте из головы идею о том, что гриды предназначены только для основной раскладки страницы, а флексы — для компонентов. У вас может быть крошечный компонент, которому требуется двумерная раскладка, и структура главной страницы, которой лучше подойдёт одномерная раскладка.
Ещё один хороший пример, где гриды будут лучшим решением: если вы задаёте ширину или базовый размер флекса по главной оси — flex-basis
как единицу длины для ваших элементов, для того чтобы выровнять их с другим рядом таких же элементов, или чтобы каким-то образом ограничить гибкость. Довольно часто это показатель того, что вам нужна двумерная раскладка, или того, что вашей раскладке лучше подойдёт контроль со стороны контейнера сетки.
Например, мы можем сделать нашу раскладку на флексах более похожей на гриды, ограничив гибкость элементов. Задайте свойство flex-grow: 0
и выставите размеры элементов в процентах, подобно тому, как мы поступали с размерами элементов в раскладке на флоатах. Если обнаружите, что поступаете так, предположу, что раскладка на гридах подойдёт вам лучше, ведь она и была создана для этого.
See the Pen Smashing Flexbox Series 4: wrapped flex items with percentage widths by rachelandrew (@rachelandrew) on CodePen.
Принимая во внимание всё вышесказанное, помните, что часто нет чёткого правильного или неправильного ответа. Иногда единственное, что можно сделать — это попробовать разные варианты и посмотреть, что лучше всего подходит этому компоненту. Помните, что также можно переключаться между методами раскладки, используя флексы на одной контрольной точке и гриды на другой.
А вот и всё!
Надеюсь, эта серия про флексы была полезна и продемонстрировала, как некоторое понимание логики выравнивания и размерности флекс-элементов делает жизнь и работу с ними проще. Если у вас остались некоторые нерешённые вопросы или у вас есть паттерн, где непонятно, который метод использовать — пишите .
Это перевод статьи Рейчел Эндрю «Use Cases For Flexbox».
htmlacademy.ru
CSS Flexbox основы c примерами
Использование flexbox
Flexbox применяется не к самим элементам, которые необходимо сгруппировать а к содержащему их контейнеру. Для этого необходимо задать ему css свойство display: flex;.
Примеры:
Без flexbox
С использованием flexbox
.flex__wrp {
display: flex;
}
Если необходимо чтобы flexbox контейнер был inline элементом (строчным), то следует использовать свойство
flex-direction
Элементам можно задать также направление размещения. Для этого используется свойство flex-direction.
У свойства может быть 4 параметра
- row — отображение строкой (используется по умолчанию)
- column — отображение столбцом
- row-reverse — строка в обратном направлении
- column-reverse — столбец в обратном направлении
Примеры:
flex-direction: row;
flex-direction: column;
flex-direction: row-reverse;
flex-direction: column-reverse;
flex-wrap
Элементы в контейнере изначально выстраиваются в 1 линию, что может влиять на их размер. Для того чтобы этого избежать используется свойство flex-wrap: wrap;.
Пример:
Дефолтное значение flex-wrap: nowrap;
Используем flex-wrap: wrap;
justify-content
Для группировки элементов можно использовать свойство justify-content.
У свойства может быть 6 параметров
- flex-start — элементы у левого края контейнера (используется по умолчанию)
- flex-end — элементы у правого края контейнера
- center — элементы по центру
- space-between — элементы на всю длину контейнера, между ними равное расстояние
- space-around — элементы на всю длину контейнера, вокруг них равное расстояние
- space-evenly — элементы на всю длину контейнера, между ними и стенками контейнера равное расстояние
Примеры:
flex-start
flex-end
center
space-between
space-around
space-evenly
align-items
Для выбора расположения элементов по оси отличной от основной используют свойство align-items.
Рассмотрим 3 основных параметра
- flex-start — элементы у верхнего края контейнера (используется по умолчанию)
- flex-end — элементы у нижнего края контейнера
- center — элементы по центру
Примеры:
flex-start
flex-end
center
align-content
Для выравнивания элементов в контейнере используется свойство align-content.
У свойства может быть 7 параметров
- stretch — элементы занимают весь объем контейнера (используется по умолчанию)
- flex-start — элементы у верхнего края контейнера
- flex-end — элементы у нижнего края контейнера
- center — элементы по центру
- space-between — между элементами равное расстояние
- space-around — вокруг элементами равное расстояние
- space-evenly — между элементами и стенками контейнера одинаковое расстояние
Примеры:
stretch
flex-start
flex-end
center
space-between
space-around
space-evenly
order
Для того чтобы «вручную» расположить элементы в нужном порядке используют свойство order. В отличие от всех вышеперечисленных, оно присваивается не контейнеру, а самому элементу. В качестве параметра используется число, соответствующее необходимому порядковому номеру элемента.
Пример:
order
1 order: 2;
2 order: 1;
3 order: 3;
webninja.ru
интерфейсы сайта от начала и до конца
От автора: дни костылей на свойствах float и margin канули в небытие, и в CSS появились новые замечательные свойства, отлично подходящие на эту роль. Такие трюки, как вертикальное выравнивание внутри блока, равномерное распределение места, контроль за сортировкой элементов и прилипающий футер, почти невозможны без flexbox.
В этой статье мы рассмотрим некоторые flexbox примеры, обсудим шаблоны, отлично работающие с flexbox, воспользуемся интерфейсом приложения Tracks, которое вобрало в себя все преимущества атомарного дизайна. Я расскажу про полезные свойства flexbox, а также заострю внимание на подводных камнях, встречающихся в некоторых конкретных шаблонах. Рассмотрим именно те шаблоны, которые могут вызвать вопросы, не забудем о старых браузерах. В общем, сделаем все, что бы после статьи вы сразу могли начать пользоваться данными CSS свойствами.
Гибкие атомарные компоненты
Основная идея интерфейса сайта Tracks заключается в изолированности каждой части дизайна. Эта идея была изложена Brad Frost.
Вся философия атомарного дизайна заключается в том, что каждый элемент, как отдельная часть лего, и когда они собираются вместе, образуется неповторимый интерфейс. В атомарном дизайне используются физические термины организма, молекулы и атома для более глубокого понимания роли каждого элемента. Такой способ разграничения на категории защищает данный шаблон проектирования от нападок со стороны grid шаблона. Так как проектирование начинается с самых малых составляющих, это позволяет легко внедрять эти составляющие по всему дизайну.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнееРисунок 1. Карточки отображаются по принципу атомарного веб-дизайна. Можете угадать, какие из них сделаны на flexbox?
Если хотите углубиться в теорию атомарного дизайна, прочитайте статью Brad’s post. Также стоит прочитать его книгу.
Рисунок 2. Изначальный интерфейс Tracks, вобравший все преимущества как flexbox, так и атомарного дизайна.
Интерфейс представляет из себя набор компонентов InVision. Во время первой проверки интерфейса я начал искать подходящие места для flexbox. Я решил применять flexbox на страницах с известными шаблонами типа «сайдбар слева, основной контент справа», которые зачастую выполнены на устаревшем свойстве float.
Одним из положительных моментов в редизайне Tracks был тот, что сайт должен был хорошо работать в Internet Explorer (IE) 10+, Android 4.1+ и iOS 7+. Это была просто замечательная новость, так как все они отлично поддерживают flexbox с соответствующими префиксами. Даже несмотря на стабильную поддержку в наши дни, скажем, для Android 4.1 требуется на всякий случай сделать фолбэк. А как будет выглядеть тот же фолбэк, если свойство вообще не поддерживается браузером? С помощью Modernizr и класса .no-flexbox разработчики могут определить эти самые браузеры и найти стабильные шаблоны (в противном случае можно воспользоваться CSS запросами @supports). К примеру:
<ul> <li>…</li> <li>…</li> <li>…</li> </ul>
<ul> <li>…</li> <li>…</li> <li>…</li> </ul> |
html.flexbox ul.flexbox-target, html.no-js ul.flexbox-target { display: flex; flex-direction: row; } html.no-flexbox ul.flexbox-target li, html.no-js ul.flexbox-target li { display: inline-block; /* Could also use a float-positioned-layout system instead */ }
html.flexbox ul.flexbox-target, html.no-js ul.flexbox-target { display: flex; flex-direction: row; }
html.no-flexbox ul.flexbox-target li, html.no-js ul.flexbox-target li { display: inline-block; /* Could also use a float-positioned-layout system instead */ } |
Там, где не совсем ясно, поддерживается ли flexbox, мы будем использовать на всякий случай display: inline-block. Также, чтобы элемент не использовался в JS, добавим к нему класс no-js. Наследование в CSS не нарушится в случае, если flexbox не поддерживается или не загрузился JS. Flexbox прекрасно сосуществует с такими свойствами, как float и display: table, относительным позиционированием. Браузер всегда будет позиционировать flexbox выше остальных свойств, если он поддерживается. А если не поддерживается, будут применены обычные свойства.
Как и везде, наш выбор зависит от аудитории браузеров, аналитики и бюджета. У меня есть золотое правило – всегда делать выбор в пользу самого важного условия.
Инлайновые шаблоны
Компоненты меню оказались крайне полезны в flexbox, не только из-за легкости создания, но и из-за ускорения процесса разработки. Благодаря flexbox инлайновые шаблоны, которые раньше отнимали у разработчиков массу времени, теперь занимают всего лишь минуты. Если вы имели честь применять данный шаблон в версиях IE до 9, вы знаете про это чувство разочарования.
Рисунок 3. Панель администратора использует инлайновый шаблон, кнопки меню вертикально центрированы.
Разметка этой панели выглядит так: элемент nav, внутри которого расположена серия ссылок. Пример в HTML:
<header role=»banner»> <nav role=»navigation»> <a href=»pipeline.html»>Back to pipeline</a> <a href=»account.html»>Account</a> <a href=»users.html»>Users</a> <a href=»export.html»>Export</a> </nav> </header>
<header role=»banner»> <nav role=»navigation»> <a href=»pipeline.html»>Back to pipeline</a> <a href=»account.html»>Account</a> <a href=»users.html»>Users</a> <a href=»export.html»>Export</a> </nav> </header> |
И соответствующие стили:
nav[role=»navigation»] { display: flex; align-items: center; /* вертикальное центрирование */ } nav[role=»navigation»] a { display: inline-block; /* во избежание проблем с линейным отображением в IE 10 */ } nav[role=»navigation»] a[href=»pipeline.html»] { flex: 1; }
nav[role=»navigation»] { display: flex; align-items: center; /* вертикальное центрирование */ }
nav[role=»navigation»] a { display: inline-block; /* во избежание проблем с линейным отображением в IE 10 */ }
nav[role=»navigation»] a[href=»pipeline.html»] { flex: 1; } |
Это самый минимум, как разметки, так и стилей. Обратите внимание на значение inline-block, заданное ссылкам. Это значение решает проблему с сортировкой элементов с помощью свойства order в IE10. Также были выявлены проблемы с дочерними элементами контейнера flexbox, если задать им любой padding или margin. Лучше всего постоянно проверять работу свойств во всех браузерах и платформах.
Рисунок 4. В сети часто можно встретить такой шаблон. Шаблон меню хедера с центрированным логотипом с помощью flexbox.
Инлайновый шаблон выше обычно реализуется с помощью несемантической разметки. С появлением flexbox подход немного изменился. Шаблон состоит из ссылок меню по левому краю, центрированного логотипа и дополнительных элементов по правому краю. Разметка выглядит так:
<header role=»banner»> <a href=»pipeline.html»>…</a> <nav role=»navigation»>…</nav> <form role=»form»>…</form> <a href=»#menu»>…</a> </header>
<header role=»banner»> <a href=»pipeline.html»>…</a>
<nav role=»navigation»>…</nav>
<form role=»form»>…</form>
<a href=»#menu»>…</a> </header> |
Flexbox снижает потребность в создании HTML костылей и создает семантику. Семантика в коде крайне важна. Семантический код с большей степенью вероятности можно будет использовать повторно.
Для выстраивания элементов в ряд до появления flexbox раньше разработчики использовали display: inline-block и даже float: left. Теперь flexbox самый лучший вариант, разработчикам больше не нужно использовать костыли, чтобы создать красивый интерфейс. Стили для этого шаблона немного длиннее, чем для шаблона меню на рисунке 3. Но эти стили легче писать, чем те, о которых мы говорили раньше.
.pipeline-header { display: flex; align-items: center; justify-content: space-between; } .pipeline-header > a { display: inline-block; /* IE 10 не знает свойства order, с помощью этого свойства мы избежим лишних проблем. */ } .pipeline-logo { flex: 1; order: 2; text-align: center; } .pipeline-nav { flex: 1.25; order: 1; } .pipeline-search { flex: 1; order: 3; } a[href=»#menu»] { order: 4; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | .pipeline-header { display: flex; align-items: center; justify-content: space-between; }
.pipeline-header > a { display: inline-block; /* IE 10 не знает свойства order, с помощью этого свойства мы избежим лишних проблем. */ }
.pipeline-logo { flex: 1; order: 2; text-align: center; }
.pipeline-nav { flex: 1.25; order: 1; }
.pipeline-search { flex: 1; order: 3; }
a[href=»#menu»] { order: 4; } |
В шаблоне на рисунке 4 можно с легкостью изменять последовательность элементов. Если потребуется сместить логотип, просто воспользуйтесь свойством order. Помните, что последовательность элементов в коде очень важна для поисковиков; особенно в случае с разными браузерами. Все браузеры и скрин ридеры используют код для определения последовательности элементов, а не визуальный порядок в CSS. Это нужно при использовании стрелок на клавиатуре.
Рисунок 5. Правильное расположение элементов в разметке (слева) и измененное с помощью flexbox визуальное расположение объектов (справа).
Ниже код для рисунка 5. Разметка никогда не изменяет порядок отображения элементов.
<div> <header role=»banner»></header> <main role=»main»></main> <footer role=»contentinfo»></footer> </div>
<div> <header role=»banner»></header> <main role=»main»></main> <footer role=»contentinfo»></footer> </div> |
А это стили, с помощью которых получается правая часть изображения 5.
.container { display: flex; flex-direction: columns; /* по умолчанию row */ } header { order: 2; } main { order: 3; } footer { order: 1; }
.container { display: flex; flex-direction: columns; /* по умолчанию row */ }
header { order: 2; }
main { order: 3; }
footer { order: 1; } |
Этот шаблон используется не только для меню, но и для футера.
Рисунок 6. Точно такой же шаблон, только теперь он применен для футера.
Определитесь, как контент должен располагаться внутри контейнера и сколько места он будет занимать. Расположить основной контент в центре или сдвинуть его вниз? Как это повлияет на остальные элементы дизайна? Составляйте такие вопросы для каждого проекта, прежде чем начать. Для конечных пользователей также крайне важна правильная навигация с помощью кнопок на клавиатуре.
Инлайновые input’ы
Формы могут быть сущим адом, особенно если они были заточены под шаблон сетки в форошопе. «Инлайновые лейблы» укоренились в веб-дизайне так же, как и легендарная гитара Fender Stratocaster в рок музыке.
Рисунок 7. Еще один прекрасный способ применить flexbox – инлайновые лейблы и инпуты. Но внимательно следите за длиной текста в лейбле, чтобы он не сдвигал инпут на новую строку.
Как я сказал в предыдущей главе, вам необходимо решить, где будет располагаться основной контент, как он будет занимать отведенное для него пространство при изменении размера окна браузера или появлении динамического контента.
Рисунок 8. Необходимо решить, как будет расположен контент. Слева таблица с вертикальным выравниванием посередине. Справа flexbox с выравниванием элементов по центру.
Этот скриншот явно указывает на недостатки flexbox при работе с динамическим или очень длинном контентом. Эффект на правом изображении я называю «центральный сдвиг», контент движется от центра к краям вдоль осей X и Y. Разметка рисунка 8.
<div> <label>…</label> <select>…</select> </div>
<div> <label>…</label> <select>…</select> </div> |
Чтобы контролировать длинный текст в это случае лучше воспользоваться свойством display: table. В таком случае контент будет просто идти вниз, а не из центра к краям.
.form-group { display: flex; } .form-group label { display: table; vertical-align: middle; } .form-group input { flex: 1; }
.form-group { display: flex; }
.form-group label { display: table; vertical-align: middle; }
.form-group input { flex: 1; } |
Совместное использование display table и flexbox это отличная методика. Я рекомендую вам ее изучить. При использовании обоих свойств постоянно смотрите на появление багов.
Рисунок 9. Инлайновые инпут и кнопка. Одинаковая высота балансирует дизайн.
Я повидал множество похожих шаблонов поля поиска. Данный шаблон настолько универсален, что его можно применить на совершенно любом макете. Конечно, существуют отдельные CSS свойства, связанные с контекстом, но они хранятся отдельно. HTML разметка типична: DIV оболочка с элементами, создающие структуру flexbox:
<div> <input type=»text» placeholder=»Add a note…»> <button>Add</button> </div>
<div> <input type=»text» placeholder=»Add a note…»> <button>Add</button> </div> |
.form-group { display: flex; } .form-group input { flex: 1; }
.form-group { display: flex; }
.form-group input { flex: 1; } |
Выпадающее меню
Рисунок 10. С помощью парочки flexbox способов область выпадающего меню слегка подсвечена.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнееМеню содержит колонку слева, содержащую линейные элементы с вертикальным позиционированием по центру, и список элементов справа, где каждый элемент находится на своей строке.
Рисунок 11. Для первичного меню при создании меню использовался исключительно flexbox.
Разметка меню:
<nav> <div> <a href=»export-data.html»>Export</a> <a href=»help.html»>Get Help</a> </div> <div> <a href=»account.html»>Account</a> <a href=»preferences.html»>Preferences</a> <a href=»users.html»>Users</a> <a href=»payment.html»>Payments</a> <a href=»logout.html»>Logout</a> </div> </nav>
<nav> <div> <a href=»export-data.html»>Export</a> <a href=»help.html»>Get Help</a> </div>
<div> <a href=»account.html»>Account</a> <a href=»preferences.html»>Preferences</a> <a href=»users.html»>Users</a> <a href=»payment.html»>Payments</a> <a href=»logout.html»>Logout</a> </div> </nav> |
CSS стилей очень мало и их легко читать. Все как любят разработчики.
.menu { display: flex; } .menu__options { display: flex; align-items: center; } .menu__items { display: flex; flex-direction: column; }
.menu { display: flex; }
.menu__options { display: flex; align-items: center; }
.menu__items { display: flex; flex-direction: column; } |
Пара строк кода и получается идеальная верстка. Кроме всего прочего, данное меню автономно, а стили и разметка полностью семантичны. Вот и еще один пример преимущества flexbox перед замысловатым позиционированием и костылями в разметке.
Рисунок 12. Шаблон с медиа объектом. SVG фиксированной ширины расположен слева, а справа примыкает контент.
В этом универсальном шаблоне, известном как «медиа объект», такие элементы как изображения или видео располагаются по одну сторону, а контент прилегает к ним по другую.
<div> <div>…</div> <div>…</div> </div>
<div> <div>…</div> <div>…</div> </div> |
.medi-obj { display: flex; align-items: flex-start; } .media-obj__body { flex: 1; }
.medi-obj { display: flex; align-items: flex-start; }
.media-obj__body { flex: 1; } |
Я рекомендую прочитать всем статью Solved by Flexbox Philip Walton на его сайте. Филипп дает полезные советы применения конкретных шаблонов вместе с flexbox, а также он постоянно обновляет все шаблоны в своем репозитории.
С этим шаблоном flexbox работает идеально, однако следите за тем, как прилегающий контент будет вести себя при изменении размера окна браузера. На видео выше видно, как уменьшается расстояние между изображением и тексом, и текст, в конце концов, накладывается поверх изображения. Быть может это глуповатый пример. Кто из здравомыслящих людей будет так сильно сжимать окно браузера? Но перед использованием flexbox очень важно понять, как контент взаимодействует с окружением. Решением будет установить для изображения max-width: 100%.
Календарь.
Было бы очень глупо не вспомнить про календарь. Вы можете задаться вопросом «А почему не воспользоваться таблицей?». Календарь построен по методике date-picker, и я решил разграничить кнопки дней, месяцев и года (каждый недельный ряд находится в отдельном DIV). Такой подход облегчит разметку. Большое спасибо Shane Hudson за объяснение методики. Разметка календаря на самом деле крайне проста.
<div> <header> <button>Left Arrow</button> <span>2015</span> <button>Right Arrow</button> </header> <div> <button>Jan</button> <button>Feb</button> </div> </div>
<div> <header> <button>Left Arrow</button> <span>2015</span> <button>Right Arrow</button> </header>
<div> <button>Jan</button> <button>Feb</button> </div> </div> |
Код CSS очень короткий, короче просто быть не может. И тем не менее он понятен.
.flex-container { display: flex; } .datepicker__header { justify-content: space-between; } .datepicker__view { align-items: center; justify-content: flex-start; }
.flex-container { display: flex; }
.datepicker__header { justify-content: space-between; }
.datepicker__view { align-items: center; justify-content: flex-start; } |
Рисунок 14.Слева используется justify-content: space-between. Справа justify-content: flex-start.
Эти два примера наглядно показывают, почему лучше все планировать заранее. Как контент будет вести себя в блоке-обертке? Как контент будет вести себя при изменении окна браузера? А нужно ли вообще создавать контейнер? Все эти вопросы очень важны на начальном этапе разработки.
Макет
Flexbox не только отлично подходит для элементов интерфейса, но и для определенных шаблонов. Типичная картина это первый контейнер в одну сторону, а дополнительный в другую.
Рисунок 15. Сайдбар слева и основной контент справа – идеальный сценарий для flexbox. Это напомнило мне о технике имитации колонок.
Код также очень маленький, как и код для старых браузеров. Разметка панели администратора построена на нескольких DIV’ах.
<div> <div>…</div> <div> <nav>…</nav> <main>…</main> </div> </div>
<div> <div>…</div>
<div> <nav>…</nav> <main>…</main> </div> </div> |
.admin-ui__body { display: flex; } .admin-ui__body nav { flex: 30%; } .admin-ui__body main { flex: 70%; }
.admin-ui__body { display: flex; }
.admin-ui__body nav { flex: 30%; }
.admin-ui__body main { flex: 70%; } |
Такой подход отлично подходит для случая со старыми браузерами, как на рисунке 14. Шаблон крайне прост. В любой момент можно добавить display: table.
В этом примере CSS 2 свойство display: table-cell это отличный фолбэк под старые браузеры. Элементы ведут себя, как ячейки таблицы. А нам именно такое поведение и нужно, ведь оно полностью имитирует работу flexbox. С помощью display: table-header-group и display: table-footer-group даже можно изменить порядок отображения элементов.
Sticky футер
Sticky футер одна из основных проблемы для начинающих разработчиков. Основная задача приклеить футер к низу страницы. При добавлении контента, футер просто сдвигается чуть ниже, но все равно остается в самом низу страницы.
Рисунок 16. Стики футер в правом сайдбаре.
<div> <button>Save Deal</button> <div> <p>…</p> <button>Copy</button> <button>Delete</button> </div> </div>
<div> <button>Save Deal</button>
<div> <p>…</p> <button>Copy</button> <button>Delete</button> </div> </div> |
.admin-edit { display: flex; flex-direction: column; justify-content: space-between; }
webformyself.com
Примеры использования Flexbox / Habr
Продолжаю публикацию статей Rachel Andrew по особенностям CSS-технологии Flexbox
Предыдущие статьи цикла:
- Что происходит при создании контейнера Flexbox.
- Все, что вам нужно знать о выравнивании во Flexbox.
- Flexbox: насколько велика эта гибкая коробка?.
Мы подошли к заключительной части моей серии о Flexbox здесь, в Smashing Magazine. В этом посте я собираюсь потратить некоторое время на размышления о том, каковы на самом деле варианты использования Flexbox, учитывая, что теперь у нас есть CSS Grid Layout, дам некоторые предложения о том, что вы можете использовать, когда и как.
Ранее в этой серии
Если вы еще не выбрали другие статьи, это, по сути, заключительный пост, поэтому сначала посмотрите их. Я начала с описания того, что происходит при создании контейнера flex. Во второй статье серии я взглянула на выравнивание и на то, как мы выравниваем элементы по главной и поперечной осям во flexbox. В третьей статье я распаковываю, как работает изменение размера в Flexbox, и как браузер определяет, насколько большим должен быть flex-элемент. Теперь, когда мы точно знаем, как работает Flexbox, мы можем обернуться, чтобы подумать о примерах использования, для которых это лучше всего.
Я должна использовать Grid или Flexbox?
Это по-прежнему главный вопрос, который мне задают при обучении компоновке, и в целом я считаю, что по мере того, как люди все больше привыкают к работе с новыми методами, это становится вопросом, который вам нужно задавать себе реже. По мере роста опыта вы будете понимать, какой метод компоновки использовать.
Однако, если вы только начинаете ухватывать эту мысль, следует помнить, что CSS Grid Layout и Flexbox оба являются CSS. Если вы указали display: grid
или display: flex
, вы часто используете больше общего, чем различий. И Grid, и Flexbox используют свойства, которые являются частью спецификации Box Alignment; оба опираются на концепции, детализированные в спецификации CSS Intrinsic and Extrinsic Sizing..
Спрашивать, должен ли ваш дизайн использовать Grid или Flexbox подобно вопросу должен ли ваш дизайн использовать размер шрифта или цвет. Вероятно, вы должны использовать оба, если требуется. И никто не будет преследовать вас, если вы воспользуетесь не тем.
Итак, мы не выбираем между Vue.js и React, Bootstrap или Foundation. Мы используем CSS, чтобы выполнить компоновку, и нам нужно использовать частицы CSS, которые имеют наибольший смысл для конкретной части нашего дизайна, над которым мы работаем. Рассмотрите каждый компонент и решите, что лучше для него, или какая комбинация элементов лучше для него.
Это может быть Grid, или это может быть Flexbox. Это может быть внешний контейнер Grid, в котором некоторые элементы сетки становятся гибкими или реверсивными. Нет проблем с вложением сетки в элемент flex, если это требуется для вашего проекта.
Что такое Flexbox на самом деле?
Спецификация Flexbox описывает метод компоновки так:
«Flex layout внешне похож на block layout. В нем отсутствуют многие более сложные текстовые или документо-ориентированные свойства, которые можно использовать в компоновке блоков, такие как floats и columns. Взамен он получил простые и мощные инструменты для распределения пространства и выравнивания контента способом, в котором давно нуждались веб-приложения и сложные веб-страницы.”
Я думаю, что ключевая фраза здесь “распределение пространства и выравнивание контента”. Flexbox — это все о том, чтобы взять кучу элементов (которые имеют разные размеры) и поместить их в контейнер (который сам может быть переменного размера). Flexbox — это мягкость. Он пытается создать наилучший макет для наших элементов, давая большим элементам больше пространства, а меньшим элементам меньше пространства, тем самым сохраняя читаемость контента.
Если люди находят Flexbox сложным и загадочным, это часто потому, что они пытаются использовать Flexbox как grid-систему, пытаясь вернуть контроль над размером и распределением пространства. Когда вы это делаете, Flexbox может показаться странным и сложным, поскольку вы боретесь с тем, что и делает его Flexbox‘ом, т.е. с присущей ему гибкостью.
Поэтому шаблоны, которые очень хорошо подходят для гибкой компоновки, это те, в которых нас не так интересует наличие идеального размера каждого элемента. Мы просто хотим, чтобы эти элементы отображались рядом друг с другом.
Существуют также шаблоны, в которых вы хотите иметь строки с переносом, однако вам не нужна строгая сетка. Если мы возьмем оригинальный пример Grid против Flexbox, где мы используем в сетке синтаксис repeat auto-fill, а затем flex-контейнер с переносом строк, то сразу увидим разницу между этими двумя методами.
В примере Grid элементы сетки выстраиваются в строки и столбцы. Когда число столбцов трека изменяется (в зависимости от пространства), элементы всегда переходят в следующую доступную ячейку сетки. На самом деле, нет никакого способа запросить элемент сетки окружить трек, чтобы заполнить по auto-flow сценарию, если есть другие пустые ячейки.
В примере flex итоговые элементы разделяют пространство, оставшееся между ними, таким образом, мы не используем выравнивание по горизонтали и вертикали.
Если у нас flex-basis установлен в auto, и любой из flex-элементов увеличивается, то остальным также будет предоставлено дополнительное пространство, чтобы выравнивание могло быть различным от строки к строке.
Это очень яркий пример того, где мы хотели бы использовать Flexbox над Grid Layout. Если мы хотим, чтобы элементы были обернуты, но занимали пространство, в котором они нуждались, по строкам. Это очень отличается от сетки. Шаблоны, подобные этому, могут представлять собой набор тегов (один или два слова, которые вы хотите хорошо отображать в виде набора элементов), занимающих необходимое пространство, а не жестко вставленных в строгую сетку.
В настоящее время Flexbox также является лучшим способом выполнения вертикального и горизонтального центрирования элемента внутри контейнера.
В будущем (если будет поддержка браузерами свойств Box Alignment вне гибкого макета), мы можем сделать это, не добавляя display: flex в контейнер. На данный момент, однако, все, что вам нужно сделать, это дополнительная строка CSS, что не является проблемой.
Flexbox очень хорошо справляется с небольшими одномерными компонентами. Наборы полей формы, иконок или другой информации можно легко расположить и позволить им быть гибкими без необходимости тщательно устанавливать размеры каждого элемента.
Вы также можете выбрать Flexbox в сценарии, где контент нужно привести к низу контейнера, не давая ему всплывать. В примере, расположенном ниже, я делаю контейнер flex-контейнером, отображая содержимое в виде столбца, а затем позволяю середине расти, выталкивая footer вниз компонента.
При разработке я нахожу, что Flexbox полезен для множества небольших заданий, выполняя правильно выравнивание, распределяя пространство между элементами. Вы безусловно можете использовать одномерный контейнер сетки для некоторых из этих задач, и не беспокоится о том, что вы решили сделать.
Однако я думаю, что Flexbox будет лучшим в ситуации, когда потребуется добавлять дополнительные элементы, которые я не ожидала в своем дизайне. Например, если у меня есть компонент навигации, использующий Grid, я бы создала достаточно треков для всех элементов, так как я не хотела бы, чтобы создавалась новая строка, если бы у меня было “слишком много” элементов. С flexbox, достаточно длинным, я бы разрешил элементам быть гибкими с flex-basis 0 (или auto), тогда бы элементы сами пускали нового компаньона в строку, освобождая ему место.
Когда не следует использовать Flexbox?
Мы рассмотрели некоторые соображения, по которым, я думаю, вы должны предпочесть Flexbox перед Grid компоновкой, поэтому теперь мы можем осмотреть некоторые из мест, где Flexbox может быть не лучшим выбором. Мы уже рассматривали наш пример Flexbox против сетки с элементами, выровненными по горизонтали и вертикали против элементов, которые занимают пространство построчно. И это различие — первое, что нужно учитывать.
Пример сетки имеет двумерную компоновку. Компоновка по строкам и столбцам одновременно.
Пример Flexbox это одномерная компоновка. Мы упаковали flex-строки, но размещение в пространстве происходит построчно. Каждая строка, по сути, выступает в качестве нового flex-контейнера во Flex-направлении.
Поэтому, если ваш компонент нуждается в двумерной компоновке, вам будет лучше использовать Grid, а не Flexbox. Не имеет значения, большой или маленький компонент. Если вы возьмете одну вещь из этой статьи, то это удалите идею из вашей головы, что Grid почему-то предназначена только для макета главной страницы, а Flexbox для компонентов. Вы можете иметь крошечный компонент, который требует двумерного макета, и структуру главной страницы, которой лучше подходит одномерный макет.
Еще одно хорошее место, где Grid может считаться лучшим решением, это применение ширины или установка flex-basis в качестве единицы длины ваших flex-элементов, чтобы выровнять их с другой строкой flex-элементов или просто ограничить гибкость в некотором роде. Довольно часто это указывает либо на то, что вам действительно нужен метод двумерного макета, либо на то, что элемент управления из grid-контейнера лучше подходит для вашего макета.
Например, мы могли бы сделать наш гибкий макет более похожим на Grid, ограничив гибкость наших элементов. Установка flex-grow в 0 и расчет размеров элементов в процентах, аналогично тому, как мы определяли размер элементов в плавающей «сетке». Если вы обнаружите, что делаете это, я бы предположила, что макет сетки — лучший подход, поскольку он предназначен для этого типа макетов.
При всем сказанном помните, что очень часто нет четкого правильного или неправильного ответа. Иногда единственное, что вы можете сделать, это попробовать разные способы и посмотреть, что лучше всего подходит для компонента. Помните, что вы также можете переключать методы макета, используя Flexbox в одной точке останова, а Grid в другой.
И так, сворачиваемся!
Я надеюсь, что эта серия по Flexbox была полезной и продемонстрировала как понимание некоторых алгоритмов выравнивания и калибровки flex-элементов облегчает жизнь при работе с ними.
Если у вас остались какие-либо нерешенные вопросы или у вас есть шаблон, который, похоже, не имеет очевидного ответа с точки зрения используемого метода компоновки, оставьте комментарий.
habr.com
Верстаем новостной сайт с помощью Flexbox / Habr
Примечание: этот материал представляет собой свободный перевод статьи Джереми Томаса о том, как просто работать с Flexbox на примере верстки шаблона новостного сайта.
Поверьте, нет никакой необходимости в детальном разборе всех аспектов работы с Flexbox, если вы хотите начать им пользоваться уже сейчас. В этом руководстве автор собирается познакомить вас с некоторыми свойствами Flexbox и сделать «новостной лейаут» наподобие того, который вы могли видеть на сайте The Guardian.
Причина, по которой автор использует Flexbox – это большое количество возможностей, которые он предоставляет:
— легкость в создании адаптивных столбцов;
— создание столбцов одинаковой высоты;
— возможность прижатия содержимого к низу контейнера.
Ну, поехали!
1. Начинаем с создания двух столбцов
Создание столбцов при помощи CSS всегда влекло за собой определенные трудности. На протяжении длительного времени для выполнения данной задачи широко использовались (и используются) float’ы и / или таблицы, но каждый из этих методов имел (и имеет) свои недостатки.
В свою очередь, Flexbox упрощает этот процесс, обладая рядом таких преимуществ, как:
— написание более «чистого» кода: от нас лишь требуется создать контейнер с правилом display: flex;
— гибкость: мы можем изменять размер, растягивать и выравнивать столбцы путем изменения пары строк CSS;
— семантическая разметка;
— кроме того, с использованием Flexbox отпадает необходимость отменять обтекание во избежание непредсказуемого поведения лейаута.
Давайте начнем работу с создания двух столбцов, один из которых будет занимать 2/3 ширины нашего контейнера, а еще один — 1/3 его часть.
<div>
<div>
2/3 column
</div>
<div>
1/3 column
</div>
</div>
Здесь присутствуют два элемента:
— контейнер 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 для того, чтобы «прижать» информационную панель к низу элемента. Вот, посмотрите, какой результат мы ожидаем получить.
А вот и сам код:
<a>
<figure>
<img src="">
</figure>
<div>
<h3>
<!-- Заголовок -->
</h3>
<p>
<!-- Контент -->
</p>
<footer>
<!-- Информация -->
</footer>
</div>
</a>
.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, который мы использовали ранее.
<div>
<div>
<a>
<!-- Содержимое статьи -->
</a>
</div>
<div>
<a>
<!-- Содержимое статьи -->
</a>
<a>
<!-- Содержимое статьи -->
</a>
<a>
<!-- Содержимое статьи -->
</a>
</div>
</div>
Поскольку мы хотим, чтобы первый вложенный столбец был шире, добавим к элементу класс 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 в своих проектах можно даже не вникая во все его тонкости, и созданный лейаут — наглядный тому пример. По крайней мере, автор очень надеется на это.
habr.com
11 вещей которые я узнал, читая спецификацию flexbox / Habr
Я всегда считал, что с flexbox довольно легко работать — глоток свежего воздуха после стольких лет float’ов и clearfix’ов.
Правда недавно я обнаружил что борюсь с ним; что-то растягивалось, когда я не думал, что оно должно тянуться. Я поправил здесь, другой элемент сжался. Я починил это, что-то другое ушло за экран. Какого Джорджа Буша тут происходит?
В конце концов, все заработало, но солнце село, а мой процесс был привычной игрой с CSS. Или… как называется та игра, где надо ударить крота, а затем другой крот выпрыгивает и надо ударить и его тоже?
Как бы там ни было, я решил что пора вести себя как взрослый разработчик и выучить flexbox должным образом. Но вместо того, чтобы прочитать 10 очередных блог-постов, я решил отправиться прямиком к исходнику и прочитать The CSS Flexible Box Layout Module Level 1 Spec
Вот хорошие отрывки.
1. Margin обладает особыми силами
Я думал, что если, например, ты хочешь заголовок с логотипом и названием сайта слева, а кнопкой логина справа…
… тебе следует дать названию flex: 1, чтобы прижать остальные элементы к другому концу строки.
Вот почему flexbox — Очень Хорошая Вещь. Простые вещи такие простые.
Но возможно, по какой-то причине, ты не хочешь тянуть элемент только для того чтобы прижать другой элемент вправо. Может, потому что у элемента есть подчеркивание, изображение или какая-либо третья причина, которую я не могу придумать.
Отличные новости! Вместо этого, ты можешь сказать прямо: «прижми этот элемент вправо», определив margin-left: auto на нужном элементе. Думай об этом как о float: right.
Например, если элемент слева является изображением:
Мне не нужно применять flex к изображению, мне не нужно применять space-between к flex-контейнеру, я просто установлю margin-left: auto на кнопке «Войти» («Sign in»):
.header {
display: flex;
}
.header .logo {
/* nothing needed! */
}
.header .sign-in {
margin-left: auto;
}
Тебе может показаться это некоторым хаком, но нет, это прямо там в обзоре спецификации как способ прижать flex-элемент в конец flexbox’а. У способа даже есть своя глава: «Выравнивание с авто margin’ами».
О, мне также следует здесь упомянуть, что я предполагаю flex-direction: row везде в этом блог-посте, но все применимо также и к row-reverse или column или column-reverse.
2. min-width имеет значение
Возможно, ты думаешь, что несложно заставить все flex-элементы внутри flex-контейнера сжиматься, для того чтобы уместить контент. Наверняка, если ты укажешь flex-shrink: 1 на элементах, они так и будут себя вести, правда?
Может, пример.
Скажем, у тебя есть часть DOM, которая отображает книгу на продажу и кнопку чтобы ее купить.
Любопытная бабочка
Спойлер: бабочка умрет в конце.
Ты разместил все с помощью flexbox и все хорошо.
.book {
display: flex;
}
.book .description {
font-size: 30px;
}
.book .buy {
margin-left: auto;
width: 80px;
text-align: center;
align-self: center;
}
(Поскольку ты хочешь кнопку «Купить» справа — даже для очень коротких названий — ты, будучи умным, указал margin-left: auto)
Название книги довольно длинное, поэтому оно использует столько пространства сколько может и затем переходит на следующую строку. Ты счастлив, жизнь прекрасна. Ты блаженно отправляешь свой код в продакшн, с уверенностью, что он выдержит все.
И потом получаешь неприятный сюрприз. Совсем не хорошего рода.
Некий дурень, много о себе возомнивший, написал книгу с длинным словом в названии.
Все сломано!
Если красная граница обозначает ширину смартфона, и ты скрываешь переполнение (overflow: hidden), ты только что потерял свою кнопку «Купить». Твой коэффициент конверсии — как и эго бедного автора — будет страдать.
(Примечание: к счастью, там где я работаю, есть хорошая QA команда, которая наполнила нашу базу данных разнородным текстом, наподобие такого. В частности, именно эта проблема побудила меня прочитать спецификацию.)
Оказывается, такое поведение происходит из-за того, что min-width элемента описания изначально установлена в auto, что в данном случае равняется ширине слова Electroencephalographically (электроэнцефалографически). Flex-элементу буквально не разрешается быть уже чем это слово.
Решение? Переопределить эту проблемную минимальную ширину min-width: auto установив min-width: 0, указывая flexbox’у, что этот элемент может быть уже, чем содержимое внутри него.
Теперь за управление текстом внутри элемента отвечаешь ты. Я предлагаю перенести слово. Таким образом, твой CSS будет выглядеть так:
.book {
display: flex;
}
.book .description {
font-size: 30px;
min-width: 0;
word-wrap: break-word;
}
.book .buy {
margin-left: auto;
width: 80px;
text-align: center;
align-self: center;
}
Результат будет таким:
Опять же, min-width: 0 не какой-то хак для обхода нелепости, это предлагаемое поведение прямо в спецификации.
В следующем разделе, я вернусь к тому, что кнопка «Купить» совсем не 80 пикселей по ширине, как я довольно ясно ей сказал.
3. Авторы flexbox обладают хрустальным шаром
Как вы возможно знаете, свойство flex является краткой записью flex-grow, flex-shrink и flex-basis.
Должен признать, я потратил энное количество минут, гадая-проверяя различные значения для этой тройки, когда пытался заставить элементы тянуться так, как надо мне.
Что я не знал до сей поры, это то, что, в общем случае, я хочу одну из трех комбинаций:
- Если я хочу, чтобы элемент немного сжимался, когда места недостаточно, но не тянулся шире чем ему надо: flex: 0 1 auto
- Если мой flex-элемент должен тянуться для заполнения всего доступного пространства, и немного сжиматься если места не хватает: flex: 1 1 auto
- Если мой элемент не должен менять размеры совсем: flex: 0 0 auto
Надеюсь, что ты пока не на максимальном изумлении — сейчас станет еще поразительнее.
Видишь ли, Бригада Flexbox’а (мне нравится думать, что команда flexbox’а носит кожаные куртки с этой надписью сзади — доступны мужские и женские размеры). Где там было это предложение? Ах да, Бригада Flexbox’а знала, что я хочу эти три комбинации свойств в большинстве случаев. Поэтому они дали им ключевые слова специально для меня.
Первый случай — это значение initial так что ключевое слово не нужно. Для второго случая используется flex: auto, и flex: none замечательно простое решение чтобы элемент не тянулся совсем.
Кто бы мог подуть! (Who woulda thunk it — игра слов, прим. переводчика)
Это как если бы было box-shadow: garish, что по умолчанию равнялось 2px 2px 4px hotpink потому что считалось «полезным значением по умолчанию».
Вернемся к невероятно уродливому книжному примеру. Чтобы сделать ту кнопку «Купить» стабильно широкой для попадания пальцем…
… мне всего лишь надо задать на ней flex: none:
.book {
display: flex;
}
.book .description {
font-size: 30px;
min-width: 0;
word-wrap: break-word;
}
.book .buy {
margin-left: auto;
flex: none;
width: 80px;
text-align: center;
align-self: center;
}
(Да, я мог бы указать flex: 0 0 80px; и сэкономить строку CSS. Но есть что-то особенное в том, как ясно flex: none демонстрирует намерение кода. Это хорошо для Будущего Дэвида который забудет как это все работает.)
4. Есть такая вещь inline-flex
По правде говоря, я узнал, что есть такая вещь как display: inline-flex несколько месяцев назад. И то, что она создаст инлайновый flex-контейнер, вместо блочного.
Но по моей оценке, 28% людей еще не знали этого, так что… теперь знайте, нижние 28%.
5. vertical-align не влияет на flex-элемент
Возможно это то, что я знал наполовину, но я уверен, что в какой-то момент, когда пытался задать правильное выравнивание, я мог испробовать vertical-align: middle и пожать плечами, когда это не сработало.
Теперь я знаю наверняка, прямо из спецификации, что «вертикальное выравнивание не влияет на flex-элемент» (так же как и float, замечу).
6. Не используй margin или padding в %
Это не просто уровня «лучшая практика», это уровня «совет-от-бабушки», так что просто делай что говорят и не задавай вопросов.
«Авторам следует полностью избегать использования процентов в padding’ах или margin’ах на flex-элементах» — с любовью, спецификация flexbox.
За этим следует моя самая любимая цитата из всех, когда-либо существовавших, спецификаций:
Заметка: это разночтение отстой, но оно в точности отражает текущее состояние мира (нет консенсуса среди реализаций, и нет консенсуса внутри CSSWG)…
Осторожно! Бомбардировка честностью продолжается.
7. Margin’ы соседних элементов не схлопываются
Возможно, ты уже знаешь, что margin’ы иногда объединяются вместе. Ты также можешь знать, что margin’ы не объединяются вместе в некоторых других случаях.
И теперь мы все знаем, что margin’ы соседних flex-элементов никогда не объединяются.
8. z-index работает даже если position: static
Я не уверен, что мне есть дело до этого. Но я чувствую, что в один день, может быть, это пригодится. Это в точности та же причина, по которой я держу бутылку лимонного сока в холодильнике.
Однажды в моем доме будет другой человек, который скажет типа «эй, у тебя есть лимонный сок?», а я типа «конечно, в холодильнике», а он «спасибо, приятель. Эй, а надо ли мне указывать position если я хочу задать z-index на flex-элементе?», и тут я такой «не братан, не для flex-элементов».
9. Flex-basis тонкое и важное свойство
Когда твои требования перерастут ключевые слова initial, auto и none, все станет немного сложнее, и теперь, когда я понял flex-basis, забавно, знаешь, я не могу придумать как закончить это предложение. Оставь комментарий, если у тебя есть идеи.
Если у тебя есть три flex-элемента с flex-значениями 3, 3, 4, тогда они гарантированно займут 30%, 30% и 40% доступного пространства, независимо от их содержимого, если их flex-basis равен 0. И только если он равен нулю.
Тем не менее, если ты хочешь чтобы flex вел себя в более дружественной, предсказуемой манере, используй flex-basis: auto. В этом случае flexbox примет твои flex-значения во внимание, но также учтет и другие факторы, подумает немного, и подберет ширины, подходящие по его мнению тебе.
Взгляни на эту четкую диаграмму из спецификации:
Я уверен, что это упомянуто по меньшей мере в одном из блог-постов про flex, которые я читал, но по какой-то причине, не проникся пока не увидел эту картинку в спецификации (schmick pick in the spec)(тройная рифма если ты из Новой Зеландии).
10. align-items: baseline
Когда я хотел выравнять flex-элементы по вертикали, я всегда использовал align-items: center. Но также как с vertical-align, у тебя есть возможность установить значение в baseline, что может быть более подходящим если у твоих элементов различный размер шрифта, а ты хочешь выравнять их базу.
Возможно очевидно, align-self: baseline тоже работает.
11. Я довольно глуп
Сколько бы раз я не читал следующий параграф, я остался неспособным его понять…
Размер содержимого — это минимальный размер содержимого на основной оси, зажатый, если он имеет соотношение сторон, с помощью любых определенных минимальных и максимальных свойств кросс-размера, преобразованных через соотношение сторон, а затем дополнительно зажатых с помощью свойства максимального основного размера, если это определено.
Оригинальный вариант
The content size is the min-content size in the main axis, clamped, if it has an aspect ratio, by any definite min and max cross size properties converted through the aspect ratio, and then further clamped by the max main size property if that is definite.
Слова проходят через мои отверстия, преобразуются в электрические импульсы, путешествующие по моему оптическому нерву, и прибывают как раз вовремя, чтобы увидеть как мой мозг выбегает через черный ход в клубе дыма.
Как будто Минни Маус и Мэд Макс завели ребенка семь лет назад, и теперь он, будучи пьяным с мятного шнапса, оскорбляет всех в пределах слышимости словами, которые он узнал когда Мамочка и Папочка ругались.
Леди и Джентльмены, мы начали наш спуск в чепуху, что значит пришло время подвести итоги (или перестань читать, если ты здесь для изучения нового).
Самое интересное из того, что я узнал, читая спецификацию, это то, насколько неполным было мое понимание, несмотря на полдюжины блог-постов которые я прочитал, и на то, насколько относительно простым является flexbox. Оказывается, что «опыт» — это не просто занятие одним и тем же из года в год.
С удовольствием могу отметить, что время, потраченное мной на чтение, уже окупилось. Я прошелся по старому коду, выставил авто margin’ы, flex-значения в краткой записи auto или none, и задал минимальную ширину в ноль там, где это было нужно.
Я лучше отношусь к этому коду теперь, зная что я делаю это должным образом.
Еще я узнал, что несмотря на то, что спецификация — местами — перенасыщена и предназначена для вендоров как я и думал, все же содержит много дружественных слов и примеров. В ней даже выделены части которые скромные веб-разработчики могут пропустить.
Однако это спорный вопрос, потому что я рассказал тебе про все хорошие отрывки, так что тебе не нужно утруждать себя ее чтением.
Теперь, если позволите, мне надо идти и прочитать все остальные CSS спецификации.
P.S. Я крайне рекомендую прочитать следующий список всех flexbox багов по браузерам:
github.com/philipwalton/flexbugs
От переводчика: это мой первый опыт перевода зарубежных публикаций, если есть замечания/предложения/ремарки по качеству перевода или по содержимому, пишите в комментариях.
Оригинальный пост здесь: hackernoon.com/11-things-i-learned-reading-the-flexbox-spec-5f0c799c776b
habr.com
Flexbox несколько полезных примеров для работы
В данной статье мы разберём 5 приёмов, решающие основные проблемы компоновки CSS. Мы также добавили несколько практических примеров из реальных проектов, в которых наглядно показано, как данные приёмы могут быть использованы.
Создание столбцов с одинаковой высотой
Сначала это может выглядеть довольно простым, но эта задача иногда способна раздражать. Использование min-height
не сработает, потому как с появлением некоторого контента размер столбцов сразу же начнёт изменяться.
Устранение этой проблемы с помощью flexbox также не является решением, поскольку столбцы, созданные с flexbox CSS, будут изначально иметь равную длину. Нам всего лишь необходимо ввести «подвижную» модель, а затем удостовериться, что свойства flex-direction
и align-items
заданы правильно.
<div>
<div>...</div>
<div>...</div>
<div>...</div>
</div>
.container {
display: flex; /* Инициализация "гибкой" модели */
/* Это стандартные значения, но вы всё равно можете их изменить*/
flex-direction: row; /* Элементы внутри контейнера будут расположены горизонтально */
align-items: stretch; /* Элементы внутри контейнера будут растянуты по всей высоте */
}
Чтобы увидеть демонстрацию этого приёма, вы можете перейти к статье «Самый простой способ создать столбцы равной высоты».
Перестановка элементов
Некогда в прошлом динамическое изменение порядка некоторых элементов являлось задачей, посильной только JavaScript. Но с появлением flexbox этой трудности больше не возникает, так как решение кроется всего лишь в одном свойстве CSS.
Свойство order
, которое позволяет использовать flexbox-вёрстка, говорит само за себя. Оно даёт нам изменять любое количество «гибких» элементов и их последовательность. Единственным параметром этого свойства является целое число, которое определяет положение этого элемента, чем больше числа – тем выше приоритет данного элемента.
<div>
<div>...</div>
<div>...</div>
<div>...</div>
</div>
.container{
display: flex;
}
/* Приоритет по убыванию номеров */
.blue{
order: 3;
}
.red{
order: 2;
}
.green{
order: 1;
}
Свойство order
имеет множество способов для применения. Если вы хотите увидеть некоторые из них, то можете взглянуть на эту статью, в ней мы используем данный приём для создания адаптивного раздела комментариев.
Горизонтальное и вертикальное центрирование
Выравнивание в CSS до сих пор является довольно серьёзной проблемой. Даже если обратиться к поисковику, то тот выдаст кучу решений, большая часть которых будет предлагать использование таблиц и преобразований, что не совсем подходит, если мы говорим об адаптивной вёрстке.
Простым решение будет являться flexbox вёрстка, при помощи которой элементы можно банально передвигать по координатной плоскости, выравнивая его, как вздумается.
<div>
<div>...</div>
</div>
.container{
display: flex;
/* Расположение по центу относительно главной оси */
justify-content: center;
/* Расположение по центу относительно второстепенной оси */
align-items: center;
}
Чтобы оценить это решение в действии и узнать о нём больше, вы можете перейти к статье, которая находится в той же теме.
Создание полностью адаптивных сеток
Многие вебмастера уповают на различные CSS библиотеки и фреймворки, создавая адаптивные сетки. Самым распространённым инструментом в данной области является Bootstrap. Однако, и он не единственный в своём роде. Подобных помощников разработаны уже сотни. Все они относительно неплохо функционируют и могут похвастаться внушительным набором опций, но от одной проблемы им не избавиться никогда – это громоздкость. Следовательно, если вы человек, который любит всё делать самостоятельно, либо просто не желаете ради сетки ставить целый фреймворк, то flexbox-вёрстка выручит вас!
Строка в flexbox сетке – это просто контейнер. Горизонтальными столбцами внутри него может быть любое количество элементов, размер которых задаётся через flex
. Такая модель адаптируется к размеру любого экрана, поэтому конечный результат должен выглядеть хорошо на большинстве устройств. Тем не менее если мы решим, что на экране недостаточно места на горизонтальной плоскости, то макет можно просто превратить в вертикальный с медиа-запросом.
<div>
<div>...</div>
<div>...</div>
<div>...</div>
</div>
.container{
display: flex;
}
/* Классы для каждой колонны с размером. */
.col-1{
flex: 1;
}
.col-2{
flex: 2;
}
@media (max-width: 800px){
.container{
/* Превращаем горизонтальный объект в вертикальный. */
flex-direction: column;
}
}
Вы можете убедиться в вариативности этого приёма в инструкции: Самый простой способ создания респонсивного заголовка.
Создание зафиксированного подвала
У flexbox CSS есть простое решение и этой задачи. Создавая страницу, содержащую закреплённый подвал, прописанный через flex-элементы, не появится необходимости долее думать о том, что он может сдвинуться.
Применение display: flex
к тегу body позволит нам использовать «гибкий режим» при построении всего макета. Когда всё будет готово, то основная часть страницы будет являть одним «гибким» элементом, а подвал другим, это упростит манипулирование их позициями.
<body>
<div>...</div>
<footer>...</footer>
</body>
html{
height: 100%;
}
body{
display: flex;
flex-direction: column;
height: 100%;
}
.main{
/* Главная секция заполнит всё доступное свободное место на странице, которое не занято подвалом */
flex: 1 0 auto;
}
footer{
/* Подвал выделит себе ровно столько места, сколько ему необходимо и не на пиксель больше */
flex: 0 0 auto;
}
Вы найдёте больше информации о данной технике в статье «Лучший путь создания закреплённого подвала».
Заключение
Большая часть браузеров сегодня поддерживает режим гибкого макета, а значит можно с уверенностью сказать, что flexbox готов помочь многим разработчикам.
Надеюсь, что эта статья оказалась полезной для вас и улучшила ваш уровень владения CSS. Удачи!
falbar.ru