Стилизация радиокнопок (кастомизация radio buttons)

Стилизация радиокнопок (кастомизация radio buttons) Верстка
Радиокнопки являются важной частью веб-форм, позволяя пользователям выбирать один вариант из группы. Однако стандартный вид радиокнопок зачастую не соответствует дизайну сайта, что требует их стилизации. В этой статье мы рассмотрим все возможные способы стилизации радиокнопок, начиная с базовых приемов и заканчивая более сложными подходами, включая использование JavaScript.

Радиокнопки — это элементы формы, которые позволяют выбрать один вариант из нескольких предложенных. Обычно они имеют круглый вид и заполнены внутри при выборе. Несмотря на свою простоту, стандартные радиокнопки могут не вписываться в дизайн вашего сайта, что делает их стилизацию необходимой.

Стилизация радиокнопок позволяет не только улучшить внешний вид интерфейса, но и повысить его удобство и доступность для пользователей. Давайте разберем основные подходы к стилизации и их особенности.

Базовые принципы работы радиокнопок

Радиокнопки определяются в HTML с помощью тега <input type="radio">. При выборе одной кнопки остальные в группе автоматически снимаются, что позволяет выбрать только один вариант. Вот пример базовой HTML разметки:

<form>
    <input type="radio" id="option1" name="options" value="1" checked>
    <label for="option1">Активная опция</label>
    <input type="radio" id="option2" name="options" value="2">
    <label for="option2">Неактивна опция</label>
    <input type="radio" id="option3" name="options" value="3" disabled>
    <label for="option3">Деактивированная опция</label>
</form>

Радиокнопки по умолчанию

Стилизация стандартных радиокнопок ограничена, так как браузеры предоставляют лишь базовые настройки. Для более детальной настройки используются CSS и JavaScript.

Основные методы стилизации радиокнопок

Существует несколько методов стилизации радиокнопок:

  • Применение CSS-свойств, таких как transform, accent-color.
  • Использование псевдоэлементов ::before и ::after.
  • Стилизация с помощью JavaScript для динамического изменения внешнего вида.

1. Стилизация стандартных радиокнопок с помощью CSS свойств

Вот описания основных CSS-свойства, которые можно использовать для стилизации стандартных радиокнопок:

  1. transform: современная альтернатива width и height.
  2. accent-color: изменяет цвет фона нажатой радиокнопки.

Html разметка стандартная (можете взять выше), а вот пример CSS:

input[type="radio"] {
    transform: scale(1.6); 
    accent-color: #4CAF50;
}

Результат:

Пример базовой стилизации

2. Стилизация с помощью псевдоэлементов ::before и ::after

Псевдоэлементы ::before и ::after позволяют добавлять кастомные элементы перед или после радиокнопки, что помогает создавать уникальный стиль. Суть данного метода заключается в том, что мы скрываем стандартную радиокнопку и рисуем новую.

Рассмотрим пример для все той же базовой HTML разметки:

/* Скрываем стандартную радиокнопку и убираем ее из потока */
input[type="radio"] {
position: absolute;
z-index: -1;
opacity: 0;
}
/* Стилизация метки радиокнопки */
input[type="radio"] + label {
    position: relative;
    padding-left: 30px;
    cursor: pointer;
}
/* Кастомная радиокнопка */
input[type="radio"] + label::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 20px;
    height: 20px;
    border: 2px solid #000;
    border-radius: 50%;
}
/* Состояние выбранной радиокнопки */
input[type="radio"]:checked + label::before {
    background-color: #4CAF50;
    box-shadow: inset 0 0 0 4px #f4f4f4;
    border: 2px solid #4CAF50;
}

Получаем:

Стилизация с помощью псевдоэлементов

В этом примере стандартная радиокнопка скрывается, а стилизация осуществляется через псевдоэлемент ::before. Радиокнопка приобретает вид круга с границей, которая заполняется цветом при выборе.

Далее при необходимости мы можем стили различных состояний для радиокнопок:

/* стили при наведении курсора на радиокнопку */
input[type="radio"]:not(:disabled):not(:checked)+label:hover::before {
  border-color: #4CAF50;
}
/* стили радиокнопки, находящейся в фокусе */
input[type="radio"]:focus+label::before {
    outline: none;
}
 /* стили для радиокнопки, находящейся в состоянии disabled */
