CSS3 custom radio buttons - css

the following works perfectly however I would like once the radio button is checked that it doesn't fill the all pink but less so that it looks like a normal radio button. Ideally it would have a nice grey circle equally centered.
.radio-toolbar input[type="radio"] {
display:none;
}
.radio-toolbar label {
display:inline-block;
background-color:#faa;
font-family:Arial;
font-size:16px;
padding:5px;
width:20px;
height:20px;
border-radius:50%;
}
.radio-toolbar input[type="radio"]:checked + label {
background-color:#333;
}
<div class="radio-toolbar">
<input type="radio" id="radio1" name="radios" value="all" checked>
<label for="radio1"></label>
<input type="radio" id="radio2" name="radios"value="false">
<label for="radio2"></label>
<input type="radio" id="radio3" name="radios" value="true">
<label for="radio3"></label>
</div>

You can do it using pseudo :after selector . Just add CSS in your existing CSS like this
CSS :
.radio-toolbar label:after{
content :'';
}
.radio-toolbar input[type="radio"]:checked + label:after {
width: 18px;
height: 18px;
display: block;
margin: 1px;
border-radius: 9px;
background-color: #333;
}
Created Fiddle Fiddle

Related

Bootstrap Paper's material style of radio/checkbox inputs broken in IE/FF

