Daria Doronina Daria Doronina - 23 days ago 6
CSS Question

Radio buttons are checked simultaneously

I've been trying to replicate this page https://vk.com/ You can see that they've changed the standard appearance of radio buttons in the 2nd form.

I succeeded in changing the design of the buttons but now they are all checked simultaneously.

HTML

<form class="form2">
<div class="heading">
<h2>Poprvé na VK?</h2>
<p>Okamžitá registrace</p>
</div>
<input type="text" placeholder="Vaše jméno" required>
<input type="text" placeholder="Vaše příjmení" required class="last-name">
<label class="birth">
<span>Datum narození
<i class="fa fa-question-circle-o"
aria-hidden="true"></i></span>
<input type="date" class="date" required>
</label>
<label>
<span class="gender-head">Pohlaví</span>
<div class="gender">
<input type="radio" id="1-option" name="selector" value="female" class="control">
<div class="button"></div>Žena
<input type="radio" id="2-option" name="selector" value="male" class="control">
<div class="button"></div>Muž
<input type="radio" id="3-option" value="other" name="selector" class="control">
<div class="button"></div>Jiné
</div>
</label>
<button type="submit">Zaregistrovat se</button>
<a href="#">
<i class="fa fa-facebook-square" aria-hidden="true"></i> Přihlásit se přes Facebook</a>
</form>


CSS

form {
width: 290px;
background-color: #fff;
padding: 20px 15px;
float: right;
border: 1px solid #E0E1E3;
font-size: 13px;
border-radius: 3px;
}

.form2 {
margin-right: 10px;
clear: right;
height: 380px;
display: flex;
flex-flow: row wrap;
color: #333436;
justify-content: center;
}

.form2 .heading {
flex-wrap: wrap;
margin: 0 auto;
}

.form2 h2 {
margin-top: 0px;
margin-bottom: 0px;
font-size: 20px;
font-weight: 100;
}

.form2 p {
font-size: 12px;
margin: 2px 0 0 9px;
}

.form2 input {
height: 30px;
border-radius: 3px;
border: 1px solid #DBDCDE;
width: 270px;
margin-top: -15px;
margin-bottom: 0;
}

.form2 .last-name {
margin-top: -15px;
}

.form2 span {
font-weight: 600;
margin-top: -50px;
color: #7A7B7D;
font-size: 13px;
}

.form2 .birth {
margin: -15px 0 0 10px;
}

.form2 .date {
margin-top: 10px;
margin-bottom: -100px;
}

.form2 .gender-head {
margin-left: -10px;
margin-bottom: 20px;
}

.gender {
display: flex;
width: 260px;
margin: 15px 0 0px -10px;
justify-content: space-between;
font-size: 13px;
color: #000;
}

.gender input[type="radio"] {
position: absolute;
top: -9999px;
left: -9999px;
}

.gender .button {
border: 1px solid #A3A4A6;
background: #fff;
border-radius: 50%;
height: 12px;
width: 12px;
margin-top: 2px;
margin-right: -40px;
}

.gender .button:hover {
cursor: pointer;
background-color: #EAEBED;
}

.gender .button::before {
display: block;
content: '';
height: 6px;
width: 6px;
border-radius: 50%;
}

input[type="radio"]:checked ~ .button {
border: 1px solid #5A7CA3;
}

input[type="radio"]:checked ~ .button::before {
background: #5A7CA3;
margin: 3px 2px 2px 3px;
}

::-webkit-input-placeholder {
color: #7A7B7D;
padding-left: 12px;
}

.form2 button {
height: 20px;
}


http://jsfiddle.net/Skidle/u3zj66sd/

I haven't learned JavaScript yet so I'd prefer CSS & HTML only solution. Thanks!

Answer

If you look at the radio buttons, by removing the position, you can see that only one is selected, and it is correct for each selection:

preview

The problem lies in the way the presentation works. The CSS code:

input[type="radio"]:checked ~ .button::before   // Is wrong.
input[type="radio"]:checked + .button::before   // Is right.

Explanation

The code given for the CSS, ~ selector is a sibling selector, which selects all the selectors.

While, what you need is the + selector, which is the immediate or adjacent sibling selector. This selects only one.

Change needs to be done here:

input[type="radio"]:checked + .button::before {
  background: #5A7CA3;
  margin: 3px 2px 2px 3px;
}

Fiddle: http://jsfiddle.net/0rqu3s2c/

Note: There's an issue when you try to click on the other inputs. So, you might need to check what's blocking it. Please do not use absolute positioning without the desired result.

Comments