Освоение flexbox для современных веб-приложений
HTML&CSS

Освоение flexbox для современных веб-приложений

Оригинал: Harnessing Flexbox For Today’s Web Apps, Karen Menezes

Несмотря на то, что синтаксис может быть изначально запутать, модуль flexbox соответствует своему названию. Он создает интеллектуальные блоки, способные растягиваться и изменять свой визуальный порядок. Он обеспечивает простое решение для проблем, с которыми всегда сталкивались в CSS: вертикальное центрирование и равные высоты. Flex-элементы действительно удобны и с ними приятно работать.

Крис Койер красиво резюмирует flexbox:

Модуль Flexbox Layout (flexible box — «гибкий блок», на данный момент W3C Last Call Working Draft) ставит задачу предложить более эффективный способ вёрстки, выравнивания и распределения свободного места между элементами в контейнере, даже когда их размер неизвестен и/или динамический (отсюда слово «гибкий»).

Главная идея flex-лайаута заключется в наделении контейнера способностью изменять ширину/высоту (и порядок) своих элементов для наилучшего заполнения пространства (чаще всего для поддержки всех видов дисплеев и размеров экранов). Flex-контейнер растягивает элементы для заполнения свободного места или сжимает их, чтобы предотвратить выход за границы.

Flexbox действительно прекрасно себя показывает в HTML5-приложениях. Большинство веб-приложений состоят из ряда модульных, многократно используемых компонентов. Вы можете использовать flexbox для тех участков макета, которые вызывают особую головную боль и для которых в обычных случаях необходимы CSS-хаки. Небольшие участки лайаута очень хорошо работают с flexbox, а для лайаутов большого масштаба можно использовать floats и другие инструменты.

Я c размахом использую flexbox в приложении, над которым сейчас работаю, и я очень доволна тем, как он управляет лайаутом и насколько умно производятся расчеты с блоками. Я хотела бы поделиться некоторыми примерами — буду признателна за любую обратную связь.

Эта статья предполагает, что у вас уже есть представление о flexbox. Множество информации о нем можно найти в интернете. Но имейте в виду, что спецификация претерпела несколько изменений за несколько лет.

Есть три версии flexbox, наибольшая разница в синтаксисе между версиями 2009 и 2012 годов:

  • Новый синтаксис синхронизирован с текущей спецификацией (например, display: flex).
  • Переходный синтаксис — неофициальный синтаксис с 2012 года, поддерживается только IE 10 (например, display: -ms-flexbox).
  • Старый синтаксис с 2009 года (например, display: box).

Поддержка браузерами

Посмотреть более детально, какой браузер какой синтаксис поддерживает можно на Can I Use .

Браузеры, поддерживающие новый синтаксис

Десктоп:

  • без префикса: Chrome 29+, Firefox 28+, IE 11+, Opera 17+
  • с префиксом: -webkit- для Chrome 21+, Safari 6.1+, Opera 15+

Обратите внимание, что старые версии Firefox (22-27) поддерживают новый синтаксис Flexbox за исключением свойств flex-wrap и flex-flow. Opers (12.1+ и 17+) поддерживает flexbox без вендорного префикса, но промежуточные версии 15 и 16 требуют вендорный префикс.

Touch-устройства:

  • без префикса: Android 4.4+, Opera mobile 12.1+, BlackBerry 10+, Chrome for Android 39+, Firefox for Android 33+, IE 11+ mobile
  • с префиксом: -webkit- для iOS 7.1+

Почти все браузеры, упомянутые выше, имеют старые версии, которые поддерживают предыдущий вариант синтаксиса flexbox, за исключением некоторых свойств, таких как flex-wrap и flex-flow (последний является сокращением свойств flex-direction и flex-wrap). Если избегать свойства flex-wrap (и, соотвественно, использовать flexbox в многострочных лайаутах), мы получаем потрясающую поддержку браузерами, сливая старый и новый синтаксис.

Браузеры, поддерживающие промежуточный синтаксис