According to Google's Material guidelines for selection controls (checkboxes, radio buttons, switches), these input fields should look like this:
The Bootstrap Paper Theme for v3.x (now called Materia in v4) is styled to hit this design target
In chrome, inputs are stylized correctly, but all other browsers merely fallback to native input controls, which disrupts the consistency of the design metaphor.
Here's an MCVE in jsFiddle / Stack Snippets that will work / fail depending on browser:
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/paper/bootstrap.min.css" rel="stylesheet"/>
<div class="checkbox">
<label><input type="checkbox" value="check1"/> Check Opt 1 </label>
</div>
<div class="checkbox">
<label><input type="checkbox" value="check2" checked/> Check Opt 2</label>
</div>
<div class="radio">
<label><input type="radio" value="radio1" name="grp1" />Radio Opt 1</label>
</div>
<div class="radio">
<label><input type="radio" value="radio2" name="grp1" checked/>Radio Opt 2</label>
</div>
And here how the previous code fares in each browser:
Is there a possible workaround for this or are we at the mercy of the browser to style inputs how they deem fit?
This question was also asked on the project's issues page in github issue #497, but closed citing browser incompatibility
The core problem faced by the implementation of the Paper Theme is it does so by styling the <input type="checkbox" /> elements using :before or :after pseudo-elements.
Per this the W3C specs and this answer in can I use a pseudo-element on an input field?
:before and :after render inside a container and <input>s can not contain elements
The fact that it works in chrome is the exception, not the rule, but we're not out of luck ...
Pure CSS Approach
So we'll want to avoid styling anything within the actual checkbox itself, but we can apply those same styles to the label instead, which will still toggle the checkbox that it describes.
Step 1 - Label Based Toggle
We do have to restructure the HTML so that checkbox comes before the label, instead of inside it. We'll do that so we can use the :checked and adjacent sibling selector + to conditionally style the label based on whether or not the checkbox is checked.
<!-- Old Format -->
<div class="checkbox">
<label>
<input type="checkbox" value="check1"/>
Check Label Text
</label>
</div>
<!-- New Format -->
<div class="label-check">
<input type="checkbox" value="check1" id="myCheck">
<label for="myCheck">Check Label Text</label>
</div>
Note: In order for this solution to work, you do need to make sure that you have valid HTML with unique IDs for every input and corresponding for attributes in the labels that describe them.
At this point in time, we can ditch the inputs, and style the labels with our own :before pseudo elements that look like checkboxes or radio buttons. To keep things simple for now, in step one, we can mimic the controls with the following Unicode Characters ... ☐, ☑, ⭘, ◉
Here's an bare bones version with the basic gist of the CSS to style each label conditionally:
input[type='checkbox'],[type='radio'] { display: none; }
[type='checkbox'] + label::before { content: "\2610";}
[type='checkbox']:checked + label::before { content: "\2611";}
[type='radio'] + label::before { content: "\2B58";}
[type='radio']:checked + label::before { content: "\25C9";}
We can also improve on this baseline quite a bit by adding some colorization, hovering effects, cursor properties, transition effects, and text shadows to make the unicode characters look and feel like actual buttons.
Here's a more fleshed out demo in jsFiddle and Stack Snippets:
body {
font-size:1.3em;
color: #2b2b2b;
background:white;
}
.label-check input { display:none; }
.label-check label::before {
width: 1.4em;
text-align: center;
display: inline-block;
cursor: pointer;
color: black;
transition: color .3s ease;
text-shadow: 0px 0px 1px #cccccc;
}
.label-check label:hover::before {
text-shadow: 0px 0px 1px #6286d0;
}
.label-check [type='checkbox']:checked + label::before,
.label-check [type='radio']:checked + label::before{
color: #056dce;
}
.label-check [type='checkbox'] + label::before { content: "\2610";}
.label-check [type='checkbox']:checked + label::before { content: "\2611";}
.label-check [type='radio'] + label::before { content: "\2B58";}
.label-check [type='radio']:checked + label::before { content: "\25C9";}
<h3>
Inputs... we don't need no stinkin Inputs
</h3>
<div class="label-check">
<div>
<input type="checkbox" name="checkGrp1" id="check1_Opt1">
<label for="check1_Opt1">A Label Here 1</label>
</div>
<div>
<input type="checkbox" name="checkGrp1" id="check1_Opt2" checked>
<label for="check1_Opt2">A Label Here 2</label>
</div>
</div>
<div class="label-check">
<div>
<input type="radio" name="radioGrp1" id="radio1_Opt1">
<label for="radio1_Opt1">Radio Label 1</label>
</div>
<div>
<input type="radio" name="radioGrp1" id="radio1_Opt2" checked>
<label for="radio1_Opt2">Radio Label 2</label>
</div>
</div>
Step 2 - Apply Material Style to label:before with CSS
With the concept of using a the label's stylized pseudo elements as a toggle in play, we can apply Paper's styles / CSS instead of just { content: "\2610";} to give our checkboxes a Material look and feel.
To do that, let's look at how the styles were supposed to work. We can look at the source code that describes checks and radios on Github in bootstrap.css#L7182
The :after element is being used to style the surrounding box/circle while the :before element adds the inner selection when the box is :checked.
Here are the high level styles for the checkbox:
Note: The check mark is made by rotating a rectangle 45 degrees and adding a white border to the bottom and right.
And here's a high level view of the styles for the radio button:
Note: The radio button container and inside is just a regular CSS circle (border-radius:50%) with varying sizes which can animate by scaling up or down.
So we'll migrate any pseudo elements found on the checkbox input to it's adjacent label like this:
/* old */ input[type="radio"]:before
/* new */ input[type="radio"] + label:before
After some careful conversion, here's a demo in jsFiddle and Stack Snippets:
body {
padding: 0 25px;
font-size: 1.2em;
}
.checkbox, .radio {
margin: 10px;
}
.checkbox, .radio {
position: relative;
}
.label-check label {
padding-left: 20px;
}
.label-check input[type="radio"],
.label-check input[type="checkbox"] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
opacity: 0;
position: absolute;
margin: 0;
z-index: -1;
width: 0;
height: 0;
overflow: hidden;
left: 0;
pointer-events: none;
}
.label-check input[type="radio"]:focus {
outline: none;
}
.label-check input[type="radio"] + label:before,
.label-check input[type="radio"] + label:after {
content: "";
display: block;
position: absolute;
left: -10px;
top: 1px;
width: 18px;
height: 18px;
border-radius: 50%;
-webkit-transition: 240ms;
-o-transition: 240ms;
transition: 240ms;
}
.label-check input[type="radio"] + label:before {
left: -8px;
top: 3px;
}
.label-check input[type="radio"] + label:before {
background-color: #2196f3;
-webkit-transform: scale(0);
-ms-transform: scale(0);
-o-transform: scale(0);
transform: scale(0);
}
.label-check input[type="radio"] + label:after{
top: 1px;
border: 2px solid #666666;
z-index:1;
}
.label-check input[type="radio"]:checked + label:before {
-webkit-transform: scale(0.6);
-ms-transform: scale(0.6);
-o-transform: scale(0.6);
transform: scale(0.6);
}
.label-check input[type="radio"]:disabled:checked + label:before {
background-color: #bbbbbb;
}
.label-check input[type="radio"]:checked + label:after {
border-color: #2196f3;
}
.label-check input[type="radio"]:disabled + label:after,
.label-check input[type="radio"]:disabled:checked + label:after {
border-color: #bbbbbb;
}
.label-check input[type="checkbox"]:focus {
outline: none;
}
.label-check input[type="checkbox"]:focus + label:after{
border-color: #2196f3;
}
.label-check input[type="checkbox"] + label:after {
content: "";
position: absolute;
top: 2px;
left: -10px;
display: block;
width: 18px;
height: 18px;
margin-top: -2px;
margin-right: 5px;
border: 2px solid #666666;
border-radius: 2px;
-webkit-transition: 240ms;
-o-transition: 240ms;
transition: 240ms;
}
.label-check input[type="checkbox"]:checked + label:before {
content: "";
position: absolute;
top: 2px;
left: -3px;
display: table;
width: 6px;
height: 12px;
border: 2px solid #fff;
border-top-width: 0;
border-left-width: 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
z-index:1;
}
.label-check input[type="checkbox"]:checked + label:after{
background-color: #2196f3;
border-color: #2196f3;
}
.label-check input[type="checkbox"]:disabled + label:after {
border-color: #bbbbbb;
}
.label-check input[type="checkbox"]:disabled:checked + label:after {
background-color: #bbbbbb;
border-color: transparent;
}
<h3>
Material Label Based Checks
</h3>
<div class="label-check">
<div class="checkbox">
<input type="checkbox" name="checkGrp1" id="check1_Opt1">
<label for="check1_Opt1">A Label Here 1</label>
</div>
<div class="checkbox">
<input type="checkbox" name="checkGrp1" id="check1_Opt2" checked>
<label for="check1_Opt2">A Label Here 2</label>
</div>
</div>
<div class="label-check">
<div class="radio">
<input type="radio" name="radioGrp1" id="radio1_Opt1">
<label for="radio1_Opt1">Radio Label 1</label>
</div>
<div class="radio">
<input type="radio" name="radioGrp1" id="radio1_Opt2" checked>
<label for="radio1_Opt2">Radio Label 2</label>
</div>
</div>
HTML/JS Approach
There are some other material implementations that have hit this target in a cross browser friendly way. All of which typically rely on:
Hiding the actual <input> element
Placing a stylized checkbox box inside of the label
In some cases, this relies on formatting the HTML appropriately yourself at design time, or generating it when the site initializes.
For example, FezVrasta's Material Design for Bootstrap, in both V3 and V4 will take an HTML structure like this:
<div class="checkbox">
<label>
<input type="checkbox">
Notifications
</label>
</div>
And insert a new span when you call $.material.init() so the result looks like this:
<div class="checkbox">
<label>
<input type="checkbox">
<span class="checkbox-material">
<span class="check"></span>
</span>
Notifications
</label>
</div>
While this relies on the initialization to occur, it allows much more fine grained control of the CSS checkbox and radio button rather than shoving it all into pseudo elements.
Bootstrap 4 does come with a set of custom radios and checkboxes. Which means: They can be adjusted to style in any way you want.
Here's an example of a custom checkbox that comes with Bootstrap 4 by default and is designed to look identical in all browsers:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck1">
<label class="custom-control-label" for="customCheck1">Check this custom checkbox</label>
</div>
And here's an example of a custom radio (check the last snippet in that answer): https://stackoverflow.com/a/48401949/8270343
(note: only colors were adjusted in that case but the shapes and/or animations can be adjusted just as well)
Reference link:
https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios-1
The v4 version seems to be working fine in Firefox:
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/4.0.0-beta.3/materia/bootstrap.min.css" rel="stylesheet"/>
<div class="checkbox">
<label><input type="checkbox" value="check1"/> Check Opt 1 </label>
</div>
<div class="checkbox">
<label><input type="checkbox" value="check2" checked/> Check Opt 2</label>
</div>
<div class="radio">
<label><input type="radio" value="radio1" name="grp1" />Radio Opt 1</label>
</div>
<div class="radio">
<label><input type="radio" value="radio2" name="grp1" checked/>Radio Opt 2</label>
</div>