input[type="radio"]:disabled + label::before {
    box-shadow: inset 0 0 0 4px #f4f4f4;
    border-color: #b4b4b4;
    background: #b4b4b4;
}

Стилизация с помощью псевдоэлементов с доп состояниями

Иногда вместо стандартного круга радиокнопки требуется использовать кастомное изображение или иконку. Для этого можно задать фоновое изображение:

input[type="radio"]:checked + label::before {
    background-image: url('https://web-revenue.ru/wp-content/uploads/2024/10/icons8-check-48.png');
    background-size: contain;
    width: 20px;
    height: 20px;
    border: 2px solid #4CAF50;
}

Радиокнопки с изображением

Так же вы можете использовать CSS шрифты типа фонт авесоме, спецсимволы:

input[type="radio"]:checked + label::before {
    content: "\2605";
    border: 2px solid #4CAF50;
    font-size: 1.3rem;
    line-height: 20px;
    text-align: center;
    color: #4CAF50;
}

Радиокнопки со спецсимволами

Эти подходы позволяют добавить визуальные элементы, которые лучше подходят к стилю сайта.

Так же при необходимости можно все это дело анимировать, к примеру вот так:

/* Анимация при выборе */
input[type="radio"]:checked + label::before {
    animation: scaleUp 0.2s ease-in-out forwards;
}
@keyframes scaleUp {
    from { transform: scale(1); }
    to { transform: scale(1.2); }
}

Чтобы анимация выглядела адекватной потребуются оборачивать все в дополнительные контейнеры, примеры будут ниже.

3. Стилизация с помощью JS

JavaScript позволяет динамически менять внешний вид радиокнопок и обрабатывать события, такие как клик? полезно при создании интерфейсов. Рассмотрим небольшой пример.

Базовая HTML разметка, где у нас будут радиокнопки:

<div class="radio-group">
        <input type="radio" id="option1" name="customRadio" value="1">
        <label for="option1" class="custom-radio"></label>
        
        <input type="radio" id="option2" name="customRadio" value="2">
        <label for="option2" class="custom-radio"></label>
</div>

Теперь добавим стили для наших кастомных радиокнопок:

.radio-group {
    display: flex;
    gap: 10px;
}
input[type="radio"] {
    display: none;
}
.custom-radio {
    width: 20px;
    height: 20px;
    border: 2px solid #000;
    border-radius: 50%;
    display: inline-block;
    position: relative;
    cursor: pointer;
}
.custom-radio::after {
    content: '';
    width: 12px;
    height: 12px;
    background: #000;
    border-radius: 50%;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    opacity: 0;
    transition: opacity 0.2s;
}
input[type="radio"]:checked + .custom-radio::after {
    opacity: 1;
}

И наконец, добавим JavaScript для обработки событий:

document.querySelectorAll('.custom-radio').forEach(radio => {
    radio.addEventListener('click', function() {
        const input = this.previousElementSibling;
        input.checked = true;
    });
});

В итоге получилось следующее:

Стилизация с помощью JS

Объяснение

  1. HTML: Мы создаем группу радиокнопок с помощью <input type="radio"> и связываем их с кастомными метками <label>.
  2. CSS: Скрываем стандартные радиокнопки и стилизуем метки, чтобы они выглядели как радиокнопки. Используем псевдоэлемент ::after для отображения внутреннего круга, который появляется при выборе.
  3. JavaScript: Добавляем обработчик событий на кастомные радиокнопки, чтобы при клике на метку соответствующая радиокнопка становилась выбранной.

Этот пример демонстрирует базовый подход к созданию кастомных радиокнопок. Вы можете расширить его, добавив дополнительные стили и функциональность по своему усмотрению.

