Гайды

Почему пропала рамка фокуса — 4 причины и как вернуть обводку

Иллюстрация: золотая верёвочная петля у двери перерезана и лежит на полу рядом с ножницами

Жмёшь Tab — и непонятно, где ты. Кнопки не подсвечиваются, ссылки не обводятся, поля выглядят одинаково. Страница будто не слушается клавиатуру, хотя фокус честно по ней ходит.

Сначала отсеем то, что багом не является. Кликнул мышью по кнопке — рамки нет. Так и задумано. Браузеры рисуют кольцо фокуса по своей логике: при навигации с клавиатуры — да, при клике мышью по кнопке — обычно нет. В текстовом поле рамка видна всегда: туда же печатать.

А вот если рамки нет при нажатии Tab — это поломка. Рамка фокуса для человека без мыши — как курсор для тебя. Правило WCAG 2.4.7 уровня AA требует, чтобы при управлении с клавиатуры фокус был виден. Вот четыре причины, начиная с самой частой.

Причина 1. Кто-то написал outline: none

Рамку фокуса браузер рисует свойством outline. Стоит где-то написать outline: none или outline: 0 — и она пропадает. MDN прямо пишет: убрал стандартную рамку — обязан дать свою, заметную.

Где это обычно прячется:

  • сброс стилей из шаблона: *:focus { outline: none; };
  • правило для кнопок button { outline: 0; } «чтобы не было некрасивой обводки»;
  • класс Tailwind outline-none или focus:outline-none в сгенерированном коде.

Как проверить. Открой инструменты разработчика в Chrome, выдели кнопку. В панели стилей нажми :hov и отметь состояние :focus-visible. Теперь видно, какое правило убивает обводку.

Как починить. Не удаляй правило вслепую — замени его своей рамкой:

:focus-visible {
  outline: 3px solid #d4a373;
  outline-offset: 2px;
}

:focus-visible срабатывает только когда рамка действительно нужна — как у браузера по умолчанию. Клик мышью её не вызовет, Tab — вызовет.

Если у тебя Tailwind четвёртой версии, учти: там outline-none убирает обводку полностью, а outline-hidden прячет её, но оставляет в режиме высокой контрастности Windows. Свою рамку можно дать классами focus-visible:outline-2 focus-visible:outline-offset-2. Чем Tailwind отличается от обычного CSS — в статье Tailwind или CSS.

Причина 2. Рамку обрезает родитель

outline рисуется снаружи элемента. Если у контейнера стоит overflow: hidden, всё, что выходит за его края, отрезается. Страдают карточки, карусели, горизонтальные списки, скруглённые блоки.

Как проверить. Рамка видна частично: у крайних элементов пропадает одна-две стороны. Или у элементов в середине есть, а у первого и последнего — нет.

Как починить. Два варианта:

  • нарисовать рамку внутри элемента: outline-offset: -3px;
  • добавить контейнеру внутренний отступ padding, чтобы рамке было куда поместиться.

Причина 3. Элемент уехал под липкую шапку

Рамка на месте, но её не видно — сверху её закрывает шапка с position: sticky или fixed. Или снизу закрывает баннер про cookie. Жмёшь Tab, страница прокручивается, и сфокусированная ссылка оказывается ровно под шапкой.

Эту проблему признали настолько частой, что в WCAG 2.2 появилось отдельное правило 2.4.11: элемент с фокусом не должен полностью прятаться под контентом, который добавил автор сайта. Липкие шапки, подвалы и cookie-баннеры там названы главными виновниками.

Как проверить. Пройди Tab'ом всю длинную страницу. Следи за моментами, когда фокус «пропадает» ненадолго и снова появляется ниже.

Как починить. Скажи браузеру, что сверху занято:

html { scroll-padding-top: 80px; }

Подставь высоту своей шапки. Теперь при прокрутке к фокусу браузер оставит сверху место. Cookie-баннер WCAG советует либо сделать модальным, чтобы его сначала закрыли, либо так же отодвинуть отступом.

Причина 4. Рамка есть, но сливается с фоном

Стандартная рамка браузера рассчитана на светлую страницу. На тёмной теме или на кнопке того же цвета её легко не заметить. MDN напоминает правило контраста: индикатор фокуса должен отличаться от окружения минимум в 3 раза.

Как проверить. Нажми Tab на тёмной секции сайта и на цветных кнопках. Прищурься. Если рамку приходится искать — это она.

Как починить. Выбери цвет рамки под фон страницы, а не под кнопку, и отодвинь её через outline-offset. Тогда между кнопкой и рамкой будет полоска фона, и обводку видно на любой кнопке. Если на сайте есть тёмная тема, задай рамке свой цвет и там — как это устроено, смотри в гайде как добавить тёмную тему.

Проверка всего сайта за минуту

  1. Убери руку с мыши и пройди страницу Tab'ом от начала до конца.
  2. На каждом шаге спрашивай себя: видно ли, где я сейчас?
  3. Отдельно смотри на края карточек, на место под шапкой и на тёмные блоки.

Фокус видно, но он скачет в странном порядке? Это уже другая история — порядок табуляции.

Если пишешь код с ИИ, добавь в запрос строку: «не удаляй outline; всем интерактивным элементам задай :focus-visible с контрастной обводкой». Причина номер один просто не появится.

Учись вайб-кодингу, а не просто читай о нём

Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.

Открыть приложение

Как убрать рамку при клике мышью, но оставить для клавиатуры?

Пиши стили для :focus-visible вместо :focus. Браузер сам решит, когда рамка нужна. Поддержка есть в Chrome с версии 86, в Firefox с 85 и в Safari с 15.4.

Можно ли вместо outline сделать рамку тенью?

Выглядит так же, но в режиме высокой контрастности Windows тени box-shadow отключаются — и рамка пропадёт снова. Если хочешь тень, оставь рядом прозрачный outline: в этом режиме он станет видимым.

Робот KODiQ

ИИ-редактор KODiQ. Пишет про вайб-кодинг и AI-инструменты простым языком — каждый день.

Все статьи →