Как сделать переключатель (toggle switch)
Короткий ответ
Возьмите обычный чекбокс, уберите стандартный вид через appearance: none и нарисуйте дорожку и кружок:
<style>
.switch { appearance: none; position: relative; width: 44px; height: 24px; margin: 0; border-radius: 999px; background: silver; cursor: pointer; transition: background 0.2s; vertical-align: middle; }
.switch::before { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: white; transition: translate 0.2s; }
.switch:checked { background: seagreen; }
.switch:checked::before { translate: 20px 0; }
.switch:focus-visible { outline: 2px solid orange; outline-offset: 2px; }
</style>
<label><input class="switch" type="checkbox" role="switch" checked> Dark mode</label>Это по-прежнему чекбокс: он переключается щелчком по подписи и пробелом, отправляется с формой. role="switch" подсказывает скринридеру, что это переключатель, и он говорит «вкл»/«выкл» вместо «отмечено».
Неактивный переключатель
Стили для отключённого состояния задаёт :disabled:
.switch:disabled { opacity: 0.5; cursor: not-allowed; }Когда переключатель, а когда чекбокс
Переключатель срабатывает сразу, как выключатель света: включил — тёмная тема появилась. Если выбор применяется только после нажатия «Сохранить», привычнее обычный флажок.
Частая ошибка
Переключатель собирают из <div> и <span> с обработчиком щелчка. Он не получает фокус, не переключается клавиатурой и не сообщает своё состояние скринридеру. Основой всегда должен быть <input type="checkbox"> или <button>.
Функции из этого ответа
- <input type="checkbox"> — Флажок (`checkbox`) — независимый выбор «да/нет»; переключатель (`radio`) — один вариант из группы.
- appearance — Отключает встроенный вид элементов формы, чтобы оформить их с нуля.
- :checked — Срабатывает у отмеченного флажка или переключателя и у выбранного `<option>`.
- ::before — Создаёт виртуальный первый дочерний элемент — для декоративного текста или фигур.
- transition — Плавно анимирует изменение свойства от старого значения к новому.