Например, давайте анимируем их переключение и добавим названия опций, для этого:

  1. Немного модифицируем HTML разметку:
    <div class="radio-group">
            <input type="radio" id="option1" name="customRadio" value="1">
            <label for="option1" class="custom-radio"></label>
            <span>Опция 1</span>
            
            <input type="radio" id="option2" name="customRadio" value="2">
            <label for="option2" class="custom-radio"></label>
            <span>Опция 2</span>
    </div>
  2. Немного модифицируем CSS:
    .radio-group {
        display: flex;
        align-items: center;
        gap: 10px;
    }
    input[type="radio"] {
        display: none;
    }
    .custom-radio {
        width: 20px;
        height: 20px;
        border: 2px solid #000;
        border-radius: 50%;
        display: inline-block;
        position: relative;
        cursor: pointer;
        transition: border-color 0.3s ease;
    }
    .custom-radio::after {
        content: '';
        width: 12px;
        height: 12px;
        background: #000;
        border-radius: 50%;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        opacity: 0;
        transition: opacity 0.3s ease, transform 0.3s ease;
    }
    input[type="radio"]:checked + .custom-radio {
        border-color: #007BFF;
    }
    input[type="radio"]:checked + .custom-radio::after {
        opacity: 1;
        transform: translate(-50%, -50%) scale(1.2);
    }
    .radio-group span {
        margin-left: 5px;
        font-size: 16px;
        cursor: pointer;
    }
  3. JS у нас остается прежним.
Стилизация с помощью JS с анимацией
Результат

Объяснение:

  1. HTML: Добавляем <span> элементы для отображения названий опций рядом с радиокнопками.
  2. CSS: Стилизуем текстовые метки, чтобы они выглядели аккуратно рядом с радиокнопками. Используем margin-left для отступа текста от кнопки. А так же добавляем transition для свойств border-coloropacity и transform, чтобы анимация была плавной. При выборе радиокнопки изменяется цвет границы и появляется внутренний круг с увеличением.

Примеры различных кастомных Radio Button

Рассмотрим различные примеры изменения вида радио кнопок на чистом CSS.

Коллекция стилей радиокнопок (default, rounded, diamond) с небольшой анимацией

Коллекция стилей радиокнопок (default, rounded, diamond) с небольшой анимацией

Html:

<div class="styled-input-container">
      <div class="styled-input-single">
        <input type="radio" name="fieldset-1" id="radio-example-one" />
        <label for="radio-example-one">Опция 1</label>
      </div>
      <div class="styled-input-single">
        <input type="radio" name="fieldset-1" id="radio-example-two" />
        <label for="radio-example-two">Опция 2</label>
      </div>
      <div class="styled-input-single">
        <input type="radio" name="fieldset-1" id="radio-example-three" />
        <label for="radio-example-three">Опция 3</label>
      </div>
    </div>

    <div class="styled-input-container styled-input--rounded">
      <div class="styled-input-single">
        <input type="radio" name="fieldset-3" id="radio3-example-one" />
        <label for="radio3-example-one">Опция 1</label>
      </div>
      <div class="styled-input-single">
        <input type="radio" name="fieldset-3" id="radio3-example-two" />
        <label for="radio3-example-two">Опция 2</label>
      </div>
      <div class="styled-input-single">
        <input type="radio" name="fieldset-3" id="radio3-example-three" />
        <label for="radio3-example-three">Опция 3</label>
      </div>
    </div>

    <div class="styled-input-container styled-input--diamond">
      <div class="styled-input-single">
        <input type="radio" name="fieldset-4" id="radio4-example-one" />
        <label for="radio4-example-one">Опция 1</label>
      </div>
      <div class="styled-input-single">
        <input type="radio" name="fieldset-4" id="radio4-example-two" />
        <label for="radio4-example-two">Опция 2</label>
      </div>
      <div class="styled-input-single">
        <input type="radio" name="fieldset-4" id="radio4-example-three" />
        <label for="radio4-example-three">Опция 3</label>
      </div>
    </div>
</div>

CSS:

.styled-input-single {
    position: relative;
    display: inline-flex;
    padding: 20px 0 20px 40px;
}
.styled-input-single label {
  cursor: pointer;
  margin-right: 10px;
}
.styled-input-single label:before, .styled-input-single label:after {
  content: '';
  position: absolute;
  top: 50%;
  border-radius: 50%;
}
.styled-input-single label:before {
  left: 0;
  width: 30px;
  height: 30px;
  margin: -15px 0 0;
  background: #f7f7f7;
  box-shadow: 0 0 1px grey;
}
.styled-input-single label:after {
  left: 5px;
  width: 20px;
  height: 20px;
  margin: -10px 0 0;
  opacity: 0;
  background: #37b2b2;
  transform: translate3d(-40px, 0, 0) scale(0.5);
  transition: opacity 0.25s ease-in-out, transform 0.25s ease-in-out;
}
.styled-input-single input[type="radio"], .styled-input-single input[type="checkbox"] {
  position: absolute;
  top: 0;
  left: -9999px;
  visibility: hidden;
}
.styled-input-single input[type="radio"]:checked + label:after, .styled-input-single input[type="checkbox"]:checked + label:after {
  transform: translate3d(0, 0, 0);
  opacity: 1;
}
.styled-input--square label:before, .styled-input--square label:after {
  border-radius: 0;
}
.styled-input--rounded label:before {
  border-radius: 10px;
}
.styled-input--rounded label:after {
  border-radius: 6px;
}
.styled-input--diamond .styled-input-single {
  padding-left: 45px;
}
.styled-input--diamond label:before, .styled-input--diamond label:after {
  border-radius: 0;
}
.styled-input--diamond label:before {
  transform: rotate(45deg);
}
.styled-input--diamond input[type="radio"]:checked + label:after, .styled-input--diamond input[type="checkbox"]:checked + label:after {
  transform: rotate(45deg);
  opacity: 1;
}

 <input type="radio" id="option12" name="options"> <label for="option12" class="button">Option 2</label>

<div class="radio-buttons">
  <input type="radio" id="option1" name="options" checked>
  <label for="option1" class="button">Option 1</label>

  <input type="radio" id="option2" name="options">
  <label for="option2" class="button">Option 2</label>

  <input type="radio" id="option3" name="options">
  <label for="option3" class="button">Option 3</label>
  
  <input type="radio" id="option4" name="options" disabled>
  <label for="option4" class="button">Option 4</label>
</div>
.radio-buttons {
  display: flex;
  gap: 10px;
}
.radio-buttons input[type="radio"] {
  display: none;
}
.radio-buttons .button {
  padding: 10px 20px;
  border: 2px solid #007BFF;
  border-radius: 5px;
  background-color: #fff;
  color: #007BFF;
  cursor: pointer;
  transition: background-color 0.3s, color 0.3s;
}
/* Checked */
.radio-buttons input[type="radio"]:checked + .button {
  background-color: #007BFF;
  color: #fff;
}
/* Hover */
.radio-buttons .button:hover {
  background-color: #0056b3;
  color: #fff;
}
/* Disabled */
.radio-buttons input[type=radio]:disabled + label {
	background: #efefef;
	color: #666;
}

Группа кнопок

Группа кнопок

<div class="button-group">
    <div class="button-group-item">
       <input type="radio" id="btn1" name="group" checked>
       <label for="btn1">Button 1</label>
    </div>
    <div class="button-group-item">
      <input type="radio" id="btn2" name="group">
      <label for="btn2">Button 2</label>
    </div>
    <div class="button-group-item">
      <input type="radio" id="btn3" name="group">
      <label for="btn3">Button 3</label>
    </div>
    <div class="button-group-item">
      <input type="radio" id="btn4" name="group" disabled>
      <label for="btn4">Button 4</label>
    </div>
</div>
.button-group {
    display: inline-block;
	overflow: hidden;
}
.button-group-item {
	display: inline-block;  
    float: left;
}
.button-group-item input[type="radio"] {
  display: none;
}
.button-group-item label {
	display: inline-block;
	cursor: pointer;
    padding: 5px 15px;
	border: 1px solid #999;
	border-right: none;
	user-select: none;
    transition: background-color 0.3s, color 0.3s;
}
.button-group .button-group-item:first-child label {
	border-radius: 6px 0 0 6px;
}
.button-group .button-group-item:last-child label {
	border-radius: 0 6px 6px 0;
	border-right: 1px solid #999;
}
/* Checked */
.button-group-item  input[type="radio"]:checked + label {
  background-color: #007BFF;
  color: #fff;
}
/* Hover */
.button-group-item  label:hover {
  background-color: #0056b3;
  color: #fff;
}
/* Disabled */
.button-group-item  input[type=radio]:disabled + label {
	background: #efefef;
	color: #666;
}

Переключатель

Переключатель

