1

I have various form elements on my page, but am having an issue with input radio buttons in Firefox. The radio buttons display perfectly in Safari and Chrome, but are entirely different in Firefox (circular instead of square!) and are :checked by default, which is also an issue.

From my research, the use of -moz-appearance is widely recommended, but in this instance I can't find any answers that directly relate to my query. Any help would be greatly appreciated.

Markup

<form>
    <label class="radio" for="#">One</label>
    <input type="radio">
    <label class="radio" for="#">Two</label>
    <input type="radio">
</form>

CSS

input[type="radio"] {
    -webkit-appearance: none; /* Remove default appearance styling for Webkit */
    -moz-appearance: none; /* Remove default appearance styling for Firefox */
    background: #ccc;
    width: 45px;
    height: 45px;
    vertical-align: middle;
    margin: 0 10px;
    cursor: pointer;
}

input[type="radio"]:hover { background: #e4e4e4; }

input[type="radio"]:checked {
    background: #000;
    position: relative;
    width: 45px;
    height: 45px;
}

input[type="radio"]:checked:after {
    content: '';
    position: absolute;
    width: 20px;
    height: 8px;
    background: transparent;
    top: 15px;
    left: 10px;
    border: 1px solid #fff;
    border-top: none;
    border-right: none;
    -webkit-transform: rotate(-45deg);
    -moz-transform: rotate(-45deg);
    -o-transform: rotate(-45deg);
    -ms-transform: rotate(-45deg);
    transform: rotate(-45deg);
}

JSFiddle

Please view the above fiddle in Firefox and Chrome to see the issues I am referring to. Thanks.

dungey_140
  • 2,602
  • 7
  • 34
  • 68

2 Answers2

5

I wouldn't advise styling radio buttons to look like checkboxes but since you ask might I suggest that you approach it a different way...

Position the label after the input, hide the input (we'll use just the label to toggle it), then use the Adjacent Sibling Selector to style the label adjacent to the :checked input:

Like this:

input[type="radio"] {
    /* hide the real radio button - but not with display:none as it causes x-browser problems */
    opacity:0.2;
    position:absolute;
    /*left:-10000;*/
}
input[type="radio"] + label {
    cursor: pointer;
}
/* N.B You could use a child span in the label if you didn't want to use the :after pseudo */
input[type="radio"] + label:after {
    display:inline-block;
    content:"✓";
    font-size:30px;
    line-height:45px;
    text-align:center;
    color:#ccc;
    background: #ccc;
    width: 45px;
    height: 45px;
    vertical-align: middle;
    margin: 0 10px;
    border-radius:50%;  
    border:1px solid grey;
}
input[type="radio"] + label:hover:after {
    background: #aaa;    
}
input[type="radio"]:checked + label:after {
    color:#fff;
    background: #555; 
    box-shadow:0 0 8px deepSkyBlue;
    border-color:white;
}
<form>        
    <input id="a" name="myradio" type="radio" />
    <label for="a">One</label>
    <input id="b" name="myradio" type="radio" />
    <label for="b">Two</label>
</form>
Moob
  • 14,420
  • 1
  • 34
  • 47
  • Hi Moob, thanks for your help. Does this not become a non-functioning form with this approach as the input is not actually being :checked? – dungey_140 May 07 '15 at 14:16
  • @dungey_140 - it's fully functioning. Labels are linked to their input element via the `for` attribute. Clicking the label toggles the input. I've updated the example to faintly show the real input elements so you can see them getting toggled. – Moob May 07 '15 at 15:40
  • Hello again @Moob, just a quick note to say thank you for your help on this, I managed to slightly tweak the above to work perfectly! – dungey_140 May 11 '15 at 21:31
  • Is this accessible? Assistive technology users trying to activate a radio button would depend on clicking the radio button itself. – Michel Hébert Nov 03 '16 at 17:30
  • Thanks to spammers and con-artists this no longer works. To fight form and permission fraud, any input element styled: display-none, off-the-page, not-visible, or other; is not considered for input, and its value not included in the form submission. (to stop websites from hiding inputs, checked on by default such as "You agree to a 3rd party, recurring, subscription charge" and fraudulently getting them to agree to unwanted services and other things) – ppostma1 Jul 26 '17 at 16:05
0

You may want to check out this simple library I'm developing for just this purpose. The underlying elements are hidden and more easily stylable elements take their place.

Stylized Checkbox

The basic usage is very simple - just call stylizedRadioButtons('myradio');.

General_Twyckenham
  • 2,161
  • 2
  • 21
  • 36