Desktop и touch-устройства: IE 10 (with -ms- vendor prefix)

Браузеры, поддерживающие старый синтаксис

Все перечисленные браузеры требуют префикс -webkit- (за исключением Firefox, которому необходим префикс -moz-).

Десктоп: Firefox 2 — 21, Chrome 4 — 20, Safari 3.1 — 6

Touch-устройства: Android 2.1 — 4.3, iOS 3.2 — 6.1, UC browser 9.9 on Android, BlackBerry 7

Для современных браузеров c авто-обновлением (т.е. десктопных Chrome, Firefox, IE и Opera), новый синтаксис работает из коробки.

Браузеры, не поддерживающие flexbox

Десктоп: Старые версии IE (9) и Opera (12)

Touch-устройства: Opera Mini

Если вас испугали вендорные префиксы и изменения в синтаксисе, посмотрите рекомендации Криса Койера .

Такжен вы можете использовать следующие инструменты, чтобы получить наилучшую поддержку браузерами через префиксы:

Среди этих инструментов я бы рекомендовал Autoprefixer. Я не экспериментировал с другими заточенными под препроцессоры решениями и буду рад отзывам. Обратите внимание, если вы используете миксины CSS-фреймворков (каких как Bourbon или Compass для Sass, Nib для Stylus или LESS Hat for LESS), они уже поддерживают вендорные префиксы для flexbox.

С помощью такого инструмента, как Autoprefixer, вы действительно получите большую поддержку flexbox, за исключением IE 9 и Opera Mini. Конечно, вы должны будете тщательно проверить ваше приложение во всех браузерах, чтобы убедиться, что различный синтаксис поддерживается.

Давайте посмотрим на несколько хороших примеров использования flexbox в веб-приложении.

1. Неопределенное число детей в родительском элементе

Use case: В моем приложении еcть фильтр. Количество фильтров зависит от того, авторизован пользователь или нет. Анонимный пользователь видит два фильтра («Popular» и «Latest»), тогда как авторизованный пользователь видит четыре (добавляются «Starred» и «Favorites»).

Проблема: Я хочу написать стили для обоих вариантов без каких-либо изменений в CSS

Обсуждение: Обычно вы используете выражение if в шаблоне, чтобы проверить, авторизован ли пользователь. Если мы используем float при верстке, то для неавторизованного пользователя мы задаем ширину одного фильтра 50%, а для авторизованного — 25%.

Решение: используя flexbox, вы можете задать свойство display: flex родительскому контейнеру, а дочерним — свойство flex равное 1, сделав таким образом дочерние элементы равной ширины внутри контейнера. Таким образом, CSS остается неизменным не зависимо от количества элементов. Помните, что свойство flex — это сокращение flex-grow, flex-shrinkand flex-basis.

Демо:

See the Pen Flexbox: Parents with an unknown number of children by Karen Menezes (@imohkay) on CodePen.

2. Поля ввода с иконками

Use case: Я хочу добавить смысловые иконки к полям ввода на форме.

Проблема: Я хочу найти гибкое, элегантное решение, которое работает без необходимости указывать высоту и ширину элементов.

Обсуждение: Это одна из классических проблем. Разные CSS-фреймворки решают ее по-разному, в основном, используя display: table-cell или абсолютное позиционирование.

Решение: а теперь flex-решение. Все, что нам нужно, это обернуть поле ввода и иконку в контейнер с display: flex. Затем, применить flex: 1 к полю ввода для того, чтобы оно заняло всю ширину контенера минус ширина иконки.

Демо (используется иконка Font Awesome):

See the Pen Flexbox: Inputs with icons by Karen Menezes (@imohkay) on CodePen.

3. Визуальный порядок элементов

Flexbox может использоваться для изменения визуального порядка элементов без изменения порядка этих элементов в исходном документе. Наша задача, как разработчиков, ответственно использовать силу этих механизмов.