CSS change when specific radio button is checked using :checked pseudo class

The code below will allow me to alter the css of any sibling div element when the checkbox is checked:-
input[type="radio"]:checked ~ div{
display:none;
}
What i need to do is target a specific div either by its Id or its class when a specific radio button in the list is checked.
I want to try and to this Purely in CSS.
Ive tried doing this :-
input[type="radio"]:checked ~ #one.div{
display:none;
}
https://codepen.io/dyk3r5/pen/WOmxpV?editors=1111
<div class="container">
<input type="radio" id="opt1" name="radiolist" checked>
<label for='opt1'>New Account</label>
<input type="radio" id="opt2" name="radiolist">
<label for='opt2'>Existing Account</label>
<div id="one">Lorem Ipsum 1</div>
<div id="two">Lorem Ipsum 2</div>
</div>
html, body{
height :100%;
}
.container{
display:flex;
justify-content:center;
}
label{
color:#000;
font-weight:600;
height: 25px;
padding: 5px 10px;
border-bottom: 2px solid lightgrey;
margin: 5px 1px;
}
input[type="radio"]{
display:none;
}
input[type="radio"]:checked + label{
border-bottom: 2px solid red;
}
input[type="radio"]:checked ~ div{
display:none;
}
I updated the css to display the corresponding div when a certain radio button is selected. The problem is your selector for the div: #one.div. This targets the element with id "one" and class "div". It should be div#one instead.
html,
body {
height: 100%;
}
.container {
display: flex;
justify-content: center;
}
label {
color: #000;
font-weight: 600;
height: 25px;
padding: 5px 10px;
border-bottom: 2px solid lightgrey;
margin: 5px 1px;
}
input[type="radio"] {
display: none;
}
input[type="radio"]:checked+label {
border-bottom: 2px solid red;
}
input[type="radio"]~div {
display: none;
}
input[type="radio"][id="opt1"]:checked~div#one,
input[type="radio"][id="opt2"]:checked~div#two {
display: block;
}
<div class="container">
<input type="radio" id="opt1" name="radiolist" checked>
<label for='opt1'>New Account</label>
<input type="radio" id="opt2" name="radiolist">
<label for='opt2'>Existing Account</label>
<div id="one">Lorem Ipsum 1</div>
<div id="two">Lorem Ipsum 2</div>
</div>

