В веб-разработке есть священные войны, которые длятся десятилетиями. Одна из самых затяжных и нелепых — битва вокруг курсора мыши на кнопках. На заре развития веба браузерные вендоры зафиксировали строгое пуристическое правило: курсор pointer (рука с указательным пальцем) отображается исключительно на гиперссылках (<a>), ведущих на другие веб-страницы. На кнопки же (<button>), переключатели и чекбоксы браузеры намертво привязали стандартную стрелку (default).
Однако реальный веб быстро пошел другим путем. В миллионах интерфейсов кнопка означает интерактивное действие, и пользователи привыкли: если на элемент можно нажать, курсор должен смениться на палец. Все популярные дизайн-системы — от Bootstrap и Material UI до Tailwind — начинались с одного и того же ритуального сброса: button { cursor: pointer; }.
В дискуссии по тикету рабочей группы w3c/csswg-drafts #14251, инициированному Эликой Этемад (fantasai), консорциум W3C наконец-то признал де-факто сложившуюся практику индустрии и закрепил официальный стандарт отображения курсоров для элементов форм нового поколения с ключевым свойством appearance: base.
Консенсус CSSWG: «Pointer означает клик»
Спецификация appearance: base разрабатывается в рамках большой инициативы Open UI. Ее цель — убрать замшелые системные рельефные стили операционных систем времен Windows 95 и дать разработчикам чистый, легко стилизуемый каркас для контролов форм (включая долгожданный кастомизируемый <select>).
При включении appearance: base браузеры теперь обязаны автоматически выставлять предсказуемые курсоры:
/* Стандартное распределение курсоров в appearance: base */
select, option, button,
input[type=button], input[type=submit], input[type=reset],
input[type=checkbox], input[type=radio],
input[type=color], input[type=image],
::file-selector-button {
cursor: pointer; /* Кликабельные элементы получают палец по умолчанию */
}
input[type=range] {
cursor: grab; /* Ползунки получают открытую ладонь */
}
input[type=range]:active {
cursor: grabbing; /* При зажатии ладонь сжимается */
}
Для неактивных и заблокированных состояний рабочая группа также ввела четкие правила:
- все заблокированные элементы с атрибутом
:disabledполучают курсорcursor: not-allowed; - элементы в режиме только для чтения
:read-only(например, неизменяемые текстовые поля) отображают стандартную стрелкуcursor: default.
Фронтендерам больше не придется копировать десятки строк сброса курсоров в свои CSS-файлы: браузер сделает это нативно.
Прогрессивное внедрение в верстке
Решение CSSWG включено в рабочий драфт спецификации CSS Basic User Interface Module Level 4. Для сохранения обратной совместимости старый режим appearance: auto сохраняет привычные системные курсоры, чтобы не ломать веб-страницы двадцатилетней давности.
В современных проектах использовать базовые контролы можно уже сейчас через директиву @supports, следуя общему курсу на декларативность в трендах современного CSS:
/* Прогрессивное улучшение: нативные курсоры нового поколения */
@supports (appearance: base) {
button,
select,
input[type="checkbox"],
input[type="radio"] {
appearance: base;
/* Курсор pointer движок подтянет из базы автоматически */
}
input[type="range"] {
appearance: base;
/* Нативный grab / grabbing без дополнительных классов */
}
}
/* Безопасный фоллбек для устаревших движков */
@supports not (appearance: base) {
button,
select,
input[type="checkbox"],
input[type="radio"] {
cursor: pointer;
}
:disabled {
cursor: not-allowed;
}
}
Закрепление нативных курсоров в базе — это не просто визуальный комфорт для зрячих пользователей мыши. Семантическое разделение состояний :disabled (not-allowed) и :read-only (default) помогает вспомогательным технологиям точнее интерпретировать доступность элементов формы.
В итоге двадцатипятилетний спор завершился победой здравого смысла: веб-платформа официально признала реальные привычки сотен миллионов пользователей.