<div class="toggle-switch">
    <div class="toggle-switch-item one">
      <input type="radio" id="on" name="toggle" checked>
      <label for="on" class="switch">ON</label>
    </div>
    <div class="toggle-switch-item two">
      <input type="radio" id="off" name="toggle">
      <label for="off" class="switch">OFF</label>
    </div>
</div>
.toggle-switch {
  display: inline-flex;
  align-items: center;
  overflow: hidden;
}
.toggle-switch-item input[type="radio"] {
  display: none;
}
.toggle-switch-item  .switch {
  padding: 4px 17px;
  border: 2px solid #007BFF;
  border-radius: 5px;
  background-color: #fff;
  color: #007BFF;
  cursor: pointer;
  line-height: 34px; 
  transition: background-color 0.3s, color 0.3s;
  border: 1px solid #007BFF;
  border-right: none;
  cursor: pointer;
  user-select: none; 
}
.toggle-switch-item.one  .switch {
  border-radius: 6px 0 0 6px;
}
.toggle-switch-item.two .switch {
  border-radius: 0 6px 6px 0;
  border-right: 1px solid #007BFF;
}
/* Checked */
.toggle-switch-item input[type="radio"]:checked + .switch {
  background-color: #007BFF;
  color: #fff;
}
/* Hover */
.toggle-switch-item .switch:hover {
  background-color: #0056b3;
  color: #fff;
}

Коллекции радиокнопок из Codepen для вдохновения

Все ссылки открываются в новом окне.

  1. Pure CSS – SVG Radio Selector Buttons.
    Pure CSS – SVG Radio Selector Buttons
  2. Project Management Triangle Selector.
    Project Management Triangle Selector
  3. Google Dots Radio Buttons.
    Google Dots Radio Buttons
  4. Custom SCSS3 Radio Button – Radiosplosion.
    Custom SCSS3 Radio Button – Radiosplosion
  5. Радиокнопки и переключалки текста.
    Радиокнопки и переключалки текста
  6. NEUMORPHIC RADIO.
    NEUMORPHIC RADIO
  7. Nerf Gun Radio Button.
    Nerf Gun Radio Button
  8. Slap Toggle.
    Slap Toggle
  9. Smile Toggle.
    Smile Toggle
  10. Balloon Radio Buttons.
    Balloon Radio Buttons
  11. Стандартные радиокнопки с интересной анимацией.
    Стандартные радиокнопки с интересной анимацией
  12. Radio Button Circuit.
    Radio Button Circuit

Дополнительная информация

При стилизации радиокнопок важно учитывать доступность. Убедитесь, что элементам формы заданы aria-атрибуты и они могут быть использованы с клавиатуры:

<input type="radio" id="option1" name="options" aria-checked="false">

Такие меры делают интерфейс более удобным для людей с ограниченными возможностями.

Проверяйте стилизацию радиокнопок в разных браузерах и устройствах, чтобы избежать проблем с отображением. Используйте инструменты, такие как BrowserStack или CrossBrowserTesting, чтобы убедиться в кроссбраузерной совместимости.

При стилизации радиокнопок следует придерживаться общих принципов дизайна интерфейсов. Согласованность стиля помогает пользователям быстрее привыкать к интерфейсу и снижает когнитивную нагрузку.

Часто встречающиеся ошибки при стилизации радиокнопок:

  • Отсутствие поддержки доступности (неправильное использование aria-атрибутов).
  • Некорректное отображение в старых браузерах.
  • Трудности с адаптивностью.

Заключение

Стилизация радиокнопок помогает создать более привлекательные и удобные пользовательские интерфейсы. Важно выбирать подходящий метод в зависимости от требований проекта и учитывать доступность и кроссбраузерную совместимость.

Экспериментируйте с различными подходами, чтобы найти оптимальные решения для своих проектов.

Поделиться с друзьями
Алексей

Веб-дизайнер и SEO оптимизатор. Занимаюсь созданием сайтов с 2010 года и их продвижение с 2012 года!

Оцените автора
( 2 оценки, среднее 5 из 5 )
Web-Revenue.ru
Добавить комментарий

  1. xây dựng nhà ở

    I used to be recommended this blog by means of my cousin. I’m now not sure
    whether this put up is written by him as nobody else realize such precise approximately
    my problem. You’re amazing! Thank you!

    Ответить
    1. Алексей автор

      Please

      Ответить