Как использовать свойство order во флексбоксах, не вызывая хаоса
Перевод статьи Avoiding chaos when using Flexbox ‘order’ для css-live.ru, с разрешения автора — Амелии Беллами-Ройдз
Недавняя твиттерная суматоха вынудила меня сделать наконец демо с флексбоксами, которое я хотела создать еще с тех пор, как впервые начала экспериментировать с flex-свойствами CSS.
Рома Комаров поделился исследованием, как с помощью флексбоксов и CSS-свойства order
получить эффект сортировки таблицы на чистом CSS. Другие CSS-эксперты тотчас выступили с предупреждением, что такой подход не рекомендуется, а то и вовсе прямо противоречит спецификации.
Рома принял критику и добавил в статью предостережение: это лишь эксперимент, не пытайтесь повторить это в продакшне! Но в твиттерном обсуждении люди задавали вопрос, всплывающий снова и снова:
Для чего же тогда вообще свойство ‘order’? Если его применение — это случай, когда «визуальный порядок отличается от исходного», то почему это условие не может выполняться и при других способах вывода?
Сет Роби (@TALlama), твит 16 февраля 2018
Для начала давайте рассмотрим, как не надо использовать order
, и почему.
Визуально неотразимый порядок не всегда отвечает смысловому. Фото Юхана Сонина, из Wikimedia Commons.
Спецификация флексбоксов предупреждает:
Авторы должны использовать
order
только для визуального, а не логического, переупорядочивания контента. Стили, использующиеorder
ради логического переупорядочивания, нарушают стандарт.
Для CSS-спецификаций крайне нехарактерны такие явные запреты для авторов. Большинство тамошних «должны» адресовано разработчикам браузеров. Так что раз они, образно говоря, требуют предъявлять специальный ордер на использование свойства order
— это дело серьезное. Пользователи клавиатуры и скринридеров полагаются на предсказуемый порядок элементов в DOM, и если такие пользователи видят экран, то им важно, чтобы этот порядок соответствовал наглядному логическому порядку элементов.
Да, верстка колонок на флоатах тоже позволяла (а то и вынуждала) использовать в коде другой порядок, не совпадающий с визуальным. Но ведь как раз поэтому мы и стремимся уйти от верстки на флоатах! Флексбоксы и CSS-гриды призваны упростить использование логичной структуры в разметке — а вовсе не помогать делать вид, что структура разметки не имеет значения.
Чтобы переупорядочить DOM, меняйте элементы местами с помощью DOM-методов, а не CSS-методов, влияющих только на визуальную раскладку.
Так почему же order
существует? Зачем свойство order
в CSS, если CSS не предназначен для переупорядочивания контента?
Потому что иногда логический порядок макета нельзя описать одним из вариантов обычного потока элементов во флексбоксах: слева направо, справа налево, сверху вниз или снизу вверх. Свойство order
— как раз для таких случаев: создать визуальный порядок, соответствующий логическому именно для вашего конкретного дизайна.
Или как более изящно выразилась редактор спецификации флексбоксов Элика Этемад (известная как fantasai):
Зрительное восприятие не подчиняется порядку в системе координат. На него влияют принципы гештальта (целостного образа — прим. перев.) и т.п., и в нем бывает одновременность, которой речь, например, передать не может. Так что мы упорядочиваем исходник по порядку чтения, а визуальной раскладке даем больше свободы в размещении элементов.
fantasai (@fantasai), твит 16 февраля 2018
Олимпийский пьедестал почета — мой любимый пример необычного порядка в раскладке, который, тем не менее, понятен всем. Именно это демо я намечала себе целых два года (и надо же, какая удача, что у меня наконец дошли руки до него как раз во время олимпиады!).
See the Pen Using the flexbox order property, properly by Amelia Bellamy-Royds (@AmeliaBR) on CodePen.
Очередность призовых мест передает высота элементов — и структура пьедестала, знакомая каждому с детства — а не порядок чтения слева направо. Порядок в коде соответствует логическим 1, 2 и 3 местам, а свойство order
создает правильную наглядную раскладку.
Я использовала похожий порядок «сначала центр» для навигации на сайте в поддержку моей книги «Использование SVG». В «шапке» там у меня три навигационных ссылки:
- Список глав
- Предыдущая глава
- Следующая глава
Если записать это как один список, то логический порядок именно такой. Но в верстке логично, чтобы «предыдущая» ссылка была с краю слева, «следующая» — с краю справа, а ссылка на оглавление — между ними. Флексбоксами я могу добиться этого без возни с флоатами и лишними дивами-обертками.
Улучшенный порядок на этом сайте включается по медиавыражению min-width. На более узких экранах ссылка на оглавление занимает всю первую строку раскладки на флексбоксах, а ссылки «следующая» и «предыдущая» переносятся на отдельную строку (или даже на две строки, если экран очень узкий по отношению к размеру шрифта).
Аналогично, в примере с пьедесталом у меня есть медиавыражение max-width, чтобы убрать свойство order
на узких экранах (наряду с другими мелкими правками стилей) и восстановить обычный порядок списка для одноколоночной раскладки.
P.S. Это тоже может быть интересно: