Grid: доступность и порядок элементов
Расположение элементов в Grid через
grid-columnиgrid-rowменяет только визуальный порядок — DOM-порядок (и порядок для скринридеров/клавиатуры) остаётся неизменным.
Зачем нужно
Grid позволяет визуально переставлять элементы независимо от их места в HTML. Это мощно, но опасно: скринридеры и Tab-навигация следуют DOM-порядку. Неправильное использование Grid для переупорядочивания интерактивных элементов создаёт серьёзные проблемы доступности.
Где используется
- Адаптивные макеты с разным порядком на мобиле/десктопе
- Карточки с изображением и заголовком
- Перегруппировка блоков лендинга
- Дашборды с переставляемыми виджетами
Основной контент
Проблема: визуал vs DOM-порядок
/* Визуально: Image | Title | Description */
/* DOM: Title, Description, Image */
.card {
display: grid;
grid-template-areas:
"image"
"title"
"description";
}
.card__title { grid-area: title; }
.card__description { grid-area: description; }
.card__image { grid-area: image; }
<!-- DOM-порядок (для Tab): Title → Description → Image -->
<div class="card">
<h2 class="card__title">Заголовок</h2> <!-- 1-й в DOM -->
<p class="card__description">Текст</p> <!-- 2-й в DOM -->
<img class="card__image" src="..." alt="..."><!-- 3-й в DOM -->
</div>
Для нефокусируемых элементов (img, текст) это допустимо. Для кнопок и ссылок — нет.
Безопасное переупорядочивание
/* OK — изображение декоративное, нет фокусируемых элементов */
.article {
display: grid;
grid-template-areas:
"img"
"heading"
"text";
}
/* ОПАСНО — кнопки в grid-order не совпадает с DOM */
.wizard {
display: grid;
grid-template-columns: 1fr 1fr;
}
.wizard .next() { grid-column: 1; } /* Визуально первая */
.wizard .prev { grid-column: 2; } /* Визуально вторая */
/* Но Tab идёт: .next() → .prev если DOM именно такой */
Рекомендации WCAG
/* WCAG 1.3.2: порядок фокуса должен соответствовать логическому порядку */
/* Если нужно изменить порядок для мобиля */
@media (max-width: 768px) {
/* Меняйте DOM-порядок через JS или используйте flex-direction */
/* Не полагайтесь только на grid-row для интерактивных элементов */
}
order vs grid-placement
/* order — как в Flexbox, меняет визуальный порядок */
.item { order: -1; } /* Опасно для интерактивных элементов */
/* grid-column/grid-row — явное позиционирование */
.item { grid-column: 2; grid-row: 1; } /* Те же проблемы */
/* Оба способа создают разрыв DOM vs visual */
Тестирование порядка
// Проверить логический порядок через Tab
// document.activeElement покажет текущий элемент
// Или использовать скринридер (NVDA, VoiceOver)
Частые ошибки
- Переставлять кнопки через grid без изменения DOM — Tab-порядок нарушается; использовать
tabindexкак патч — плохая практика - Считать, что
grid-areaвлияет на скринридер — нет; DOM-порядок определяет порядок чтения - Не тестировать с клавиатурой — после изменения макета всегда проверяйте Tab-навигацию