Skip to content

Radio

Default browser radios are replaced with a custom styled radio component with help of .radio, a series of classes that improves the look and feel of the radio.

Structurally .radio element contains the following elements:

  • .radio__control - container for the radio itself and corresponding label
  • .radio__content - optional container for label and additional description
HTML
<div class="control">
    <div class="radio">
        <div class="radio__control">
            <input
                class="radio__input"
                type="radio"
                id="first-question"
                name="question">

            <label
                class="radio__label"
                for="question"></label>
        </div>

        <div class="radio__content">
            <label
                class="label"
                for="first-question">Default radio</label>
        </div>
    </div>
</div>

<div class="control">
    <div class="radio">
        <div class="radio__control">
            <input
                class="radio__input"
                type="radio"
                id="second-question"
                checked
                name="question">

            <label
                class="radio__label"
                for="question"></label>
        </div>

        <div class="radio__content">
            <label
                class="label"
                for="second-question">Checked radio</label>
        </div>
    </div>
</div>

Radio without label

HTML
<div class="control">
    <div class="radio">
        <div class="radio__control">
            <input
                class="radio__input"
                type="radio"
                id="label-less"
                name="label-less">

            <label
                class="radio__label"
                for="label-less"></label>
        </div>
    </div>
</div>

Checked radio

HTML
<div class="control">
    <div class="radio">
        <div class="radio__control">
            <input
                class="radio__input"
                type="radio"
                id="checked-radio"
                checked
                name="checked-radio">

            <label
                class="radio__label"
                for="checked-radio"></label>
        </div>

        <div class="radio__content">
            <label
                class="label"
                for="checked-radio">Checked radio</label>
        </div>
    </div>
</div>

Disabled radio

HTML
<div class="control">
    <div class="radio radio_disabled">
        <div class="radio__control">
            <input
                class="radio__input"
                type="radio"
                id="disabled-radio"
                disabled
                name="disabled-radio">

            <label
                class="radio__label"
                for="disabled-radio"></label>
        </div>

        <div class="radio__content">
            <label
                class="label"
                for="disabled-radio">Disabled radio</label>
        </div>
    </div>
</div>

Disabled checked radio

HTML
<div class="control">
    <div class="radio radio_disabled">
        <div class="radio__control">
            <input
                class="radio__input"
                type="radio"
                id="disabled-checked-radio"
                disabled
                checked
                name="disabled-checked-radio">

            <label
                class="radio__label"
                for="disabled-checked-radio"></label>
        </div>

        <div class="radio__content">
            <label
                class="label"
                for="disabled-checked-radio">Disabled checked radio</label>
        </div>
    </div>
</div>

Radio with additional description

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
HTML
<div class="control">
    <div class="radio">
        <div class="radio__control">
            <input
                class="radio__input"
                type="radio"
                id="radio-with-description"
                name="radio-with-description">

            <label
                class="radio__label"
                for="radio-with-description"></label>
        </div>

        <div class="radio__content">
            <label
                class="label"
                for="radio-with-description">With additional description</label>

            <div class="radio__description">
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
            </div>
        </div>
    </div>
</div>

Radio without additional description

HTML
<div class="control">
    <div class="radio">
        <div class="radio__control">
            <input
                class="radio__input"
                type="radio"
                id="radio-without-description"
                name="radio-without-description">

            <label
                class="radio__label"
                for="radio-without-description"></label>
        </div>

        <div class="radio__content">
            <label
                class="label"
                for="radio-without-description">Without additional description</label>
        </div>
    </div>
</div>

Radio with errors

  • Error 1
  • Error 1
  • Error 1
HTML
<div class="control">
    <div class="radio radio_error">
        <div class="radio__control">
            <input
                class="radio__input"
                type="radio"
                id="radio-with-error"
                name="radio-with-error">

            <label
                class="radio__label"
                for="radio-with-error"></label>
        </div>

        <div class="radio__content">
            <label
                class="label"
                for="radio-with-error"></label>
        </div>

        <div class="control__errors">
            <ul>
                <li>Error 1</li>
                <li>Error 1</li>
                <li>Error 1</li>
            </ul>
        </div>
    </div>
