Меня зовут София. Я - CSS инженер. Это мой блог.

Если вам очень больно без стилей, вы можете их.

.

Радио-кнопки на градиентах

пример применения индивидуальных свойств трансформации

Верстаем классические радио-кнопки с помощью градиентов. Начнём с разметки:

<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);
}