What css style can I use to change location of my radio buttons

How can I lower the radio buttons to be same height as Male and Female? I tried width or height both did not work I even tried padding and it didn't work.
Try this:
input[type="radio"] {
margin-top: -1px;
vertical-align: middle;
}
Your parent div by the way need to has height set.
This minimal example works for me out of the box:
<form>
<span>Gender</span>
<fieldset style="display:inline; border:0;">
<label><input type="radio"/> Female</label>
<label><input type="radio"/> Male</label>
</fieldset>
</form>
Try this css :
.maxl{
margin:25px ;
}
.inline{
display: inline-block;
}
.inline + .inline{
margin-left:10px;
}
.radio{
color:#999;
font-size:15px;
position:relative;
}
.radio span{
position:relative;
padding-left:20px;
}
.radio span:after{
content:'';
width:15px;
height:15px;
border:3px solid;
position:absolute;
left:0;
top:1px;
border-radius:100%;
-ms-border-radius:100%;
-moz-border-radius:100%;
-webkit-border-radius:100%;
box-sizing:border-box;
-ms-box-sizing:border-box;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
}
.radio input[type="radio"]{
cursor: pointer;
position:absolute;
width:100%;
height:100%;
z-index: 1;
opacity: 0;
filter: alpha(opacity=0);
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"
}
.radio input[type="radio"]:checked + span{
color:#0B8;
}
.radio input[type="radio"]:checked + span:before{
content:'';
width:5px;
height:5px;
position:absolute;
background:#0B8;
left:5px;
top:6px;
border-radius:100%;
-ms-border-radius:100%;
-moz-border-radius:100%;
-webkit-border-radius:100%;
}
<div class="maxl">
<label class="radio inline">
<input type="radio" name="sex" value="male" checked>
<span> Male </span>
</label>
<label class="radio inline">
<input type="radio" name="sex" value="female">
<span>Female </span>
</label>
</div>
input{
vertical-align:bottom;
}
<form>
<span>Gender</span>
<label><input type="radio" name="select_gender"/> Male</label>
<label><input type="radio" name="select_gender"/> Female</label>
</form>
Hope this helps.

Radio label background color when checked in Contact Form 7

