Reputation: 435
I am having a checkbox styled using pseudo element. It is working as expected using below html code . Image also added for reference. But when I add another input element just after the first input element, the checkbox circle disappears. The additional input element is added by webserver during runtime so it cannot be avoided. I am not sure how to fix it . Can someone please throw some light on it.
Working Code
<div class="fgt-sec">
<input type="checkbox" name="cc" id="c2" />
<label for="c2">
<span></span>
</label>
<small>Yes, I understand and agree to the Terms & Conditions.</small>
</div>
<div class="checky-sec">
<div class="fgt-sec">
<input type="checkbox" name="cc" id="c1">
<label for="c1">
<span></span>
</label>
<small>Remember me</small>
</div><!--fgt-sec end-->
<a href="#" title="">Forgot Password?</a>
</div>
Not Working HTML Code after adding additional html input element
<div class="fgt-sec">
<input type="checkbox" name="cc" id="c2" />
<input type="hidden" name="test" />
<label for="c2">
<span></span>
</label>
<small>Yes, I understand and agree to the Terms & Conditions.</small>
</div>
Circle Disappears
CSS Code
.fgt-sec {
float: left;
}
.fgt-sec input[type="checkbox"] {
display: none;
}
.fgt-sec label {
float: left;
}
.fgt-sec input[type="checkbox"] ~ label span {
display: inline-block;
width: 15px;
height: 15px;
position: relative;
border:1px solid #d2d2d2;
-webkit-border-radius: 100px;
-moz-border-radius: 100px;
-ms-border-radius: 100px;
-o-border-radius: 100px;
border-radius: 100px;
}
.fgt-sec input[type="checkbox"] ~ label span:before {
content: '';
width: 7px;
height: 7px;
-webkit-border-radius: 100px;
-moz-border-radius: 100px;
-ms-border-radius: 100px;
-o-border-radius: 100px;
border-radius: 100px;
font-size: 8px;
color: #ffffff;
opacity: 0;
visibility: hidden;
background-color: #e44d3a;
position: absolute;
font-family: fontawesome;
top: 50%;
left: 50%;
-webkit-transform: translateX(-50%) translateY(-50%);
-moz-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
-o-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
.fgt-sec input[type="checkbox"]:checked ~ label span:before {
opacity: 1;
visibility: visible;
}
.fgt-sec small {
float: left;
color: #000000;
font-size: 14px;
font-weight: 500;
margin-left: 10px;
}
.checky-sec > a {
float: right;
color: #000000;
font-size: 14px;
font-weight: 500;
}
/* ======= Radio Button Styles ======= */
.fgt-sec input[type="radio"] {
display: none;
}
.fgt-sec ~ label {
float: left;
}
.fgt-sec input[type="radio"] ~ label span {
display: inline-block;
width: 15px;
height: 15px;
position: relative;
border:1px solid #d2d2d2;
-webkit-border-radius: 100px;
-moz-border-radius: 100px;
-ms-border-radius: 100px;
-o-border-radius: 100px;
border-radius: 100px;
}
.fgt-sec input[type="radio"] ~ label span:before {
content: '';
width: 7px;
height: 7px;
-webkit-border-radius: 100px;
-moz-border-radius: 100px;
-ms-border-radius: 100px;
-o-border-radius: 100px;
border-radius: 100px;
font-size: 8px;
color: #ffffff;
opacity: 0;
visibility: hidden;
background-color: #e44d3a;
position: absolute;
font-family: fontawesome;
top: 49%;
left: 49%;
-webkit-transform: translateX(-50%) translateY(-50%);
-moz-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
-o-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
.fgt-sec input[type="radio"]:checked ~ label span:before {
opacity: 1;
visibility: visible;
}
Upvotes: 0
Views: 463
Reputation: 7447
Update
It seems that the updated code work at least in this codepen, so perhaps in the actual project there are some other styles that are overriding the correct ones.
Not sure what might be the cause, but as requested, here is how the pseudo element works in the posted code in a nut shell:
input
is hidden with the following code:.fgt-sec input[type="checkbox"] {
display: none;
}
span
inside a label
, with the following code. Because this label
has its for
set for said input
, clicking on it makes the input
checked or unchecked (as if clicking on input
). <label for="c2">
<span></span>
</label>
.fgt-sec input[type="checkbox"] ~ label span {
display: inline-block;
width: 15px;
height: 15px;
position: relative;
border: 1px solid #d2d2d2;
-webkit-border-radius: 100px;
-moz-border-radius: 100px;
-ms-border-radius: 100px;
-o-border-radius: 100px;
border-radius: 100px;
}
::before
pseudo element (the posted code uses a shorthand :before
) for the said span
, it starts as invisible, as defined by the following code:.fgt-sec input[type="checkbox"] ~ label span:before {
content: "";
width: 7px;
height: 7px;
-webkit-border-radius: 100px;
-moz-border-radius: 100px;
-ms-border-radius: 100px;
-o-border-radius: 100px;
border-radius: 100px;
font-size: 8px;
color: #ffffff;
opacity: 0;
visibility: hidden;
background-color: #e44d3a;
position: absolute;
font-family: fontawesome;
top: 50%;
left: 50%;
-webkit-transform: translateX(-50%) translateY(-50%);
-moz-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
-o-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
:checked
status, the said ::before
pseudo element is set visible (so that the "orange dot" shows up), by the following code:.fgt-sec input[type="checkbox"]:checked ~ label span:before {
opacity: 1;
visibility: visible;
}
For more detailed information, consider to check MDN pages for CSS selectors and ::before
.
Hope that this could help locate the error.
Original
It looks like this is because the label
is styled as the next adjacent element of the original input
. Since the pseudo element is also dependent on the styles on label
, it disappears as the label
is not correctly styled.
It seems to work if the additional input
is added after label
:
<div class="fgt-sec">
<input type="checkbox" name="cc" id="c2" />
<label for="c2">
<span></span>
</label>
<!-- 👇 Additional input moved to here -->
<input type="hidden" name="test" />
<small>Yes, I understand and agree to the Terms & Conditions.</small>
</div>
Alternatively, if the additional input
cannot be moved, consider change the combinator in CSS from +
to ~
so it targets the label
correctly, as shown in below example.
Example:
.fgt-sec {
float: left;
}
.fgt-sec input[type="checkbox"] {
display: none;
}
.fgt-sec label {
float: left;
}
/* 👇 Changed combinator to "~" here */
.fgt-sec input[type="checkbox"] ~ label span {
display: inline-block;
width: 15px;
height: 15px;
position: relative;
border: 1px solid #d2d2d2;
-webkit-border-radius: 100px;
-moz-border-radius: 100px;
-ms-border-radius: 100px;
-o-border-radius: 100px;
border-radius: 100px;
}
/* 👇 Changed combinator to "~" here */
.fgt-sec input[type="checkbox"] ~ label span:before {
content: "";
width: 7px;
height: 7px;
-webkit-border-radius: 100px;
-moz-border-radius: 100px;
-ms-border-radius: 100px;
-o-border-radius: 100px;
border-radius: 100px;
font-size: 8px;
color: #ffffff;
opacity: 0;
visibility: hidden;
background-color: #e44d3a;
position: absolute;
font-family: fontawesome;
top: 50%;
left: 50%;
-webkit-transform: translateX(-50%) translateY(-50%);
-moz-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
-o-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
/* 👇 Changed combinator to "~" here */
.fgt-sec input[type="checkbox"]:checked ~ label span:before {
opacity: 1;
visibility: visible;
}
.fgt-sec small {
float: left;
color: #000000;
font-size: 14px;
font-weight: 500;
margin-left: 10px;
}
.checky-sec > a {
float: right;
color: #000000;
font-size: 14px;
font-weight: 500;
}
<div class="fgt-sec">
<input type="checkbox" name="cc" id="c2" />
<input type="hidden" name="test" />
<label for="c2">
<span></span>
</label>
<small>Yes, I understand and agree to the Terms & Conditions.</small>
</div>
Upvotes: 2