← Назад к вопросам

В чем разница между :focus и :focus-within?

2.2 Middle🔥 111 комментариев
#HTML и CSS

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

В чем разница между :focus и :focus-within?

:focus применяется к элементу, который сам имеет фокус, а :focus-within применяется к элементу, если он сам или любой его дочерний элемент имеет фокус. Это кардинальная разница в области применения.

:focus — фокус на самом элементе

:focus срабатывает только когда конкретный элемент получает фокус (через Tab, клик мышью или programmatically).

/* Стиль применяется ТА ТОЛЬКО когда input имеет фокус */
input:focus {
  border-color: #007bff;
  outline: 2px solid #007bff;
  background-color: #f8f9fa;
}

button:focus {
  outline: 3px solid #ffd700;
  outline-offset: 2px;
}
<input type="text" /> <!-- При клике сюда — :focus применится к INPUT -->
<button>Click me</button> <!-- При клике сюда — :focus применится к BUTTON -->

:focus-within — фокус в элементе или его детях

:focus-within срабатывает когда родительский элемент или любой его потомок получает фокус. Это очень полезно для целого контейнера (форма, окно и т.д.).

/* Стиль применяется всей ФОРМЕ если внутри есть element с фокусом */
form:focus-within {
  border: 2px solid #007bff;
  box-shadow: 0 0 0 4px rgba(0, 123, 255, 0.25);
}

/* Контейнер меняет цвет если внутри элемент в фокусе */
.input-group:focus-within {
  background-color: #f0f7ff;
}

/* Иконка меняет цвет при фокусе на input внутри */
.input-group:focus-within .icon {
  color: #007bff;
}
<form>
  <div class="input-group">
    <span class="icon">@</span>
    <input type="email" /> <!-- При клике сюда — :focus-within применится к FORM и .input-group -->
  </div>
</form>

Практическое сравнение

<!DOCTYPE html>
<html>
<head>
<style>
  /* :focus — только когда label сам в фокусе (невозможно с помощью клика) */
  label:focus {
    color: red;
  }

  /* :focus-within — когда label ИЛИ его input имеет фокус */
  label:focus-within {
    color: blue;
    background-color: #f0f0f0;
  }

  /* Только input в фокусе */
  input:focus {
    outline: 2px solid green;
  }
</style>
</head>
<body>
  <!-- Эта label получит :focus-within когда input в фокусе -->
  <label>
    Email:
    <input type="email" />
  </label>

  <!-- Эта label получит :focus-within когда любой input в фокусе -->
  <label :focus-within>
    Профиль
    <div>
      <input type="text" placeholder="Имя" />
      <input type="text" placeholder="Фамилия" />
    </div>
  </label>
</body>
</html>

Примеры использования

Пример 1: Подсвечивание всей формы при заполнении

.form-card {
  border: 2px solid #ccc;
  padding: 20px;
  border-radius: 8px;
  transition: all 0.3s;
}

/* Когда любое поле в форме получает фокус */
.form-card:focus-within {
  border-color: #007bff;
  box-shadow: 0 0 0 4px rgba(0, 123, 255, 0.1);
  background-color: #f9fbfd;
}
<form class="form-card">
  <input type="text" placeholder="Имя" />
  <input type="email" placeholder="Email" />
  <button>Отправить</button>
</form>

Пример 2: Изменение иконки в input группе

.input-wrapper {
  position: relative;
  display: flex;
  align-items: center;
}

.input-wrapper input {
  padding-left: 40px;
}

/* Иконка по умолчанию серая */
.input-wrapper .icon {
  position: absolute;
  left: 12px;
  color: #999;
  transition: color 0.2s;
}

/* Иконка становится синей при фокусе input */
.input-wrapper:focus-within .icon {
  color: #007bff;
}

.input-wrapper:focus-within input {
  border-color: #007bff;
  outline: none;
}
<div class="input-wrapper">
  <span class="icon">🔍</span>
  <input type="text" placeholder="Поиск..." />
</div>

Пример 3: Модальное окно

/* Затемнение backdrop когда модаль в фокусе */
.modal-overlay {
  display: none;
}

.modal:focus-within .modal-overlay {
  display: block;
  background-color: rgba(0, 0, 0, 0.5);
}

/* Увеличение z-index при фокусе */
.modal:focus-within {
  z-index: 1000;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
}

React компонент с обоими стилями

import styles from ./FormField.module.css;

interface FormFieldProps {
  label: string;
  name: string;
  type?: string;
  required?: boolean;
}

export function FormField({
  label,
  name,
  type = text,
  required
}: FormFieldProps) {
  return (
    <div className={styles.fieldWrapper}>
      {/* :focus-within для контейнера */}
      <label className={styles.label} htmlFor={name}>
        {label}
        {required && <span className={styles.required}>*</span>}
      </label>
      
      {/* :focus для самого input */}
      <input
        className={styles.input}
        id={name}
        name={name}
        type={type}
        required={required}
      />
      
      {/* Сообщение ошибки показывается при :focus-within */}
      <span className={styles.errorMessage}>
        Это поле обязательно
      </span>
    </div>
  );
}
/* FormField.module.css */
.fieldWrapper:focus-within {
  border-bottom: 2px solid #007bff;
  background-color: rgba(0, 123, 255, 0.02);
}

.input:focus {
  outline: none;
  border-color: #007bff;
}

.fieldWrapper:focus-within .errorMessage {
  display: block;
  color: #dc3545;
  font-size: 12px;
  margin-top: 4px;
}

Когда использовать

СитуацияИспользовать
Подсветить одно поле при вводе:focus на input
Подсветить всю форму при заполнении:focus-within на form
Изменить иконку рядом с input:focus-within на обёртке
Ошибка валидации только текущего поля:focus
Подсвечивание группы полей:focus-within на контейнере группы
Покраска кнопки в зависимости от фокуса:focus на button
Модальное окно с фокусом:focus-within на .modal

Поддержка браузерами

  • :focus — поддерживается всеми браузерами
  • :focus-within — поддерживается всеми современными браузерами (IE 11 не поддерживает)

Для IE 11 используй полифил или JavaScript:

// Простой полифил
document.addEventListener(focusin, (e) => {
  e.target.classList.add(has-focus);
});

document.addEventListener(focusout, (e) => {
  e.target.classList.remove(has-focus);
});
/* Используй класс вместо :focus-within для IE */
form.has-focus {
  border-color: #007bff;
}

Ключевые выводы

  • :focus — стиль применяется к элементу, который имеет фокус
  • :focus-within — стиль применяется к элементу, если он или его потомок имеет фокус
  • :focus-within идеален для форм, контейнеров и групп элементов
  • :focus для отдельных интерактивных элементов
  • Используй оба селектора для полного контроля над UI состоянием фокуса