</div>

LESS

You can modify any radio less variable in your User Less section to change radio styles.

Radio variables

Variables used to style radio.

@radioSize: 20;
@radioGutter: @globalSpacing * 0.75;

@radioColorDescription: @controlAdditionalTextContentColor;
@radioColor: @controlColor;
@radioBgColor: @controlBgcolor;
@radioBorderColor: @controlBorderColor;
@radioBorderWidth: 1px;

@radioActiveBoxShadow: 0px 2px 4px -2px rgba(17, 19, 22, 0.08), 0px 4px 6px -1px rgba(17, 19, 22, 0.08);

@radioLabelBorder: @radioBorderWidth solid @radioBorderColor;

@radioDisabledBgColor: @controlDisabledBgColor;
@radioDisabledBorder: @radioBorderWidth solid @controlDisabledBgColor;

@radioCheckedBorderColor: @controlColor;
@radioActiveBorderWidth: 2;

@radioBorderRadius: 50%;

@radioDotSize: 10;

@radioErrorColor: @controlErrorColor;

If you want to change radio styles, you can just change the variables. To change default border-radius just modify @radioBorderRadius variable.

@radioBorderRadius: 10px;

Radio styles

Standard radio styles.

.radio {
    display: flex;
    column-gap: @radioGutter;

    &__control {
        position: relative;
        display: inline-flex;
        flex: 0 0 auto;

        .pixel-to-rem(width, @radioSize);
        .pixel-to-rem(height, @radioSize);

        border-radius: @radioBorderRadius;
        transition: box-shadow 0.15s ease-in;

        user-select: none;

        &:active,
        &:focus {
            box-shadow: @radioActiveBoxShadow;
        }
    }

    &__description {
        color: @radioColorDescription;
        .size-s();
    }

    &__input {
        position: absolute;
        width: 100%;
        height: 100%;

        user-select: none;
        clip: rect(1px, 1px, 1px, 1px);

        &:checked {
            + .radio__label {
                .pixel-to-rem(border-width, @radioActiveBorderWidth);
                border-color: @radioCheckedBorderColor;

                &::after {
                    display: inline-block;
                }
            }
        }

        &:active,
        &:focus {
            &:not(:disabled) {
                + .radio__label {
                    .pixel-to-rem(border-width, @radioActiveBorderWidth);
                    border-color: @radioCheckedBorderColor;
                }
            }
        }
    }

    &__label {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;
        height: 100%;

        transition: background-color 0.2s ease-in, box-shadow 0.15s ease-in, border-color 0.15s ease-in;

        border: @radioLabelBorder;
        border-radius: @radioBorderRadius;
        cursor: pointer;

        &:hover:not(:disabled) {
            box-shadow: @checkboxHoverBoxShadow;
            border-color: @checkboxHoverBorderColor;
        }

        &::after {
            content: '';

            display: none;

            .pixel-to-rem(width, @radioDotSize);
            .pixel-to-rem(height, @radioDotSize);

            background: @radioColor;

            border-radius: @radioBorderRadius;
        }
    }

    &_disabled {
        .radio__input {
            background-color: @radioDisabledBgColor;

            &:not(:disabled) {
                background-color: transparent;

                & + .radio__label {
                    background-color: transparent;
                    border: @radioDisabledBorder;
                }
            }

            &:hover {
                box-shadow: none;
            }

            &:not(:checked) {
                width: 100%;
                height: 100%;
            }

            &:checked + .radio__label {
                border-color: @radioDisabledBgColor;

                &:after {
                    background-color: @radioDisabledBgColor;
                }
            }
        }

        .radio__label {
            background-color: @radioDisabledBgColor;
            border: none;

            &:hover {
                box-shadow: none;
            }
        }

        label[for] {
            cursor: default;
        }
    }

    &_error {
        .radio__content {
            color: @radioErrorColor;
        }
    }
}