Custom checkbox using only CSS and HTML

2019-02-12 02:03发布

问题:

I need to create a custom checkbox using only html and CSS. So far I have:

HTML/CSS:

.checkbox-custom {
  opacity: 0;
  position: absolute;
}
.checkbox-custom,
.checkbox-custom-label {
  display: inline-block;
  vertical-align: middle;
  margin: 5px;
  cursor: pointer;
}
.checkbox-custom + .checkbox-custom-label:before {
  content: '';
  background: #fff;
  border-radius: 5px;
  border: 2px solid #ddd;
  display: inline-block;
  vertical-align: middle;
  width: 10px;
  height: 10px;
  padding: 2px;
  margin-right: 10px;
  text-align: center;
}
.checkbox-custom:checked + .checkbox-custom-label:before {
  content: "";
  display: inline-block;
  width: 1px;
  height: 5px;
  border: solid blue;
  border-width: 0 3px 3px 0;
  transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  border-radius: 0px;
  margin: 0px 15px 5px 5px;
}
<div>
  <input id="checkbox-1" class="checkbox-custom" name="checkbox-1" type="checkbox">
  <label for="checkbox-1" class="checkbox-custom-label">First Choice</label>
</div>
<div>
  <input id="checkbox-2" class="checkbox-custom" name="checkbox-2" type="checkbox">
  <label for="checkbox-2" class="checkbox-custom-label">Second Choice</label>
</div>

The checked checkbox should be a checkmark with the square bordered around it instead of just a checkmark. Searching for answers, I have only found cases where the checkmark is displayed using a UTF-8 character or an image. I am not able to use either of these for what I am trying to accomplish. I am only able to use plain CSS and HTML. Any suggestions?

codepen here: http://codepen.io/alisontague/pen/EPXagW?editors=110

回答1:

The problem is that you are using the same pseudo element for the square border and the checkmark. The simple solution would be to continue using the :before pseudo element for the border, and then use an :after pseudo element for the checkmark.

Updated Example

You would have to absolutely position the :after pseudo element relative to the parent .checkbox-custom label element.

Here is the updated code:

.checkbox-custom {
  display: none;
}
.checkbox-custom-label {
  display: inline-block;
  position: relative;
  vertical-align: middle;
  margin: 5px;
  cursor: pointer;
}
.checkbox-custom + .checkbox-custom-label:before {
  content: '';
  background: #fff;
  border-radius: 5px;
  border: 2px solid #ddd;
  display: inline-block;
  vertical-align: middle;
  width: 10px; height: 10px;
  padding: 2px; margin-right: 10px;
}
.checkbox-custom:checked + .checkbox-custom-label:after {
  content: "";
  padding: 2px;
  position: absolute;
  width: 1px;
  height: 5px;
  border: solid blue;
  border-width: 0 3px 3px 0;
  transform: rotate(45deg);
  top: 2px; left: 5px;
}
<h3>Checkboxes</h3>
<div>
  <input id="checkbox-1" class="checkbox-custom" name="checkbox-1" type="checkbox">
  <label for="checkbox-1" class="checkbox-custom-label">First Choice</label>
</div>
<div>
  <input id="checkbox-2" class="checkbox-custom" name="checkbox-2" type="checkbox">
  <label for="checkbox-2" class="checkbox-custom-label">Second Choice</label>
</div>



回答2:

My previous answer is wrong because it uses the ::before pseudo-element selector on an element that isn't a container. Thanks to @BoltClock for pointing out my error. So, I came up with another solution that uses the Checkbox Hack and the CSS3 sibling selector (~).

Demo at CodePen

input[type=checkbox] {
  position: absolute;
  top: -9999px;
  left: -9999px;
}
input[type=checkbox] ~ label::before {
  content: '\2713';
  display: inline-block;
  text-align: center;
  color: white;
  line-height: 1em;
  width: 1em;
  height: 1em;
  border: 1px inset silver;
  border-radius: 0.25em;
  margin: 0.25em;
}
input[type=checkbox]:checked ~ label::before {
  color: black;
}
<form name="checkbox-form" id="checkbox-form">
  <div>
    <input id="checkbox-1" class="checkbox-custom" name="checkbox-1" type="checkbox">
    <label for="checkbox-1" class="checkbox-custom-label">First Choice</label>
  </div>
  <div>
    <input id="checkbox-2" class="checkbox-custom" name="checkbox-2" type="checkbox">
    <label for="checkbox-2" class="checkbox-custom-label">Second Choice</label>
  </div>
</form>

I didn't use StackOverflow's "Run Code-Snippet" functionality because it does something weird when I run it. I think it's because of the checkbox hack.



回答3:

Custom checkbox using only HTML and CSS along with three checkbox states (checked, unchecked and half checked or unchecked(if it's used in a group of checkboxes))

<label class="checkboxcontainer"> one
  <input type="checkbox">
  <span class="checkmark"></span>
</label>

.checkboxcontainer input {
  display: none;
}

.checkboxcontainer {
  display: inlin-block;
  padding-left: 30px;
  position: relative;
  cursor: pointer;
  user-select: none;
}

.checkboxcontainer .checkmark {
  display: inlin-block;
  width: 25px;
  height: 25px;
  background: #eee;
  position: absolute;
  left: 0;
  top: 0;
}

.checkboxcontainer input:checked+.checkmark {
  background-color: #2196fc;
}

.checkboxcontainer input:checked+.checkmark:after {
  content: "";
  position: absolute;
  height: 4px;
  width: 9px;
  border-left: 3px solid white;
  border-bottom: 3px solid white;
  top: 45%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-45deg);
}

.checkboxcontainer input:indeterminate+.checkmark:after {
  content: "";
  position: absolute;
  height: 0px;
  width: 9px;
  border-left: 3px solid white;
  border-bottom: 3px solid white;
  top: 45%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(180deg);
  }

Jsfiddle: Demo



回答4:

.checkbox-custom {
  position: relative;
}

.checkbox-custom input[type=checkbox] {
  display: none;
}

.checkbox-custom input[type=checkbox]~b {
  cursor: pointer;
  outline: 0;
  position: relative;
  display: inline-block;
  margin: 4px 1px 0;
  background-color: #ffffff;
  border: 2px solid #ad823a;
  width: 24px;
  height: 24px;
  vertical-align: middle;
  line-height: 1;
  text-align: center;
  font-size: 20px;
  color: #ad823a;
}

.checkbox-custom input[type=checkbox]:checked~b:after {
  content: '\2713';
}
<div class="checkbox-custom">
  <label>
                <input type="checkbox">
                <b></b>
                <span>app 1</span>
            </label>
</div>
<div class="checkbox-custom">
  <label>
                <input type="checkbox">
                <b></b>
                <span>app 1</span>
            </label>
</div>