Safari & Testing

Атрибут HTML inert в 2026: статические модалки, фокус в Safari WebKit и проверки на облачном Mac mini

MacHTML Lab2026.05.14около 31 мин чтения

Маркетинговые лендинги и статическая документация в 2026 году по-прежнему выгодны: простой CDN-кеш, предсказуемые сборки. Но после открытия модалки клавиатура всё ещё добирается до ссылок в подвале, а VoiceOver читает фоновые заголовки. Полупрозрачная подложка не решает задачу. Булев атрибут inert «замораживает» целое поддерево: нет попадания указателя и таб-фокуса, текст остаётся видимым—надёжнее, чем вручную выставлять tabindex="-1" десяткам ссылок.

Мы связываем inert с материалами про Popover API, каскад @layer и View Transitions для MPA, чтобы слои, анимации и фокус не спорили друг с другом. Ниже — практика Safari WebKit и сценарий аренды Mac mini в облаке MacHTML (ориентир публичной цены около 16,9 $/день), чтобы закрыть разрыв между Chromium-only CI и реальными пользователями.

Смысл и область inert

По спецификации HTML inert делает потомков неинтерактивными, но не скрывает их визуально. Типичный шаблон: обёртка #page-shell для шапки, основного текста и подвала; модальное окно — сосед снаружи. При открытии shell.inert = true, при закрытии false. Так вы не отключаете кнопки внутри самой модалки по ошибке.

В отличие от disabled, ограниченного формами, inert работает на любом HTML — удобно для Hugo, Eleventy или ручной вёрстки. Достаточно небольшого state-модуля на ванильном JS. С hash или history.pushState можно делиться состоянием модалки, сохраняя деградацию без скриптов.

Сравнение с aria-hidden и нативным <dialog>

aria-hidden="true" в основном убирает узел из дерева доступности, но не гарантирует отсутствие кликов и фокуса. Ошибки z-index оставляют «невидимые, но кликабельные» зоны, особенно в мобильном Safari. inert одновременно блокирует hit-testing и обход фокуса, что ближе к ожиданиям модального окна. Нативный dialog.showModal() даёт верхний слой и ловушку фокуса; если дизайн это запрещает, inert остаётся переносимым компромиссом.

Сторонние iframe (чат, карты, реклама) часто не подчиняются inert предка из-за cross-origin. В договоре пропишите tabindex и хуки видимости до того, как маркетинг добавит новый скрипт. Один абзац в RFC экономит часы споров на этапе комплаенса.

Safari, VoiceOver и субпиксель на Retina

WebKit в 2026 широко поддерживает inert, но три эффекта повторяются: двойное объявление границ VoiceOver при лишнем aria-modal; дрожание hit-testing, если рядом стоит backdrop-filter на брате; расхождение Safari Technology Preview и стабильной версии — фиксируйте оба канала для саппорта.

Метрика: первый pointerdown на основной кнопке после открытия должен прийти быстрее 120 мс на холодном кеше; иначе чаще всего виноват прозрачный перехватчик. Добавьте показатель к дашбордам LCP/CLS, чтобы его понимали не только фронтендеры. Ночные прогоны WebKit удобно гонять на Apple Silicon Mac mini с idle около 12 Вт — тихо для офиса.

Ящики, маркетинговые встраивания и бюджет z-index

Cookie-бар, видео в hero и чат конкурируют за стек. Задайте диапазоны: контент 0–99, липкая навигация 100–199, модалки 1000+, запретите случайные гигантские числа. Нужно оставить юридический баннер активным — inert только маркетинговую ветку; наоборот, inert основной контент, если важна только кнопка согласия.

При View Transitions снимайте inert после завершения промисов анимации, иначе фокус останется на удаляемом узле. Для prefers-reduced-motion: reduce сократите переходы до почти мгновенных (1 мс по прозрачности), чтобы порядок табов был предсказуем.

Телеметрия и session replay

SDK реплея добавляют прозрачные слои, которые ловят события даже при inert фоне. Поместите аналитику внутрь inert-оболочки или ставьте реплей на паузу под модалкой. В E2E проверяйте, что активаций hero-CTA при открытой модалке 0.

В разработке полезен временный focusin-лог document.activeElement; в продакшене удалите, но оставьте пятиминутный флаг для разборов инцидентов. В релиз-нотах указывайте CFBundleShortVersionString Safari и минор macOS.

Матрица решений

СценарийВыборПочему
Одна маркетинговая модалкаinert + role=dialogмало JS, ясные hit-тесты
Многошаговый мастернативный dialog/popoverверхний слой, light dismiss
Сторонний iframeконтракт + tabindexinert не всегда сквозь origin
Инцидент «закрыть всё»горячая клавишаоперации спасаются сами

Минимальный vanilla-переключатель

const shell = document.querySelector('#page-shell');
const dlg = document.querySelector('#modal');
function openModal() {
  shell.inert = true;
  dlg.hidden = false;
  dlg.querySelector('button[data-close], [autofocus]')?.focus();
}
function closeModal() {
  dlg.hidden = true;
  shell.inert = false;
}

Чеклист перед релизом

  1. С открытой модалкой пройти всю страницу Tab вперёд и назад — фокус не должен уходить в фон.
  2. С VoiceOver повторить обход, цель 0 утечек.
  3. Проверить ширины 320 px, 768 px, 1280 px на цепочки скролла и «пробивающие» клики.
  4. Временный счётчик pointerdown на главном CTA — во время модалки 0.
  5. Записи Safari stable и Chromium хранить минимум 90 дней.

Закупки всё чаще требуют доказательств тестов доступности; одного Lighthouse мало. Аренда облачного Mac mini на несколько дней обычно дешевле переноса релиза из-за бага WebKit. Ориентир ~16,9 $/день по публичным страницам помогает согласовать бюджет.

Таблица «какие SDK работают при inert (платёжные)» и «какие надо глушить (автоплей превью)» в начале README сокращает онбординг до 15 минут. Многоязычные сайты могут делить логику переключателя и локализовать только тексты.

Задокументируйте горячие клавиши (Esc, глобальное снятие оверлеев). Короткое видео на облачной мини убеждает стейкхолдеров быстрее длинной спецификации.

FAQ

Скрывает ли inert текст от скринридеров?

Не автоматически; для скрытия нужны другие приёмы.

Можно ли переключать inert на каждом кадре анимации?

Лучше нет — лишний layout thrashing; только на open/close.

Shadow DOM?

Под inert-предком shadow тоже неинтерактивен — планируйте слоты.

Apple Silicon Mac mini остаётся самым тихим способом честно проверять WebKit. Облачные узлы MacHTML дают SSH и опциональный VNC, чтобы распределённая команда делила один macOS-профиль без пересылки железа. После проекта остановите инстанс вместо 36 месяцев амортизации сервера под столом.

Доступность модалок — не разовый тикет: маркетинг меняет встраивания, Safari получает минорные апдейты, скрипты двигают фокус. Когда WebKit-QA оформлена как «арендуемая мини-машина» за ~16,9 $/день, стоимость предсказуема, а релизы реже упираются в сюрпризы WebKit.

Проверка inert в Safari на облачном Mac mini

Арендуйте Mac mini в облаке, чтобы сверить inert, dialog и popover с VoiceOver перед мержем статического HTML в продакшен.

Проверка inert на Mac
от ~16,9 $/день