Кастомизация radio и checkbox с помощью CSS

Тренажер по CSS для пользователей с начальным уровнем подготовки.

Тренажер CSS

В этой серии заданий вы научитесь изменять стандартный внешний вид флажков (checkbox) и переключателей (radio button) с помощью CSS. Мы скроем стандартные элементы управления и создадим свои собственные, стилизуя их состояния (выбранное, невыбранное, фокус, неактивное). Задания построены от простого к сложному: начнем со скрытия стандартных элементов и базовой стилизации, затем добавим состояния, изображения и переходы.

Список тем

Скрытие стандартных элементов

Первый шаг в кастомизации — скрыть стандартные флажки и переключатели, чтобы они не мешали нашим собственным стилям. Используйте подходящее CSS свойство, чтобы сделать элементы <input> невидимыми, но при этом доступными для взаимодействия.

CSS
/* Скрываем стандартные input */
input[type="checkbox"],
input[type="radio"] {
  input1: absolute;
  input2: 0;
  width: 1px; /* Не 0, чтобы сохранить доступность */
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}

.control-group {
  margin-bottom: 10px;
}

/* Базовые стили для label (пока без кастомных контролов) */
label {
  display: inline-block;
  padding-left: 5px;
  cursor: pointer;
}
HTML
<form>
  <div class="control-group">
    <input type="checkbox" id="c1" name="cc" />
    <label for="c1">Чекбокс 1</label>
  </div>
  <div class="control-group">
    <input type="radio" id="r1" name="rr" />
    <label for="r1">Радио 1</label>
  </div>
  <div class="control-group">
    <input type="radio" id="r2" name="rr" />
    <label for="r2">Радио 2</label>
  </div>
</form>
Чтобы скрыть элемент, сохранив его функциональность (например, возможность получить фокус), часто используют комбинацию свойств, таких как `position: absolute`, `opacity: 0`, `width: 0`, `height: 0` или `appearance: none`. В данном случае достаточно одного простого свойства, чтобы визуально убрать элемент из потока.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Создание кастомного чекбокса

Теперь создадим основу для нашего кастомного чекбокса. Используйте псевдоэлемент `::before` для элемента `<label>`, связанного с чекбоксом. Задайте ему базовые стили: размеры, рамку и отступ справа, чтобы он выглядел как пустой квадратик.

CSS
input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}

.control-group {
  margin-bottom: 10px;
}

label {
  cursor: pointer;
  display: inline-flex; /* Для выравнивания псевдоэлемента и текста */
  align-items: center;
}

/* Создаем кастомный чекбокс */
input[type="checkbox"] + labelinput1::before {
  input2: ""; /* Обязательно для отображения псевдоэлемента */
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 1px solid #aaa;
  border-radius: 3px;
  margin-right: 8px;
  background-color: #fff;
}
HTML
<form>
  <div class="control-group">
    <input type="checkbox" id="c1" name="cc" />
    <label for="c1">Кастомный чекбокс</label>
  </div>
</form>
Вам нужно выбрать `<label>`, который идет сразу после скрытого `<input type="checkbox">`. Используйте селектор смежного родственного элемента (`+`). Для создания видимого блока используйте псевдоэлемент `::before`. Задайте ему свойства `content`, `display`, `width`, `height`, `border` и `margin-right`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Стилизация состояния :checked для чекбокса

