Style checkboxes with appearance


#1

Would be nice to style checkboxes without tricks. Right now to create a custom checkbox you need to hide the checkbox, use another element to replace the checkbox itself and handling some accessibility edge cases like avoiding to hide the input completely from screen reader…

Would not be simpler if we can define an svg to replace our checkbox with appearance property? As part of the proposal would nice we can change colors of the svg and use animations.

example of current situation

<label>
  <span class="checkbox">
    <input type="checkbox" class="checkbox-input"/>
    <span class="checkbox-icon"></span>
  </span>
   label
</label>

.checkbox {}
.checkbox-input { visibility: hidden; height:0; width:0; }
.checkbox-icon:before {
  content: "[]";
  display: inline-block;
}
.checkbox-input:checked ~ .checkbox-icon:before {
  content: "[x]";
}

Example proposal

<label>
  <input type="checkbox" class="checkbox-3"/>
  label
</label>

.checkbox-2 {
  appearance: url(input.svg#checkbox);
  transition: fill .5s;
}
.checkbox-2:checked {
  appearance: url(input.svg#checkbox-checked);
}

.checkbox-2:checked .checkbox-2-tick {
  fill: tomato;
}

.checkbox-2:disabled {
  opacity: .4;
}
.checkbox-2:disabled .checkbox-2-tick {
  fill: gray;
}


#2

Opera’s old Presto engine let us do exactly this with the content property. Unfortunately, no other browser seems interested.


#3

Forms in general need a standardized way of styling.


#4

I see three options:

  1. use specific property to replace the visual like “list-style-image” does

    pros: complete freedom to use the checkbox/forms you wish to use with svg or image cons: hard to theme, I do not think we could select the svg elements, if it’s an image you definitely cannot theme it

    .input[type="checkbox"] {
      appearance: url(ui.svg#checkbox);
    }
    
    /* tick class is inside the svg, not sure if it is possible, looks like a bit awkward */
    .input[type="checkbox"] .tick { 
      appearance: url(ui.svg#checkbox);
    }
    
  2. define a set of specific properties or pseudo classes to style checkbox/forms

    pros: you have some kind of standard way to style the checkbox across browsers cons: you need to create an appearance: web-checkbox to avoid to use the OS input you have some limitation on what you can style it

    .input[type="checkbox"] {
    	appearance: web-checkbox;
    	checkbox-size: 40px;
    	checkbox-color: blue;
    }
    
    .input[type="checkbox"]:checked {
    	checkbox-color: red;
    }
    
    /* or */
    
    .input[type="checkbox"] {
    	appearance: web-checkbox;
    }
    
    .input[type="checkbox"]::tick {
    	checkbox-size: 40px;
    	checkbox-color:  blue;
    }
    
    .input[type="checkbox"]:checked::tick {
    	checkbox-color:  red;
    }
    
  3. use CSS Paint API to create your visual

    pros: complete freedom to use the checkbox/forms you wish ability to theme as you wish cons: this option is powerfull but I think styling form are a common problem and should be solved by the platform and use paint to solve edge cases or more complex cases

    .input[type="checkbox"] {
    	--checkbox-color: blue;
    	appearance: paint(checkbox);
    }
    
    .input[type="checkbox"]:checked {
    	--checkbox-color: red;
    }