По факту, мы можем структурировать наш документ для поддержки приложений чтения с экрана (к примеру, расположить боковую панель бед основным содержимым в исходном коде) и использовать flexbox для изменения визуального порядка (расположить боковую панель справа от основного контента, используя свойства order и flex-direction). Давайте рассморим этот вопрос подробнее.

А. Изменение визуального порядка с помощью flex-direction

Use case: У меня есть боковая панель, спозиционированная справа от основного содержимого. На маленьких экранах я хочу, чтобы панель располагалась сверху от основного содержимого, т.е. в обратном порядке.

Проблема: Я не хочу использовать JavaScript или CSS хаки для изменения визуального порядка.

Обсуждение: Flexbox — это удивительный инструмент для адаптивных макетов. Мы можем использовать его двумя способами: использовать свойство flex-direction или свойство order. Давайте рассмотрим первый вариант.

Решение: Расположим боковую панель перед основным содержимым в лайауте. У этого есть две причины: во-первых, мы придерживаемся принципа mobile-first, а во-вторых — такое расположение больше подходит для программ чтения с экрана. Зададим свойство flex-direction: column для родительского контейнера (по умолчанию оно имеет значение row). В медиа запросе для больших экранов, изменим значение flex-direction на row-reverse, это решит нашу задачу.

В качестве бонуса, зададим ширину 180px для боковой панели на больших экранах.

See the Pen Flexbox: Sidebar with source order independence using flex-direction by Karen Menezes (@imohkay) on CodePen.

B. Изменение визуального порядка с помощью свойства order

Use case и проблема остаются такими же, как в предыдущем примере.

Обсуждение: Свойство order предоставляет больший контроль над визуальным порядком, чем flex-direction.

Решение: Зададим свойство flex-direction: column родительскому контейнеру для мобильных устройств. Теперь, в медиа запросе min-width изменим свойство flex-direction на row, чтобы боковая панель отображалась слева, а основное содержимое справа. Чтобы изменить порядок элементов, укажем свойство order: 1 для основного содержимого и order: 2 — для боковой панели!

See the Pen Flexbox: Sidebar with source order independence using order by Karen Menezes (@imohkay) on CodePen.

С. Переключение порядка элементов

Use case: Я хочу отобразить список из пяти наиболее высокооплачиваемых актеров Голливуда в 2013 году, и добавить возможность переключения направления сортировки.

Проблема: Я хочу сделать это на чистом CSS, я не знаю почему и вообще не уверен, возможно ли это.

Обсуждение: Это простая демонстрация без использования JavaScript, чтобы показать мощные возможности Flexbox. Возможно, это непрактично и глупо, но давайте посмотрим, возможно ли это вообще.

Решение: Добавим переключатель, который будет изменять порядок элементов от меньшего к большему. Ниже добавим список актеров. Используя псевдо-класс :checked, мы выберем следующий за переключателем список и изменим порядок элементов в нем (в помощью flex-direction: column-reverse). Это довольно странно, но прекрасно работает, если вы не используете приложения для чтения с экрана. В приведенном ниже демо, используйте переключатель, чтобы посмотреть результат. В спецификации упоминается, что свойство order не влият ни на tabindex, ни на программы чтения с экрана, но я бы не рекомендовал этот способ на реальных проектах. Тем не менее этот способ можно использовать для быстрого прототипа.

Обратите внимание: В текущей версии Firefox есть баг — tabindex соответствует визуальному порядку, а не исходному порядку. Вы можете посмотреть тест-кейсы CSS Accessibility Community Group.

See the Pen Flexbox: Toggling a list's order by Karen Menezes (@imohkay) on CodePen.

4. Модуль комментариев

Use case: У меня есть обычный модуль комментариев, с изображением слева и содержимым справа. Аватар всегда одинаковой нирины и высоты (не адаптивный).

Проблема: Я использую flexbox, но содержимое перекрывает изображение:

Если задать max-width 100% и height auto для изображения, получим следующее:

Обсуждение: Этот пример похож на пример «Поля ввода с иконками». Тем не менее, мы можем использовать его для обсуждения свойства flex-shrink, которое может быть полезно в некоторых случаях.

Решение: Добавим свойство display: flex родительскому контейнеру. Вы можете заметить, что содержимое комментария перекрывает аватар (или аватар слишком маленький, как на картинке выше). Чтобы исправить это, добавим к изображению свойство flex-shrink: 0, которое гарантирует, что аватар не будет уменьшаться, подстраиваясь под другие flex-элементы. Альтернативный способ — задать свойство flex: 1 содержимому комментария. В целом, спецификация рекоммедует использовать свойство flex, однако неплохо знать и о свойстве flex-shrink.

See the Pen Comments module with flexbox by Karen Menezes (@imohkay) on CodePen.

5. Комплексное меню

Use case: Меню в моем приложении включает форму поиска и виджет фильтрации. В нем смешаны кнопки, поля ввода, иконки и текст.

Проблема: Я беспокоюсь о том, чтобы лайаут не сломался на разных размерах экрана.

Обсуждение: Это отличный случай, чтобы использовать flexbox. У нас есть несколько элементов фиксированной ширины и несколько элементов, которые должны заполнять всю доступную ширину.

Решение: Мы можем использовать flexbox, чтобы задать вертикальное центрирование и сделать блок фильтраии и поиска адаптивным.

See the Pen Flexbox demo: Search and filter by Karen Menezes (@imohkay) on CodePen.

6. Карточки

Use case: Я делаю модуль карточек для моего приложения на основе компонента Google. В мобильной версии эти карточки выстраиваются в одну колонку.

Проблема: Я хочу, чтобы на больших экранах карточки располагались в строку. Высота карточек в одной строке должна быть одинаковой, но я не хочу создавать дополнительные обертки для строк. Кнопка «See more» должна всегда располагаться внизу карточки.

Обсуждение: Мы можем рассмотреть дополнительные свойства модуля flexbox, такие так margin: auto, чтобы более разумно управлять интервалом.

Решение: Flexbox предоставляет неверояное решение для древней проблемы CSS: выравнивания высот. На самом деле flexbox является настолько гибким, что позволяет сделать карточки в одной строке одинаковой высоты, при этом каждая строка не будет обернута в дополнительный контейнер. Он также позволяет отобразить кнопку «See all» так, как если бы она была абсолютно спозиционирована по низу относительно карточки с помощью margin: auto.

See the Pen Flexbox: Card module by Karen Menezes (@imohkay) on CodePen.

Заключение

Flexbox идеально подходит для гибридного веб-приложения, целевая аудитория которого по большей части пользуется планшетами с современными браузерами. На самом деле, некоторые популярные CSS-фреймворки уже используют flexbox, например, Foundation for Apps и Ionic .

Если ваше приложение требует поддержки только современных браузеров, добро пожаловать на борт! Использование инструментов, таких, как Autoprefixer, облегчает переход в мир flexbox, с его многочисленными версиями и разным синтаксисом.

Пока flexbox используется хорошо вместе с float, но он может и заменить его, а также делать другие вещи, которые не могут другие способы расположения блоков, такие как inline-блоки, display: table или абсолютное позиционирование. CSS Grid Layout Module предназначен для замены таких хаков, как float, но пока этот стандарт находится на ранней стадии и плохо поддерживается браузерами . Однако я смею мечтать, что в будущем мы будем использовать CSS сетки и flexbox, чтобы создавать интуативны пользовательские интерфейсы.

Это займет некоторое время, пока вы скажете «Ага!» flexbox, потому что вам отвыкать от того, что вы уже знаете о расположении блоков CSS. После того, как вы свободно заговорите на языке CSS, процесс проектирования приложений станет для вас более простым, а таблицы стилей будут выглядеть красивее.

Рассылка
Подпишитесь на рассылку и получайте дайджест новостей и статей.
Никакого спама!
Подписаться