.
Радио-кнопки на градиентах
Верстаем классические радио-кнопки с помощью градиентов. Начнём с разметки:
<input type="radio">
<style>
input {
/* 🪄 ✨ */
}
</style>
Первое, что следует сделать для стилизации инпута, сбросить ему свойства appearance
в значение
none
.
input {
appearance: none;
}
В большинстве мест это свойство описано как "отвечающее за платформо-специфические стили элемента". Не будем вдаваться в подробности и поверим авторам этих источников. Если не задать здесь нужное значение, почти никакие другие свойства не будут иметь эффекта.
Теперь инпут выглядит буквально никак...
... и можно начать добавлять нужные стили.
input {
appearance: none;
height: 3em;
width: 3em;
border: 0.1em solid grey;
border-radius: 50%;
}
Стили для активного состояния задаются через псевдокласс :checked
, кружок в центре нарисуем с
помощью градиента:
input:checked {
background-image: radial-gradient(
var(--green) 30%,
transparent calc(30% + 1px)
);
border-color: var(--green);
}
Градиент до 30% + 1px
, а не 30%, как можно было бы предположить, из-за некоторых дефектов
рендеринга, возникающих при слишком резких переходах. Сравните сами:
Анимация на ваш выбор
Есть два варианта анимации центрального кружка: анимировать его цвет из прозрачного, или анимировать его размер из нулевого.
Для любого из них требуется использовать директиву @property
. Подробнее о ней писала в этой статье. Здесь она потребуется,
потому что нужно анимировать градиент в свойстве background-image
.
Это свойство имеет дискретный тип анимации. Это значит, что плавного перехода между двумя фоновыми картинками не существует. В момент посередине между двумя ключевыми кадрами картинка просто резко меняются.
Поэтому заменим размеры градиента на переменную, типизируем ее и будем анимировать ёё.
@property --gradientSize {
syntax: "<percentage>";
inherits: false;
initial-value: 0%;
}
input {
background-image: radial-gradient(
var(--green) var(--gradientSize),
transparent calc(var(--gradientSize) + var(--addition, 0))
);
transition-property: border-color, --gradientSize;
transition-duration: 0.2s;
}
input:checked {
--addition: 1px;
--gradientSize: 30%;
border-color: var(--green);
}
Теперь переход между состояниями происходит плавно:
Так же можно сделать и для цвета:
@property --gradientColor {
syntax: "<color>";
inherits: false;
initial-value: transparent;
}
input {
background-image: radial-gradient(
var(--gradientColor) 30%,
transparent calc(30% + 1px)
);
transition-property: border-color, --gradientColor;
transition-duration: 0.2s;
}
input:checked {
--gradientColor: var(--green);
border-color: var(--green);
}