12

Is there a browser agnostic way to increase a <input type="checkbox">'s size without changing HTML markup ?

I tried to change height and width in the CSS but the problems is that in Firefox the checkbox gets pixelated. In Opera only the logic size of the input increases, not the visual.

Should I use a <label> and :before pseudo selectors to make it look nice and big, what are the alternative solutions?

Trying to avoid JavaScript if possible.

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Walle Cyril
  • 3,087
  • 4
  • 23
  • 55
  • Note that asking for "alternative solutions" is pretty broad; there are literally hundreds of them. Serg has presented one of them, but there are many others... – Heretic Monkey Jan 23 '17 at 23:10
  • OK, started a bounty for more answers – Walle Cyril Jan 28 '17 at 11:08
  • for the firefox issue: try `-moz-appearance: none;` and then configure the border. the checkmark itself should be rendered via SVG and thus scalable. – the8472 Feb 04 '17 at 08:46

3 Answers3

7

You are right in your assumption, cross-browser support is inconsistent. If you want bulletproof customization you will want to write your own solution.

Personally, I would look at solutions used by major css frameworks such as Bootstrap and Foundation.

From one of the links:

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

label input[type="checkbox"]:checked + .cr > .cr-icon{
    transform: scale(1) rotateZ(0deg);
    opacity: 1;
}

label input[type="checkbox"] + .cr > .cr-icon{
    transform: scale(3) rotateZ(-20deg);
    opacity: 0;
    transition: all .3s ease-in;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<label>
    <input type="checkbox" value="" checked="">
    <span class="cr"><i class="cr-icon fa fa-check"></i></span>
    Click Me
</label>

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

label input[type="checkbox"]:checked + .cr > .cr-icon{
    transform: scale(1) rotateZ(0deg);
    opacity: 1;
}

label input[type="checkbox"] + .cr > .cr-icon{
    transform: scale(3) rotateZ(-20deg);
    opacity: 0;
    transition: all .3s ease-in;
}

.cr-icon {
    display: inline-block;
    font: normal normal normal 14px/1 FontAwesome;
    font-size: inherit;
    text-rendering: auto;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
.cr-icon:before {
    content: "\2713";  
}
<label>
    <input type="checkbox" value="" checked="">
    <span class="cr"><i class="cr-icon"></i></span>
    Click Me
</label>
vals
  • 61,425
  • 11
  • 89
  • 138
Serg Chernata
  • 12,280
  • 6
  • 32
  • 50
2

For this you can use pseudo selector

HTML

<input type="checkbox" id="test1" />
<label for="test1">Checkbox</label>

CSS

/* Base for label styling */
[type="checkbox"]:not(:checked),
[type="checkbox"]:checked {
  position: absolute;
  left: -9999px;
}
[type="checkbox"]:not(:checked) + label,
[type="checkbox"]:checked + label {
  position: relative;
  padding-left: 25px;
  cursor: pointer;
}

/* checkbox aspect */
[type="checkbox"]:not(:checked) + label:before,
[type="checkbox"]:checked + label:before {
  content: '';
  position: absolute;
  left:0; top: -1px;
  width: 17px; height: 17px;
  border: 1px solid #bbb;
  background: #fff;
  border-radius: 3px;
  box-shadow: inset 0 1px 3px rgba(0,0,0,.1);
}
/* checked mark aspect */
[type="checkbox"]:not(:checked) + label:after,
[type="checkbox"]:checked + label:after {
  content: '✔';
  position: absolute;
  top: 1px; left: 4px;
  font-size: 19px;
  line-height: 0.8;
  color: #09ad7e;
  transition: all .2s;
}
/* checked mark aspect changes */
[type="checkbox"]:not(:checked) + label:after {
  opacity: 0;
  transform: scale(0);
}
[type="checkbox"]:checked + label:after {
  opacity: 1;
  transform: scale(1);
}
/* disabled checkbox */
[type="checkbox"]:disabled:not(:checked) + label:before,
[type="checkbox"]:disabled:checked + label:before {
  box-shadow: none;
  border-color: #bbb;
  background-color: #ddd;
}
[type="checkbox"]:disabled:checked + label:after {
  color: #999;
}
[type="checkbox"]:disabled + label {
  color: #aaa;
}
/* accessibility */
[type="checkbox"]:checked:focus + label:before,
[type="checkbox"]:not(:checked):focus + label:before {
  border: 1px dotted blue;
}

/* hover style just for information */
label:hover:before {
  border: 1px solid #4778d9!important;
}

for updated fiddle click here

Super User
  • 9,448
  • 3
  • 31
  • 47
0

Here is the leanest solution I can think of: use a label next to a checkbox, and style the label using a character placed in a ::before pseudo-element.

input[type="checkbox"]{ display: none; }
input[type="checkbox"]+label::before
{
   content: '☑ ';
   font-size: 1.5em;
}
input[type="checkbox"]:checked+label::before
{
   content: '☐ ';
}
<input id="cb" type="checkbox"/>
<label for="cb">Click Me</label>

You may change the size of the box by customising the font size, or even change the whole style of the checkbox using your custom font.

UPDATE: If you want to customize the look of the box while staying away from using a custom font, you may want to play with SVG backgrounds. Here is an ugly example, but you get the idea (also feel free to use a border for the outside of the checkbox or include it to the SVG):

input[type="checkbox"]{ display: none; }
input[type="checkbox"]+label::before
{
   content: '☐';
   font-size: 1.5em;

}
input[type="checkbox"]:checked+label::before
{
   background: url('https://upload.wikimedia.org/wikipedia/commons/8/8b/Checkbox.svg');
   background-size: contain;
   background-repeat: no-repeat;
   background-position: center center;
}
<input id="cb" type="checkbox"/>
<label for="cb">Click Me</label>
Gyum Fox
  • 3,287
  • 2
  • 41
  • 71