Outline

outline — контур вокруг элемента, отображаемый поверх блочной модели, не влияя на размеры и расположение элемента. Критически важен для доступности (индикатор фокуса), но может использоваться и декоративно.

Зачем нужно

Outline — главный визуальный индикатор фокуса при навигации клавиатурой. Без него пользователи, использующие клавиатуру, не могут определить, какой элемент активен. Удаление outline без замены — серьёзная ошибка доступности.

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

  • Индикатор фокуса (:focus, :focus-visible)
  • Отладка раскладки (outline не влияет на размеры, в отличие от border)
  • Декоративные эффекты (с outline-offset)

Предпосылки


Базовый синтаксис

/* Shorthand */
.box {
  outline: 2px solid #3498db;
  /* outline: width style color */
}

/* Развёрнуто */
.box {
  outline-width: 2px;
  outline-style: solid;
  outline-color: #3498db;
}

/* Убрать outline */
.box { outline: none; }

outline-style

.solid  { outline-style: solid; }
.dashed { outline-style: dashed; }
.dotted { outline-style: dotted; }
.double { outline-style: double; }
.groove { outline-style: groove; }
.ridge  { outline-style: ridge; }
.auto   { outline-style: auto; }  /* Стиль зависит от браузера/ОС */

outline-offset

Расстояние между outline и border-edge элемента:

.box {
  outline: 2px solid #3498db;
  outline-offset: 4px; /* Отступ наружу */
}

/* Отрицательный — outline внутри элемента */
.inset {
  outline: 2px solid red;
  outline-offset: -4px;
}

Outline vs Border

Свойство Border Outline
Влияет на размер Да Нет
Участвует в потоке Да Нет
Отдельные стороны Да Нет
border-radius Да Следует за border-radius (в современных браузерах)
Анимация Да Ограниченно
Offset Нет outline-offset
/* Outline не двигает соседние элементы */
.item:hover {
  outline: 3px solid blue; /* Соседи остаются на месте */
}

/* Border двигает */
.item:hover {
  border: 3px solid blue; /* Соседи сдвинутся на 3px */
}

Доступность — :focus и :focus-visible

Никогда не убирайте outline без замены

/* ПЛОХО — убивает доступность */
*:focus { outline: none; }
button:focus { outline: none; }

/* ХОРОШО — кастомный стиль фокуса */
button:focus-visible {
  outline: 2px solid #3498db;
  outline-offset: 2px;
}

/* ХОРОШО — замена outline на box-shadow */
button:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.5);
}

:focus vs :focus-visible

/* :focus — любой фокус (клик + клавиатура) */
button:focus {
  outline: 2px solid blue;
}

/* :focus-visible — только клавиатурный фокус */
button:focus-visible {
  outline: 2px solid blue;
}
/* Клик мышью НЕ покажет outline — удобно для дизайна */

/* Рекомендуемый паттерн */
:focus {
  outline: none; /* Убрать для мыши */
}
:focus-visible {
  outline: 2px solid #3498db; /* Показать для клавиатуры */
  outline-offset: 2px;
}

:focus-within

/* Подсветить контейнер, когда фокус на дочернем элементе */
.form-group:focus-within {
  outline: 2px solid #3498db;
  outline-offset: 4px;
  border-radius: 8px;
}

Отладка с outline

/* Визуализация всех элементов — outline не ломает layout! */
* {
  outline: 1px solid rgba(255, 0, 0, 0.3);
}

/* Подсветить конкретный элемент */
.debug {
  outline: 3px dashed red;
}

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

  1. Убрать outline без замены — пользователи клавиатуры не видят фокус:

    /* НЕЛЬЗЯ */
    *:focus { outline: none; }
    
    /* Нужна замена */
    *:focus-visible { outline: 2px solid #3498db; }
    
  2. Использовать border вместо outline для отладки — border сдвигает layout

  3. Не учитывать, что outline поверх контента — может перекрыть текст при отрицательном offset

  4. :focus вместо :focus-visible — показывает outline при клике мышью (раздражает пользователей)

Практика

  • Стилизовать :focus-visible для кнопок и ссылок
  • Использовать outline-offset для создания двойного контура
  • Заменить outline на box-shadow для фокуса
  • Использовать outline для отладки layout

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

Ресурсы