Customize radio buttons elements

Web developers could style form elemets with CSS pseudo class & pseudo elements and other modern CSS properties.

HTML structure

<div class="radio-set"> <input id="my-radio" type="radio" name="radio" value="0" /> <label class="radio-set__label" for="my-radio"></label> </div>

Style Customization

Apply accent-color to <input />'s style.

<style> .radio-set { --size: 1.25em; --border-radius: var(--size); --duration: 100ms; --timing-function: cubic-bezier(.4,0,.2,1); /* normal */ --accent-color: var(--default-accent-color, rgba(42 108 246)); --border-color: var(--default-border-color, rgba(131 138 146)); --background-color: var(--default-background-color, rgba(255 255 255)); --dot-color: var(--default-dot-color, var(--accent-color)); /* disabled */ --border-color--disabled: var(--default-border-color--disabled, rgba(178 185 192)); --background-color--disabled: var(--default-background-color--disabled, rgba(255 255 255)); --dot-color--disabled: var(--default-dot-color--disabled, rgba(178 185 192)); } .radio-set__label { --dot-scale-normal: .001; --dot-scale-active: 1; --dot-scale: var(--dot-scale-normal); } .radio-set input:checked~.radio-set__label { --border-color: var(--accent-color); --dot-scale: var(--dot-scale-active); } .radio-set input:not(:disabled):focus-visible~.radio-set__label { --border-color: var(--accent-color); } .radio-set input:disabled~.radio-set__label { --border-color: var(--border-color--disabled); --background-color: var(--background-color--disabled); --dot-color: var(--dot-color--disabled); } .radio-set{position:relative;inline-size:var(--border-radius);aspect-ratio:1/1;overflow:hidden;} .radio-set input{position:absolute;top:-100%;outline:0 none;} .radio-set__label{position:relative;inline-size:100%;block-size:100%;background-color:var(--background-color);display:block;border-radius:var(--border-radius);overflow:hidden;} .radio-set__label::before{position:absolute;inset-inline-start:0;inset-block-start:0;content:'';inline-size:100%;block-size:100%;border-radius:var(--size);box-shadow:inset 0 0 0 2px var(--border-color);box-sizing:border-box;transition:box-shadow var(--duration) var(--timing-function);will-change:box-shadow;} .radio-set__label::after{position:absolute;inset-inline:0;inset-block:0;content:'';inline-size:8px;block-size:8px;margin:auto;border-radius:8px;background-color:var(--dot-color);transition:transform var(--duration) var(--timing-function);will-change:transform;transform:scale(var(--dot-scale));} @media (hover: hover) { .radio-set input:not(:disabled)~.radio-set__label:hover { --border-color: var(--accent-color); } } @media (prefers-color-scheme: dark) { .radio-set { --default-accent-color: rgba(75 168 248); --default-border-color: rgba(131 138 146); --default-background-color: rgba(0 0 0); --default-border-color--disabled: rgba(131 138 146); --default-background-color--disabled: rgba(44 54 63); } } </style>