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; | |
| } |