Добавим стиль для выбранного состояния чекбокса. Когда чекбокс отмечен, наш кастомный элемент должен измениться. Используйте псевдокласс `:checked` и селектор смежного элемента, чтобы изменить фон кастомного чекбокса (псевдоэлемента `::before`) на синий цвет (#007bff).

CSS
input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.control-group {
  margin-bottom: 10px;
}

label {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

input[type="checkbox"] + label::before {
  content: "";
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 1px solid #aaa;
  border-radius: 3px;
  margin-right: 8px;
  background-color: #fff;
}

/* Стиль для отмеченного состояния */
input[type="checkbox"]input1 + label::before {
  input2: #007bff;
  border-color: #007bff;
}
HTML
<form>
  <div class="control-group">
    <input type="checkbox" id="c1" name="cc" checked />
    <label for="c1">Отмеченный чекбокс</label>
  </div>
   <div class="control-group">
    <input type="checkbox" id="c2" name="cc2" />
    <label for="c2">Неотмеченный чекбокс</label>
  </div>
</form>
Вам нужно выбрать псевдоэлемент `::before` у `<label>`, который следует за *отмеченным* `<input type="checkbox">`. Используйте псевдокласс `:checked` на `input`, селектор смежного элемента (`+`) для выбора `label` и затем `::before` для стилизации самого квадратика. Измените свойство `background-color`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Создание кастомного radio button

Аналогично чекбоксу, создадим кастомный переключатель (radio button). Используйте псевдоэлемент `::before` для `<label>`, связанного с radio input. Сделайте его круглым с помощью `border-radius`.

CSS
input[type="radio"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.control-group {
  margin-bottom: 10px;
}

label {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

/* Создаем кастомный radio */
input[type="radio"] + labelinput1::before {
  content: "";
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 1px solid #aaa;
  input2: 50%; /* Делаем круглым */
  margin-right: 8px;
  background-color: #fff;
  box-sizing: border-box; /* Учитываем рамку в размере */
}
HTML
<form>
  <div class="control-group">
    <input type="radio" id="r1" name="rr" />
    <label for="r1">Радио 1</label>
  </div>
  <div class="control-group">
    <input type="radio" id="r2" name="rr" />
    <label for="r2">Радио 2</label>
  </div>
</form>
Выберите `<label>`, идущий после `<input type="radio">`, с помощью селектора `+`. Используйте псевдоэлемент `::before` с `content: ""`. Задайте ему `width`, `height`, `border` и `margin-right`. Чтобы сделать его круглым, используйте свойство `border-radius` со значением `50%`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Стилизация состояния :checked для radio button

Добавим стиль для выбранного radio button. Когда переключатель выбран, внутри нашего кастомного круга должен появиться другой круг меньшего размера. Используйте псевдокласс `:checked` и псевдоэлемент `::after` для `<label>`, чтобы создать внутренний круг.

CSS
input[type="radio"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.control-group {
  margin-bottom: 10px;
}

label {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

input[type="radio"] + label::before {
  content: "";
  display: inline-block;
  width: 18px; /* Чуть больше для ::after */
  height: 18px;
  border: 1px solid #aaa;
  border-radius: 50%;
  margin-right: 8px;
  background-color: #fff;
  box-sizing: border-box;
  input1: relative; /* Контекст позиционирования для ::after */
}

/* Стиль для внутреннего круга отмеченного radio */
input[type="radio"]:checked + labelinput2::after {
  content: "";
  display: block;
  width: 10px;
  height: 10px;
  background-color: #007bff;
  border-radius: 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  input3: translate(-50%, -50%);
}
HTML
<form>
  <div class="control-group">
    <input type="radio" id="r1" name="rr" checked />
    <label for="r1">Радио 1 (выбрано)</label>
  </div>
  <div class="control-group">
    <input type="radio" id="r2" name="rr" />
    <label for="r2">Радио 2</label>
  </div>
</form>
Выберите `<label>`, следующий за *отмеченным* `<input type="radio">`, используя `:checked` и `+`. Примените стили к псевдоэлементу `::after` этого `<label>`. Задайте ему `content`, `display`, `width`, `height`, `background-color` и `border-radius: 50%`. Чтобы спозиционировать внутренний круг по центру, можно использовать `position: absolute` для `::after` и `position: relative` для `::before`, а затем свойства `top`, `left` и `transform: translate(-50%, -50%)`. Убедитесь, что `::before` имеет `position: relative`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Кастомный чекбокс с изображением

Заменим стандартный вид чекбокса на изображение. Используйте фоновое изображение для псевдоэлемента `::before`. Примените одно изображение для невыбранного состояния и другое для выбранного (`:checked`).

CSS
input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.control-group {
  margin-bottom: 10px;
}

label {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

input[type="checkbox"] + label::before {
  content: "";
  display: inline-block;
  width: 24px; /* Размер картинки */
  height: 24px; /* Размер картинки */
  margin-right: 8px;
  input1: no-repeat;
  background-position: center;
  /* Картинка для невыбранного состояния */
  background-image: url("https://naytikurs.ru/img/7.png");
}

/* Картинка для выбранного состояния */
input[type="checkbox"]:checked + label::before {
  input2: url("https://naytikurs.ru/img/8.png");
}
HTML
<form>
  <div class="control-group">
    <input type="checkbox" id="c1" name="cc" />
    <label for="c1">Чекбокс с картинкой</label>
  </div>
   <div class="control-group">
    <input type="checkbox" id="c2" name="cc2" checked />
    <label for="c2">Отмеченный чекбокс</label>
  </div>
</form>
Сначала задайте базовые стили для `::before`, включая `width`, `height` и `background-repeat: no-repeat`, `background-position: center`. Уберите рамку (`border: none`). Затем для невыбранного состояния (`input[type="checkbox"] + label::before`) установите `background-image` с URL картинки для пустого чекбокса. Для выбранного состояния (`input[type="checkbox"]:checked + label::before`) установите `background-image` с URL картинки для отмеченного чекбокса.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Добавление стилей фокуса и неактивности

Улучшим доступность и информативность наших кастомных элементов. Добавьте стиль для состояния фокуса (когда пользователь переходит на элемент с клавиатуры) и для неактивного состояния (`disabled`). Для фокуса используйте `outline` или `box-shadow` на псевдоэлементе `::before`, когда исходный `input` получает фокус. Для неактивного состояния измените прозрачность или цвет.

CSS
input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.control-group {
  margin-bottom: 10px;
}

label {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

input[type="checkbox"] + label::before {
  content: "";
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 1px solid #aaa;
  border-radius: 3px;
  margin-right: 8px;
  background-color: #fff;
  transition: background-color 0.2s, border-color 0.2s;
}

input[type="checkbox"]:checked + label::before {
  background-color: #007bff;
  border-color: #007bff;
}

/* Стиль фокуса */
input[type="checkbox"]input1 + label::before {
  outline: 2px solid #80bdff;
  outline-offset: 2px;
  /* или box-shadow: 0 0 0 2px #80bdff; */
}

/* Стили для неактивного состояния */
input[type="checkbox"]input2 + label {
  cursor: not-allowed;
  color: #999;
}

input[type="checkbox"]:disabled + label::before {
  input3: 0.6;
  background-color: #e9ecef;
}
HTML
<form>
  <div class="control-group">
    <input type="checkbox" id="c1" name="cc" />
    <label for="c1">Обычный</label>
  </div>
  <div class="control-group">
    <input type="checkbox" id="c2" name="cc" disabled />
    <label for="c2">Неактивный</label>
  </div>
   <div class="control-group">
    <input type="checkbox" id="c3" name="cc" disabled checked />
    <label for="c3">Неактивный и отмечен</label>
  </div>
</form>
Для стилизации фокуса используйте псевдокласс `:focus` на `input` в сочетании с селектором `+` и `::before`. Примените `outline` или `box-shadow`. Для стилизации неактивного состояния используйте псевдокласс `:disabled` на `input`, селектор `+` для `label` и `::before`. Измените `opacity` или `background-color` и `border-color` для `::before`, а также `cursor: not-allowed` для `label`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку
НайтиКурс.Ру