Flexbox: доступность и порядок

Свойство order изменяет визуальный порядок flex-элементов без изменения DOM, что создаёт разрыв между порядком в коде и порядком восприятия для вспомогательных технологий.

Зачем нужно

Изменение порядка через order или flex-direction: row-reverse влияет только на визуал — скринридеры и Tab-навигация по-прежнему следуют DOM-порядку. Это создаёт серьёзные проблемы доступности. Понимание этой ловушки критично для написания инклюзивных интерфейсов.

Где используется

  • Мобильная адаптация (перестановка блоков)
  • Навигация (логотип, меню, кнопки)
  • Карточки с изображением и текстом
  • Формы с плавающими label

Основной контент

Свойство order

.container {
  display: flex;
}

/* Визуальный порядок: B, A, C */
.item-a { order: 1; } /* visual: 2nd */
.item-b { order: 0; } /* visual: 1st (default 0 побеждает) */
.item-c { order: 2; } /* visual: 3rd */
<!-- DOM-порядок (для скринридера): A, B, C -->
<div class="container">
  <div class="item-a">A</div>
  <div class="item-b">B</div>
  <div class="item-c">C</div>
</div>

Проблема доступности

/* НЕ ДЕЛАТЬ ТАК для навигационных элементов */
.nav {
  display: flex;
}

/* Tab-порядок: Home, About, Contact, Logo */
/* Визуальный порядок: Logo, Home, About, Contact */
.logo   { order: -1; } /* Визуально первый, но Tab-порядок последний */
.link-1 { order: 0; }
.link-2 { order: 1; }
.link-3 { order: 2; }

Правильный подход — менять DOM-порядок

<!-- Правильно: DOM-порядок = визуальный порядок для интерактивных элементов -->
<nav class="nav">
  <a class="logo" href="/">Logo</a>
  <a href="/about">About</a>
  <a href="/contact">Contact</a>
</nav>

Когда order безопасен

/* Декоративные, нефокусируемые элементы */
.card {
  display: flex;
  flex-direction: column;
}

/* Переставить фото и текст — декоративно, не навигационно */
.card--image-right .card__image {
  order: 2; /* ОК — изображение, не интерактивный элемент */
}

row-reverse и column-reverse

/* row-reverse разворачивает визуально, DOM остаётся */
.nav {
  display: flex;
  flex-direction: row-reverse; /* Опасно для навигации! */
}

/* Tab-порядок противоположен визуальному */

Безопасная мобильная перестановка через медиазапросы

/* Правильно: менять order только для некликабельных блоков */
.page-layout {
  display: flex;
  flex-direction: column;
}

.main    { order: 1; }
.sidebar { order: 2; }

@media (min-width: 768px) {
  .page-layout { flex-direction: row; }
  .sidebar { order: -1; width: 280px; } /* Sidebar слева на десктопе */
}

Частые ошибки

  • order на кнопках и ссылках — Tab-порядок не совпадает с визуальным, нарушает доступность
  • flex-direction: row-reverse в навигации — инвертирует Tab-порядок без предупреждения
  • Только CSS-решение без DOM-изменений — для критичных изменений порядка (главное меню) нужно менять HTML, а не только CSS

Связанные темы

Ресурсы