I am trying to style a checkbox using the following:
Here is an example, with theme support. It is a modern approach with CSS transitions. There is absolutely no JavaScript required.
I derived the following code linked in this comment; on a related question.
Edit: I added radio buttons, as maxshuty suggests.
const selector = '.grid-container > .grid-row > .grid-col[data-theme="retro"]';
const main = () => {
new CheckboxStyler().run(selector);
new RadioStyler().run(selector);
};
/*
* This is only used to add the wrapper class and checkmark span to an existing DOM,
* to make this CSS work.
*/
class AbstractInputStyler {
constructor(options) {
this.opts = options;
}
run(parentSelector) {
let wrapperClass = this.opts.wrapperClass;
let parent = document.querySelector(parentSelector) || document.getElementsByTagName('body')[0];
let labels = parent.querySelectorAll('label');
if (labels.length) labels.forEach(label => {
if (label.querySelector(`input[type="${this.opts._inputType}"]`)) {
if (!label.classList.contains(wrapperClass)) {
label.classList.add(wrapperClass);
label.appendChild(this.__createDefaultNode());
}
}
});
return this;
}
/* @protected */
__createDefaultNode() {
let checkmark = document.createElement('span');
checkmark.className = this.opts._activeClass;
return checkmark;
}
}
class CheckboxStyler extends AbstractInputStyler {
constructor(options) {
super(Object.assign({
_inputType: 'checkbox',
_activeClass: 'checkmark'
}, CheckboxStyler.defaultOptions, options));
}
}
CheckboxStyler.defaultOptions = {
wrapperClass: 'checkbox-wrapper'
};
class RadioStyler extends AbstractInputStyler {
constructor(options) {
super(Object.assign({
_inputType: 'radio',
_activeClass: 'pip'
}, RadioStyler.defaultOptions, options));
}
}
RadioStyler.defaultOptions = {
wrapperClass: 'radio-wrapper'
};
main();
/* Theming */
:root {
--background-color: #FFF;
--font-color: #000;
--checkbox-default-background: #EEE;
--checkbox-hover-background: #CCC;
--checkbox-disabled-background: #AAA;
--checkbox-selected-background: #1A74BA;
--checkbox-selected-disabled-background: #6694B7;
--checkbox-checkmark-color: #FFF;
--checkbox-checkmark-disabled-color: #DDD;
}
[data-theme="dark"] {
--background-color: #111;
--font-color: #EEE;
--checkbox-default-background: #222;
--checkbox-hover-background: #444;
--checkbox-disabled-background: #555;
--checkbox-selected-background: #2196F3;
--checkbox-selected-disabled-background: #125487;
--checkbox-checkmark-color: #EEE;
--checkbox-checkmark-disabled-color: #999;
}
[data-theme="retro"] {
--background-color: #FFA;
--font-color: #000;
--checkbox-default-background: #EEE;
--checkbox-hover-background: #FFF;
--checkbox-disabled-background: #BBB;
--checkbox-selected-background: #EEE;
--checkbox-selected-disabled-background: #BBB;
--checkbox-checkmark-color: #F44;
--checkbox-checkmark-disabled-color: #D00;
}
/* General styles */
html {
width: 100%;
height: 100%;
}
body {
/*background: var(--background-color); -- For demo, moved to column. */
/*color: var(--font-color); -- For demo, moved to column. */
background: #777;
width: calc(100% - 0.5em);
height: calc(100% - 0.5em);
padding: 0.25em;
}
h1 {
font-size: 1.33em !important;
}
h2 {
font-size: 1.15em !important;
margin-top: 1em;
}
/* Grid style - using flex */
.grid-container {
display: flex;
height: 100%;
flex-direction: column;
flex: 1;
}
.grid-row {
display: flex;
flex-direction: row;
flex: 1;
margin: 0.25em 0;
}
.grid-col {
display: flex;
flex-direction: column;
height: 100%;
padding: 0 1em;
flex: 1;
margin: 0 0.25em;
/* If not demo, remove and uncomment the body color rules */
background: var(--background-color);
color: var(--font-color);
}
.grid-cell {
width: 100%;
height: 100%;
}
/* The checkbox wrapper */
.checkbox-wrapper,
.radio-wrapper {
display: block;
position: relative;
padding-left: 1.5em;
margin-bottom: 0.5em;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* Hide the browser's default checkbox and radio buttons */
.checkbox-wrapper input[type="checkbox"] {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
.radio-wrapper input[type="radio"] {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
/* Create a custom checkbox */
.checkbox-wrapper .checkmark {
position: absolute;
top: 0;
left: 0;
height: 1em;
width: 1em;
background-color: var(--checkbox-default-background);
transition: all 0.2s ease-in;
}
.radio-wrapper .pip {
position: absolute;
top: 0;
left: 0;
height: 1em;
width: 1em;
border-radius: 50%;
background-color: var(--checkbox-default-background);
transition: all 0.2s ease-in;
}
/* Disabled style */
.checkbox-wrapper input[type="checkbox"]:disabled~.checkmark,
.radio-wrapper input[type="radio"]:disabled~.pip {
cursor: not-allowed;
background-color: var(--checkbox-disabled-background);
color: var(--checkbox-checkmark-disabled-color);
}
.checkbox-wrapper input[type="checkbox"]:disabled~.checkmark:after,
.radio-wrapper input[type="radio"]:disabled~.pip:after {
color: var(--checkbox-checkmark-disabled-color);
}
.checkbox-wrapper input[type="checkbox"]:disabled:checked~.checkmark,
.radio-wrapper input[type="radio"]:disabled:checked~.pip {
background-color: var(--checkbox-selected-disabled-background);
}
/* On mouse-over, add a grey background color */
.checkbox-wrapper:hover input[type="checkbox"]:not(:disabled):not(:checked)~.checkmark,
.radio-wrapper:hover input[type="radio"]:not(:disabled):not(:checked)~.pip {
background-color: var(--checkbox-hover-background);
}
/* When the checkbox is checked, add a blue background */
.checkbox-wrapper input[type="checkbox"]:checked~.checkmark,
.radio-wrapper input[type="radio"]:checked~.pip {
background-color: var(--checkbox-selected-background);
}
/* Create the checkmark/indicator (hidden when not checked) */
.checkbox-wrapper .checkmark:after {
display: none;
width: 100%;
position: absolute;
text-align: center;
content: "\2713";
color: var(--checkbox-checkmark-color);
line-height: 1.1em;
}
.radio-wrapper .pip:after {
display: none;
width: 100%;
position: absolute;
text-align: center;
content: "\2022";
color: var(--checkbox-checkmark-color);
font-size: 1.5em;
top: -0.2em;
}
/* Show the checkmark when checked */
.checkbox-wrapper input[type="checkbox"]:checked~.checkmark:after {
display: block;
line-height: 1.1em;
}
.radio-wrapper input[type="radio"]:checked~.pip:after {
display: block;
line-height: 1.1em;
}
Pure CSS
Checkbox
Radio
Pure CSS
Checkbox
Radio
JS + CSS
Checkbox
Radio