I am having issues making the background color change when an option is clicked on an CF7 form with radio buttons. Basically, I need the background color to change when the option is ‘checked’. So when clicking on Option 1, it needs to stay red (for example) until Option 2 is clicked. I can’t seem to select the label to do this.
HTML
<span class="wpcf7-form-control-wrap ra-kies-onderdeel">
<span class="wpcf7-form-control wpcf7-radio">
<span class="wpcf7-list-item first">
<label>
<input type="radio" name="ra-kies-onderdeel" value="Roetfilter">
<span class="wpcf7-list-item-label">Option 1</span>
</label>
</span>
<span class="wpcf7-list-item last">
<label>
<input type="radio" name="ra-kies-onderdeel" value="Katalysator">
<span class="wpcf7-list-item-label">Option 2</span>
</label>
</span>
</span>
</span>
CSS
input[type="radio"] {
display: none;
}
label {
display: block;
width: 100%;
background-color: #ddd;
padding: 16px;
margin-bottom: 20px;
cursor:pointer;
font-family: Arial;
font-size: 16px;
}
http://codepen.io/anon/pen/XNYjQJ
Changing the HTML is not an option unfortunately, and I would rather not use jQuery for this.
Thanks!
I figured it out, solved it with the following CSS:
input[type="radio"] {
display: none;
}
.wpcf7-list-item-label {
display: block;
width: 100%;
background-color: #ddd;
padding: 16px;
margin-bottom: 20px;
cursor: pointer;
font-family: Arial;
font-size: 16px;
}
input[type=radio]:checked + .wpcf7-list-item-label {
background-color: red;
}
Image of radiobuttons with changed colors
This technique uses the label element bound to hidden input elements, that receiving a :checked state will change the appearance of the :before pseudo element:
CSS:
/* COMMON RADIO AND CHECKBOX STYLES */
input[type=radio],
input[type=checkbox]{
/* Hide original inputs */
visibility: hidden;
position: absolute;
}
input[type=radio] + label:before,
input[type=checkbox] + label:before{
height:12px;
width:12px;
margin-right: 2px;
content: " ";
display:inline-block;
vertical-align: baseline;
border:1px solid #777;
}
input[type=radio]:checked + label:before,
input[type=checkbox]:checked + label:before{
background:gold;
}
/* CUSTOM RADIO AND CHECKBOX STYLES */
input[type=radio] + label:before{
border-radius:50%;
}
input[type=checkbox] + label:before{
border-radius:2px;
}
Html:
<input type="radio" name="r" id="r1"><label for="r1">Radio 1</label>
<input type="radio" name="r" id="r2"><label for="r2">Radio 2</label>
<input type="checkbox" name="c1" id="c1"><label for="c1">Check 1</label>
<input type="checkbox" name="c2" id="c2"><label for="c2">check 2</label>
I hope this helps :)

CSS Sibling selector malfunctioning under Chrome

I'm making a vote system and here's my code. It works fine under Firefox, but it's not working properly under Chrome and I don't know what's the problem with it.
Under Firefox when you hover over each square the previous are selected.
Under Chrome to select the first one you need to point over the second square and so on.
One more thing, if you click over the fifth box despite its not colored the link is working.
http://jsfiddle.net/SV8Dh/
<div id="vote-stars">
<input type="radio" name="stars" id="5" class="but" value="5" />
<label for="5">5</label>
<input type="radio" name="stars" id="4" class="but" value="4" />
<label for="4">4</label>
<input type="radio" name="stars" id="3" class="but" value="3" />
<label for="3">3</label>
<input type="radio" name="stars" id="2" class="but" value="2" />
<label for="2">2</label>
<input type="radio" name="stars" id="1" class="but" value="1" />
<label for="1">1</label>
</div>
Some css:
input[type="radio"]{
display:none;
}
.but + label
{
width: 23px;
height: 23px;
background-color:gray;
display:inline-block;
padding: 0 0 0 0px;
float: left;
border:1px;
border-style: groove;
border-color: yellow;
}
.but:hover + label,
.but:hover ~ .but + label,
.but:hover ~ label {
width: 23px;
height: 23px;
background-color:green;
display:inline-block;
padding: 0 0 0 0px;
margin: 0px;
}
.but:checked + label,
.but:checked ~ .but + label,
.but:checked ~ label {
width: 23px;
height: 23px;
background-color:green;
display:inline-block;
padding: 0 0 0 0px;
margin: 0px;
border:2px;
border-style: groove;
border-color: green;
}
Cheers
Seems it is caused by changing the display type of the radio buttons to none and Chrome has no idea to trigger :hover for the hidden element.
As an alternative, you can use :hover pseudo-class for the labels instead.
label:hover,
label:hover ~ label {
width: 23px;
height: 23px;
background-color: green;
display: inline-block;
padding: 0;
margin: 0;
}
Working Demo.
Or you can simple change Radio Button to visibility:hidden;

Resources