Чекбокс (checkbox, флажок) — это элемент формы <input type="checkbox">, который хранит одно из двух состояний, отмечен или нет, и позволяет выбирать любое число опций из набора независимо друг от друга. Внешне это квадратное поле с галочкой; браузер рисует его по-своему, и чтобы вписать флажок в дизайн, вид переопределяют средствами CSS.
Содержание
Ниже разберем, как связать чекбокс с подписью, быстро покрасить стандартный флажок свойством accent-color, полностью нарисовать свой через appearance: none, обработать состояния :checked, :hover, :focus и :disabled и не потерять при этом доступность. Все примеры — готовый HTML и CSS, который можно вставить в страницу и увидеть результат.
Чекбокс, радиокнопка и переключатель: не путать
Эти элементы легко смешать, но задачи у них разные. Разведем их до того, как перейдем к стилям.
| Элемент | Что делает | Разметка | Когда брать |
|---|---|---|---|
| Чекбокс | независимый выбор, каждый флажок сам по себе | <input type="checkbox"> |
согласия, фильтры с множественным выбором |
| Радиокнопка | ровно один вариант из группы с общим name |
<input type="radio" name="size"> |
выбрать один из нескольких |
| Переключатель (switch) | включить/выключить одну настройку | тот же чекбокс, оформленный как тумблер | быстрое вкл/выкл опции |
| Выпадающий список | один или несколько вариантов, свернутых компактно | <select> |
много однородных вариантов, мало места |
Важная оговорка: отдельного HTML-элемента «переключатель» нет. Визуальный тумблер — это тот же <input type="checkbox">, которому CSS придали форму ползунка; для доступности такому элементу добавляют role="switch".
Разметка: input и подпись через label
Голый <input> без подписи неудобен: по тексту рядом нельзя кликнуть. Подпись задают тегом <label>, и связать их можно двумя способами.
<!-- Способ 1: label ссылается на input по for/id -->
<input type="checkbox" id="agree">
<label for="agree">Соглашаюсь с условиями</label>
<!-- Способ 2: input вложен внутрь label -->
<label>
<input type="checkbox"> Подписаться на рассылку
</label>
Оба варианта расширяют кликабельную зону на текст подписи: клик по слову «Соглашаюсь» переключает флажок. При первом способе значение for должно совпадать с id поля — это и есть их связь.
Простой путь: покрасить флажок через accent-color
Если нужно лишь привести цвет стандартного флажка к фирменному, полная перерисовка не требуется. Свойство accent-color красит нативный чекбокс, сохраняя его поведение и доступность.
input[type="checkbox"] {
accent-color: #2f80ed;
width: 1.1em;
height: 1.1em;
}
Флажок станет синим в отмеченном состоянии, галочку и фокус браузер отрисует сам. Это самый дешевый способ, и он работает в актуальных Chrome, Firefox, Safari и Edge (свойство доступно во всех основных браузерах примерно с 2021-2022 годов).
Граница приема: accent-color меняет только цвет. Задать другую форму, толщину рамки, скругление или анимацию появления галочки так нельзя — для этого нужен следующий подход.
Полная кастомизация: appearance: none
Чтобы нарисовать флажок с нуля, сначала снимают стандартный вид свойством appearance: none, а потом оформляют сам элемент как обычный блок. Галочку удобно рисовать псевдоэлементом ::before без картинок и SVG-файлов.
Минимальный рабочий пример целиком — его можно вставить в страницу:
<label class="check">
<input type="checkbox" checked>
<span>Помидоры</span>
</label>
.check {
display: inline-flex;
align-items: center;
gap: 0.5em;
font-size: 1.1rem;
cursor: pointer;
}
.check input[type="checkbox"] {
appearance: none;
-webkit-appearance: none;
margin: 0;
width: 1.2em;
height: 1.2em;
border: 2px solid #9aa0a6;
border-radius: 0.3em;
display: inline-grid;
place-content: center;
transition: background-color .15s, border-color .15s;
}
.check input[type="checkbox"]::before {
content: "";
width: 0.65em;
height: 0.65em;
transform: scale(0);
transition: transform .12s ease-in-out;
background-color: #fff;
clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0, 43% 62%);
}
.check input[type="checkbox"]:checked {
background-color: #2f80ed;
border-color: #2f80ed;
}
.check input[type="checkbox"]:checked::before {
transform: scale(1);
}
Что отрисуется: серый квадрат со скругленными углами; когда флажок отмечен, фон становится синим, а внутри плавно, за счет transform, проступает белая галочка. Так как в примере стоит checked, при загрузке галочка видна сразу.
Разберем ключевые строки:
appearance: noneубирает нативный вид, после чего рамку, фон и размеры задаем сами. Префикс-webkit-appearanceоставлен для старых версий Safari.display: inline-gridвместе сplace-content: centerцентрирует псевдоэлемент-галочку внутри квадрата.::beforeрисует галочку: квадратный блок обрезается по контуру «птички» черезclip-path: polygon(...), аbackground-colorзадает ее цвет.:checkedменяет фон рамки на синий, а:checked::beforeувеличивает галочку сscale(0)доscale(1)— отсюда эффект появления.
Состояния и доступность
Кастомный флажок должен отзываться на наведение, фокус и блокировку, иначе он ощущается сломанным. Добавим состояния к тому же элементу.
.check input[type="checkbox"]:hover {
border-color: #2f80ed;
}
.check input[type="checkbox"]:focus-visible {
outline: 2px solid #2f80ed;
outline-offset: 2px;
}
.check input[type="checkbox"]:disabled {
border-color: #d0d0d0;
background-color: #f1f1f1;
cursor: not-allowed;
}
:focus-visible рисует контур только при навигации с клавиатуры (Tab), а не при клике мышью — так фокус виден тем, кому он нужен, и не мешает остальным.
Здесь же главная оговорка о доступности. Нативный чекбокс нельзя прятать через display: none или visibility: hidden: тогда он выпадает из потока, перестает получать фокус и не переключается с клавиатуры. Подход с appearance: none этим и хорош — элемент остается на месте и фокусируемым, стилизуется сам <input>.
Раньше, до широкой поддержки appearance, флажок скрывали иначе: input уводили за экран (position: absolute; opacity: 0), а рисовали на соседнем <span> или <label> через комбинатор +. Прием рабочий и встречается в старом коде, но в 2026 году стилизация самого input через appearance: none проще и меньше рискует доступностью.
Промежуточное состояние: indeterminate
У чекбокса есть третий визуальный вид — частично отмечен. Его применяют для флажка «выбрать все», когда часть вложенных пунктов отмечена, а часть нет. В CSS для этого есть псевдокласс :indeterminate.
.check input[type="checkbox"]:indeterminate {
background-color: #2f80ed;
border-color: #2f80ed;
}
Граница приема: HTML-атрибута indeterminate не существует, только checked. Само состояние выставляется из скрипта — checkbox.indeterminate = true, — а CSS лишь дает зацепку для стиля. Чистой разметкой промежуточный флажок не задать.
Сводка приемов
| Инструмент | Что дает |
|---|---|
accent-color |
быстро красит нативный флажок, форму не меняет |
appearance: none |
сбрасывает нативный вид для полной перерисовки |
:checked |
стили отмеченного состояния |
:hover |
отклик на наведение |
:focus-visible |
контур фокуса при навигации с клавиатуры |
:disabled |
вид заблокированного поля |
:indeterminate |
промежуточный вид (состояние ставится из JS) |
Выводы
- Чекбокс — независимый выбор из набора; его не путают с радиокнопкой (один из группы) и переключателем (тот же
<input type="checkbox">, оформленный тумблером, сrole="switch"). - Подпись связывают с полем через
<label>(поfor/idили вложением), это расширяет кликабельную зону на текст. - Если нужен только фирменный цвет, хватает
accent-color: он красит нативный флажок, сохраняя поведение и доступность, но не меняет форму, рамку и анимацию. - Полная перерисовка — через
appearance: noneплюс галочка псевдоэлементом::before; нативныйinputпри этом не прячутdisplay: none, иначе теряется фокус и управление с клавиатуры. - Состояния задают псевдоклассами
:checked,:hover,:focus-visible,:disabled; промежуточный вид:indeterminateцепляют стилем, но само состояние ставится из JS.
Где применяется и что учить дальше
Чекбоксы — базовый элемент любой формы: согласие с условиями перед отправкой, фильтры с множественным выбором в каталогах, списки задач, настройки-переключатели. Умение аккуратно переопределить их вид, не потеряв доступность, — обычная задача верстальщика, и те же приемы (appearance: none, псевдоэлементы, состояния через псевдоклассы) переносятся на радиокнопки, select и другие поля.
Освойте тему на практике
Собрать эти навыки системно, с практикой и разбором кода, удобнее на курсе. Хорошая точка входа для новичка — HTML и CSS: курс по разработке сайтов для начинающих, где как раз учат собирать и оформлять интерфейсные элементы страницы. Чтобы заранее посмотреть формат занятий и разобрать тему вживую с преподавателем, загляните на открытые уроки и вебинары Otus.
FAQ
Почему галочку рисуют через clip-path или ::before, а не картинкой? Псевдоэлемент не требует лишнего запроса к серверу, масштабируется без потери четкости и перекрашивается одним свойством цвета. Картинку-иконку пришлось бы держать отдельным файлом и менять на второй вариант для отмеченного состояния.
Можно ли стилизовать чекбокс без appearance: none? Частично. Цвет нативного флажка задает accent-color, и для многих задач этого хватает. Но чтобы поменять форму, рамку, скругление или анимацию, нужен либо appearance: none на самом поле, либо старый прием со скрытием input и отрисовкой на соседнем элементе.
Как сделать флажок крупнее? Задайте width и height в единицах em и увеличьте font-size у контейнера — размер флажка привяжется к тексту. Свойство transform: scale() тоже увеличивает элемент, но может размыть рамку и контур фокуса, поэтому для чекбокса надежнее явные размеры.



