Существует ли в настоящее время способ выделить элемент input с помощью псевдокласса focus-visible?

У меня возникла проблема, связанная с необходимостью различать состояние фокуса у инпута в зависимости от способа его активации: с помощью клавиши Tab или кликом мыши. Я хочу применять разные CSS стили для инпута в этих случаях. Несмотря на обширный поиск в интернете, мне не удалось найти решений, которые бы работали именно для инпутов - большинство из них касается кнопок и других элементов. Есть ли возможность решить эту задачу? В качестве примера ниже приведен код на JavaScript:
  • 13 марта 2025 г. 7:14
Ответы на вопрос 2
Да, вы можете использовать псевдокласс `:focus-visible` для стилизации элементов в зависимости от способа их активации (например, при фокусе с клавиатуры или мыши). Этот псевдокласс позволяет применять стили только в тех случаях, когда элемент имеет фокус и он был достигнут с помощью клавиатуры (например, с помощью клавиши Tab).

Вот пример, как вы можете использовать `:focus-visible` для инпутов:

```html
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        /* Стили для обычного состояния фокуса */
        input {
            border: 2px solid gray;
            padding: 10px;
            transition: border-color 0.3s;
        }

        /* Стили для состояния фокуса, активированного с помощью клавиатуры */
        input:focus-visible {
            border-color: blue;
        }

        /* Стили для состояния фокуса, активированного с помощью мыши */
        input:focus:not(:focus-visible) {
            border-color: green;
        }
    </style>
</head>
<body>
    <input type="text" placeholder="Введите текст">

    <script>
        // Для поддержки пользователей, у которых может быть отключен `focus-visible`
        document.addEventListener('keydown', (event) => {
            if (event.key === 'Tab') {
                document.body.classList.add('tab-navigating');
            }
        });

        document.addEventListener('mousedown', () => {
            document.body.classList.remove('tab-navigating');
        });

        document.addEventListener('focusin', (event) => {
            if (document.body.classList.contains('tab-navigating')) {
                event.target.classList.add('keyboard-focus');
            } else {
                event.target.classList.remove('keyboard-focus');
            }
        });

        document.addEventListener('focusout', (event) => {
            event.target.classList.remove('keyboard-focus');
        });
    </script>
</body>
</html>
```

В этом примере:

- Если элемент `input` получает фокус с помощью клавиатуры (например, при навигации с помощью клавиши Tab), то он будет обрамлен синей рамкой.
- Если элемент `input` получает фокус с помощью мыши, то он будет обрамлен зеленой рамкой.

Это достигается с помощью псевдоклассов `:focus-visible` и `:focus:not(:focus-visible)`.

Обратите внимание, что поддержка `:focus-visible` может варьироваться в разных браузерах. При использовании JavaScript, как в этом примере, вы можете обеспечить поддержку для всех пользователей, которые могут не иметь включенной поддержку данного псевдокласса.
Если элемент подразумевает использование клавиатуры (input, textarea), то focus-visible ставится независимо от того, каким способом на этот элемент попал фокус. Это соответствует рекомендации в стандарте CSS. 
If the element which supports keyboard input (such as an input element, or any other element that would triggers a virtual keyboard to be shown on focus if a physical keyboard were not present), indicate focus.
Похожие вопросы