SASS component for enabling larger, custom radio buttons. Unfortunately it doesn't work in Firefox (but does fall back to native radios). Completely customizable with SASS variables
A Pen by Gavin Elster on CodePen.
h1 SCSS Radio Buttons | |
p Overrides the browser’s native presentation of a radio button <em>without relying on the radio's label element.</em> | |
p Every effort should be made to avoid overriding its native <em>behavior</em> however; accessibility and native states should be unaltered. | |
p | |
strong Play around with the variables at the top of the SCSS to customize. | |
label | |
input> [type='radio' name='q1' checked] | |
| Checked | |
label | |
input> [type='radio' name='q1'] | |
| Unchecked | |
label | |
input> [type='radio' name='q1' disabled] | |
| Disabled | |
h4 Multiple | |
input> [type='radio' name='q2'] | |
input> [type='radio' name='q2'] | |
input> [type='radio' name='q2'] | |
input> [type='radio' name='q2'] | |
input> [type='radio' name='q2' checked] | |
input> [type='radio' name='q2'] | |
input> [type='radio' name='q2'] | |
input> [type='radio' name='q2'] | |
input> [type='radio' name='q2'] |
$color-light-blue: dodgerblue; | |
// Gray Scale | |
$color-gray: lighten(black, 50% ) !default; | |
$color-light-gray: lighten(black, 80% ) !default; | |
$color-lighter-gray: lighten(black, 91.8%) !default; | |
$custom-radio-size: 32px; | |
$custom-radio-transition-speed: 100ms; | |
$custom-radio-inset-shadow: inset 0 .1em 1px -.1em rgba(0,0,0,.3); | |
$custom-radio-pip-color: $color-light-blue; | |
$custom-radio-pip-size: round($custom-radio-size * .4); | |
$custom-radio-unchecked-bg: white; | |
$custom-radio-unchecked-border: transparentize($color-gray, .6); | |
$custom-radio-checked-bg: mix($custom-radio-unchecked-bg, $custom-radio-pip-color, 60%); | |
$custom-radio-checked-border: $color-light-blue; | |
$custom-radio-active-inset-shadow: inset 0 0 2px 3px rgba(0,0,0,.1); | |
$custom-radio-focus-shadow: 0 0 0 2px transparentize($color-light-blue, .5); | |
$custom-radio-disabled-bg: $color-lighter-gray; | |
$custom-radio-disabled-pip-color: $color-light-gray; | |
// Override the browser's native presentation of a radio button. Every effort should be made to | |
// avoid overriding its native *behavior* however; keyboard access, accessibility, and native states | |
// should be unaltered. | |
@if ($custom-radio-size % 2 == 1) { @error '$custom-radio-size must be even'; } | |
// round to nearest even number | |
@if ($custom-radio-pip-size % 2 == 1) { $custom-radio-pip-size: $custom-radio-pip-size - 1; } | |
input[type="radio"] { | |
$border-width: 1px; | |
position: relative; | |
display: inline-block; | |
width: $custom-radio-size - 2; | |
height: $custom-radio-size - 2; | |
border-radius: 100%; | |
outline: none !important; | |
// Radio | |
// ----- | |
&::before { | |
position: relative; | |
top: -$border-width; | |
left: -$border-width; | |
display: block; | |
content: ''; | |
background: $custom-radio-unchecked-bg; | |
border: $border-width solid $custom-radio-unchecked-border; | |
border-radius: 100%; | |
box-shadow: $custom-radio-inset-shadow; | |
width: $custom-radio-size; | |
height: $custom-radio-size; | |
} | |
&:active::before { | |
box-shadow: $custom-radio-inset-shadow, | |
$custom-radio-active-inset-shadow; | |
} | |
&:focus::before { | |
box-shadow: $custom-radio-inset-shadow, | |
$custom-radio-focus-shadow; | |
} | |
&:checked::before { | |
background: $custom-radio-checked-bg; | |
border-color: $custom-radio-checked-border; | |
} | |
&:disabled::before { | |
cursor: not-allowed; | |
background-color: $custom-radio-disabled-bg; | |
border-color: transparentize($custom-radio-unchecked-border, .2); | |
} | |
// Radio Pip | |
// --- | |
&::after { | |
position: relative; | |
top: -($custom-radio-size / 2) - $border-width; | |
left: ($custom-radio-size / 2) - $border-width; | |
display: block; | |
content: ''; | |
background: $custom-radio-pip-color; | |
border-radius: 100%; | |
box-shadow: 0 1px 1px rgba(0,0,0,.1); | |
width: 0; | |
height: 0; | |
} | |
&:checked::after { | |
transition: all ease-in-out $custom-radio-transition-speed 0; | |
top: floor( | |
- ($custom-radio-size / 2) | |
- ($custom-radio-pip-size / 2) | |
- $border-width | |
); | |
left: floor( | |
+ ($custom-radio-size / 2) | |
- ($custom-radio-pip-size / 2) | |
- $border-width | |
+ 1 | |
); | |
width: $custom-radio-pip-size; | |
height: $custom-radio-pip-size; | |
} | |
&:disabled::after { | |
background: $custom-radio-disabled-pip-color; | |
} | |
} | |
// Demo CSS | |
body { | |
font-family: Avenir Next, Helvetica Neue, sans-serif; | |
padding: 2em; | |
} | |
label { | |
font-size: 2.5em; | |
display: block; | |
} | |
input + input { | |
margin-left: .5em; | |
} |