There is a completely css and html only solution, if its just the display part that you are concerned about. You still use radio buttons, but modify their display to custom display.
Here is an example:
<input type="radio" name="delivery" id="standard" value="standard" class="delivery-option"/><label for="standard" class="delivery-label"> Standard </label>
<input type="radio" name="delivery" id="today" value="today" class="delivery-option"/><label for="today" class="delivery-label"> Today </label>
<input type="radio" name="delivery" id="overnight" value="overnight" class="delivery-option"/><label for="overnight" class="delivery-label"> Overnight </label>
CSS:
.delivery-label {
display: block;
padding-left: 30px;
position: relative;
}
.delivery-label:before {
position: absolute;
width: 15px;
height: 15px;
content: '';
border: 1px solid black;
left: 0;
}
.delivery-option:checked + .delivery-label:before {
content: 'x';
line-height: 15px;
text-align: center;
}
.delivery-option {
position: absolute;
margin-left: -1000px;
}
Please note that the important part here is that the labels have a 'for' attribute connecting it to 'id' of the corresponding input field. This is the right way to write semantically correct html.
When you do this, clicking on the label is same as clicking on the input field. Thats the trick to get this working.
Also not duplicating ids is necessary for this. Duplicate ids is semantically incorrect HTML and also would break such default html functions.
Here is the working jsfiddle:
https://jsfiddle.net/bacuxng7/1/