Применение Flexbox – комбинация старой и новой версии с целью обеспечения улучшенной поддержки в браузерах.

Перевод статьи:  Using Flexbox: Mixing Old and New for the Best Browser Support.
Автор:  Chris Coyier.

Flexbox представляет собой внушительный инструмент и является неотъемлемой частью макета веб-документа в будущем. За прошедшие несколько лет его синтаксис претерпел некоторые изменения, что привело к понятию нового и старого синтаксиса. Но скомпоновав вместе имеющиеся старый, новый и промежуточный варианты синтаксиса мы можем добиться неплохой поддержки Flexbox модели в браузерах. В большей степени это касается реализации максимально простых и самых распространенных макетов страницы, предусматривающих контроль размещения их компонентов.

HTML основа.

Внешний <div> представляет собой семантически бессмысленный элемент-обертку, охватывающий три основные области страницы и определяющий рамки Flexbox контекста. Каждая из внутренних областей создана с помощью семантически корректной разметки и будет представлять отдельную колонку макета документа.

<div class="page-wrap">

<section class="main-content" role="main">
Main content /* Размещаем этот блок первым в разметке */
</section>

<nav class="main-nav" role="navigation">
Links
</nav>

<aside class="main-sidebar" role="complementary">
Sidebar
</aside>

</div>

Что в результате даст такой внешний вид:

Изображение.

Создаем Flexbox контекст.

Первое, что нам необходимо сделать — это при помощи элемента-контейнера, содержащего три колонки макета, создать Flexbox контекст отображения. Поступая таким образом, мы наделяем все прямые потомки такого элемента свойством гибкости, то есть способностью трансформации их размеров. И не важно, с помощью каких элементов они были реализованы до того, как мы заключили их в этот контекст, теперь они обладают гибкостью, необходимой нам для контроля их размещения.

И именно здесь, в рамках создаваемого нами контекста мы должны использовать комплекс правил, предусмотренных старым, новым и промежуточным синтаксисом модуля Flexbox. Порядок определения этих правил является очень важным моментом. Поскольку само имя свойства не предусматривает никаких префиксов, то мы должны быть уверены в том, что в процессе создания контекста мы не переопределяем новые значения этого свойства, теми, которые предусмотрены ранним синтаксисом в тех браузерах, которые все еще поддерживают (и возможно всегда будут это делать) оба варианта.

.page-wrap {
display: -webkit-box; /* старый синтаксис — iOS 6-, Safari 3.1-6 */
display: -moz-box; /* старый синтаксис — Firefox 19- (не гарантированно, но в большинстве случаев работает) */
display: -ms-flexbox; /* промежуточный синтаксис — IE 10 */
display: -webkit-flex; /* новый синтаксис — Chrome */
display: flex; /* новый синтаксис, предусмотренный спецификацией — Opera 12.1, Firefox 20+ */
}

Контроль ширины колонок.

В результате всех преобразований мы должны получить трех колоночный макет страницы с соотношениями 20% / 60% / 20%.

Во-первых, нам необходимо установить 60%-ю ширину колонки основного контента. И, во-вторых, равномерно распределить оставшееся в нашем распоряжении свободное пространство между боковыми колонками.

И вновь, в процессе установки необходимых значений ширины двух боковых колонок, мы используем все тот же подход – строго последовательную комбинацию правил, предусмотренных различными версиями Flexbox синтаксиса (старым, новым и промежуточным).

.main-content {
width: 60%;
}
.main-nav,
.main-sidebar {
-webkit-box-flex: 1; /* старый синтаксис — iOS 6-, Safari 3.1-6 */
-moz-box-flex: 1; /* старый синтаксис — Firefox 19- */
width: 20%; /* Для предотвращения конфликта нового и старого синтаксисов. */
-webkit-flex: 1; /* Chrome */
-ms-flex: 1; /* IE 10 */
flex: 1; /* новый синтаксис, предусмотренный спецификацией — Opera 12.1, Firefox 20+ */
}

Новый синтаксис не требует явного указания ширины боковых колонок, так как в этом случае оставшиеся 40% доступного свободного пространства будут автоматически поровну (по 20%) разделены между ними. Но мною было обнаружено, что если не указать их ширину явно, то это может привести к нежелательным последствиям, связанным с конфликтом различных значений ширины определенных с помощью старого синтаксиса.

Организация порядка отображения колонок.

Макет нашей страницы требует, чтобы колонка основного контента размещалась по центру, но все относящееся к ней форматирование мы выполняем в первую очередь. Это очень просто сделать с помощью Flexbox модели, но нам снова придется использовать комбинацию правил, предусмотренных различными версиями синтаксиса.

.main-content {
-webkit-box-ordinal-group: 2; /* старый синтаксис — iOS 6-, Safari 3.1-6 */
-moz-box-ordinal-group: 2; /* старый синтаксис — Firefox 19- */
-ms-flex-order: 2; /* промежуточный синтаксис 2011 года — IE 10 */
-webkit-order: 2; /* новый синтаксис — Chrome */
order: 2; /* новый синтаксис, предусмотренный спецификацией — Opera 12.1, Firefox 20+ */
}
.main-nav {
-webkit-box-ordinal-group: 1;
-moz-box-ordinal-group: 1;
-ms-flex-order: 1;
-webkit-order: 1;
order: 1;
}
.main-sidebar {
-webkit-box-ordinal-group: 3;
-moz-box-ordinal-group: 3;
-ms-flex-order: 3;
-webkit-order: 3;
order: 3;
}

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

За счет использования в нашем CSS коде всех трех существующих на данный момент вариантов Flexbox синтаксиса мы можем рассчитывать на его полную работоспособность в следующих браузерах:

    Chrome все версии.
  • Firefox все версии.
  • Safari все версии.
  • Opera начиная с 12.1 версии.
  • IE 10 и выше.
  • iOS все версии.
  • Android все версии.

Основным ограничением здесь является поддержка в IE, хотя общая картина выглядит довольно неплохо. Если же вы используете такой подход для создания специальной мобильной версии сайта, то вы находитесь в еще более выигрышной ситуации. Буду рад вашим комментариям по результатам работы этого кода на Windows Phone.

Что касается поддержки в Firefox 19-, то здесь можно столкнуться с багами и это нужно проконтролировать, так как результат зависит от конкретного случая. Допустим, применительно к используемому в статье примеру я так и не нашел способ гарантированно установить 20%-ю ширину боковых колонок. И она может захватить область основного контента, ширина которой иногда зависит от формата находящегося внутри текста. Кроме того, мне пришлось использовать свойство -moz-box-flex: 1 применительно к средней колонке основного контента. Иначе в том случае если она содержит фрагмент текста отформатированный как white-space: nowrap, ширина которого больше ширины средней колонки (его контейнера), то это приведет к растягиванию самой колонки. Такое поведение необъяснимо и является ни чем иным как багом.

Смотреть результат работы кода на CodePen

* Примечание переводчика.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *