takeradi
takeradi

Reputation: 3861

Custom Checkbox Styling - Label jumps on check/uncheck

I am styling a checkbox using CSS3. Everything works fine except that the label jumps whenever I check and uncheck the checkbox. Could you please tell me why?

input[type="checkbox"]{
  display:none;
}

input[type="checkbox"] + label::before{
  background-color: white;
  border: 1px solid #ccc;
  content: '';
  display: inline-block;
  height: 15px;
  width: 15px;
  text-align: center;
  margin: 0 5px -2px 0;
}

input[type="checkbox"]:checked + label::before{
  content: '\2713';
}
<div>
  <input type="checkbox" id="checkbox1">
  <label for="checkbox1">Check 1</label>
</div>

Upvotes: 1

Views: 1132

Answers (3)

zer00ne
zer00ne

Reputation: 43990

Update

As reported by OP, there was(is?) a jumping behavior still present on demo. I added 2 more properties that might resolve the problem. I am getting the same desired results so I can't test it myself (hard to fix what you can't see).

Additional CSS

  margin: 0 5px -5px 0;
  line-height: 100%;
  position: relative; // This should keep the input positioned in one spot. 
  float: left; // This should keep any extra movements of label and/or input from jumping as well.

The point of adding these 2 properties is that both of them take the element(s) out of the normal flow of the document, therefore having little to no interaction with other elements that might normally nudge or displace inputs and/or labels.


  • looked for that funky margin offset that'll always get added on in order to counteract that jumping behavior.

  • balanced out the neg and pos values

  • and added line-height: 100%

    margin: 0 5px -5px 0; line-height: 100%;

Also replaced the div with a fieldset it's not necessary, it just looks better. :)

input[type="checkbox"] {
  display: none;
}
input[type="checkbox"] + label::before {
  background-color: white;
  border: 1px solid #ccc;
  content: '';
  display: inline-block;
  height: 15px;
  width: 15px;
  text-align: center;
  margin: 0 5px -5px 0;
  line-height: 100%;
  position: relative;
  float: left;
}
input[type="checkbox"]:checked + label::before {
  content: '\2713';
}
<fieldset>
  <input type="checkbox" id="checkbox1">
  <label for="checkbox1">Check 1</label>
</fieldset>

Upvotes: 0

IndieRok
IndieRok

Reputation: 1788

You could add an overflow hidden to your pseudo element to prevent the jumping effect. I also updated the css a little bit to compensate for the overflow and the fact that the arrow wasn't really centered properly in the box.

JSFIDDLE Example

Here is my take on it:

input[type="checkbox"]{
  display:none;
}

input[type="checkbox"] + label::before{
  background-color: white;
  border: 1px solid #ccc;
  content: '';
  display: inline-block;
  height: 22px; /*Change width and height to compensate*/
  width: 22px; 
  text-align: center;
  margin: 0 5px -2px 0;
  /*Added styles*/
  overflow: hidden;
  top: 3px;
  position: relative;
}

input[type="checkbox"]:checked + label::before{
  content: '\2713';
}

Upvotes: 2

Sooraj
Sooraj

Reputation: 10567

You can make the position for pseudo element to absolute and place it accordingly.

Here is a solution.

div
{
  padding-left:20px;
}
input[type="checkbox"]{
  display:none;
}

input[type="checkbox"] + label::before{
  background-color: white;
  border: 1px solid #ccc;
  content: '';
  display: inline-block;
  height: 15px;
  width: 15px;
  text-align: center;
  margin: 0 5px -2px 0;
  position:absolute;
  left:10px;
}

input[type="checkbox"]:checked + label::before{
  content: '\2713';
}
<div>
  <input type="checkbox" id="checkbox1">
  <label for="checkbox1">Check 1</label>
</div>

There might be other attractive solutions too, this is just one.

Upvotes: 1

Related Questions