<form>
    <h2>Radio Buttons</h2>
    <span id="fill" class="radio-ghost-fill"></span>
    <label>
      <input name="items" type="radio" />
      <span class="radio-ghost"></span>
      Item one
    </label>

    <label>
      <input name="items" type="radio" />
      <span class="radio-ghost"></span>
      Item two
    </label>

    <label>
      <input name="items" type="radio" />
      <span class="radio-ghost"></span>
      Item three
    </label>
  </form>
 html {
      --accent: #0f03c2;
      --dark-accent: #0a0644;
    }

      body {
        min-height: 100vh;
        font-family: 'Roboto', sans-serif;
        font-size: 15px;
        color: var(--dark-accent);
        background: #ffffff;
        overflow: hidden;
      }

      form {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 250px;
        min-height: 100vh;
        margin: auto;
        flex-direction: column;
      }

      h2, h1 {
        flex-shrink: 0;
        font-weight: 500;
      }

      h1 {
        font-size: 1.35em;
      }

      h2 {
        width: 100%;
        padding-top: 20px;
        font-size: 1.2em;
      }

      label {
        position: relative;
        flex-shrink: 0;
        transition: all 200ms ease-in;
        display: flex;
        align-items: center;
        cursor: pointer;
        height: 50px;
        width: 100%;
        padding: 0 10px;
        border-radius: 8px;
        border: 1px solid transparent;
        margin-bottom: 5px;
        font-weight: 500;
      }

      input[type='radio'], input[type='checkbox'] {
        position: absolute;
        opacity: 0;
      }

      .radio-ghost {
        position: relative;
        display: block;
        width: 18px;
        height: 18px;
        border-radius: 18px;
        border: 3px solid var(--accent);
        margin-right: 10px;
      }

      .radio-ghost-fill {
        position: absolute;
        transition: all 250ms ease-in-out;
        transform: scale(.2);
        content: '';
        width: 14px;
        height: 14px;
        background-color: var(--accent);
        border-radius: 7px;
        opacity: 0;
      }
 document.addEventListener('DOMContentLoaded', function () {
      var radioButtons = document.getElementsByName('items');
      var fill = document.getElementById('fill');
      var hasSelection = false;
      var prevRect, checkedButton;

      function updateOffsets() {
        if (checkedButton) {
          var rect = checkedButton.nextElementSibling.getBoundingClientRect();
          fill.style.transition = 'none';
          fill.style.top = (rect.top + 5  + document.body.scrollTop) + 'px';
          fill.style.left = (rect.left + 5 + document.body.scrollLeft) + 'px';
          prevRect = rect;
        }
      }

      window.addEventListener('resize', updateOffsets);
      window.addEventListener('scroll', updateOffsets);

      document.addEventListener('change', function (e) {
         if (e.target.name === 'items') {


          Array.from(radioButtons).forEach(function (radioButton) {
            if (radioButton.checked) {
              checkedButton = radioButton;
              radioButton.parentNode.className = 'selected';
              var rect = radioButton.nextElementSibling.getBoundingClientRect();

              if (!hasSelection) {
                fill.style.transition = 'none';
                fill.style.top = (rect.top + 5 + document.body.scrollTop) + 'px';
                fill.style.left = (rect.left + 5 + document.body.scrollLeft) + 'px';

                fill.style.transform = 'scale(.2)';

                setTimeout(function () {
                  fill.style.transition = '';
                  fill.style.opacity = 1;
                  fill.style.transform = 'scale(1)';
                }, 25);
              } else {
                fill.style.transition = 'none';
                fill.style.top = (rect.top + 5 + document.body.scrollTop) + 'px';
                fill.style.left = (rect.left + 5 + document.body.scrollLeft) + 'px';
                fill.style.transform = 'scale(1) translateY(' + (0 - (rect.top - prevRect.top - 5)) + 'px)';

                setTimeout(function () {
                  fill.style.transition = '';
                  fill.style.opacity = 1;
                  fill.style.transform = 'scale(1) translateY(0px) translateX(0px)';
                }, 25);

              }

              hasSelection = true;
              prevRect = rect;
            } else {
              radioButton.parentNode.className = '';
            }
          });

          return;
        }
      });
    });

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.