How do I change the color of the check mark within an HTML checkbox input?
7 Answers
Here's a pure CSS solution that shouldn't break screen readers or default user agent actions. Additionally, this is supported in the latest versions of the big 4 browsers (and a few others if you add some additional hacks, but I'll leave that to you to figure out; probably won't get more than IE8+ support since it uses pseudo elements).
The idea is to hide the actual form element (because browsers do a hard replace with internal styles and don't expose all style-ability to css yet) and replace it with one we like. One side effect is that you will want to track change events rather than click events in your JS if you need it (but you were doing that anyway right?).
Because the label is tied to the form element clicking it works like one would expect, so the new, awesome, checkbox (::before
) abuses attribute selectors ([checked]
) on the original to check if it is checked
. When it is checked it will display our awesomer checkmark (::after
).
The checkmark (::after
) abuses border width for thickness and height/width for making a checkmark like item. Finally, we transform the box 45deg to match the angle up properly.
To change the color of the checkmark, change the border color on the ::after
style. Additionally, if you wanted it to always match your text color remove the border color on it altogether. To change the radio, change the radial gradient start color (the one that isn't white).
Also awesome is that its tied to font size, so if your text is bigger, it should shim right in (though rounding errors can happen when using relative font sizes, so be careful)
I've included basic styles for both check-able types (checkbox and radio).
HTML:
<fieldset>
<legend>Checkbox example</legend>
<input id="checkbox" type="checkbox"/>
<label for="checkbox">Some awesome checkbox label</label>
</fieldset>
<fieldset>
<legend>Radio example</legend>
<div>
<input id="radio1" type="radio" name="radio"/>
<label for="radio1">Some awesome radio option #1</label>
<div>
</div>
<input id="radio2" type="radio" name="radio"/>
<label for="radio2">Some awesome radio option #2</label>
</div>
</fieldset>
CSS:
label, input[type="radio"], input[type="checkbox"] {
line-height: 2.1ex;
}
input[type="radio"],
input[type="checkbox"] {
position: absolute;
left: -999em;
}
input[type="radio"] + label,
input[type="checkbox"] + label {
position: relative;
overflow: hidden;
cursor: pointer;
}
input[type="radio"] + label::before,
input[type="checkbox"] + label::before {
content: "";
display: inline-block;
vertical-align: -25%;
height: 2ex;
width: 2ex;
background-color: white;
border: 1px solid rgb(166, 166, 166);
border-radius: 4px;
box-shadow: inset 0 2px 5px rgba(0,0,0,0.25);
margin-right: 0.5em;
}
input[type="radio"]:checked + label::before {
background: radial-gradient(circle at center, #1062a4 .6ex, white .7ex);
}
input[type="radio"] + label::before {
border-radius: 50%;
}
input[type="checkbox"]:checked + label::after {
content: '';
position: absolute;
width: 1.2ex;
height: 0.4ex;
background: rgba(0, 0, 0, 0);
top: 0.9ex;
left: 0.4ex;
border: 3px solid #1062a4;
border-top: none;
border-right: none;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
}
Side note: necropost because this was the first question that popped up when I was trying to remember how I pulled this off in the past. ;)

- 9,107
- 1
- 33
- 56
-
2Anything that supports the newer double colon psuedo elements (pretty much IE9+, and everyone else). Only problem I haven't worked out to be a full progressive enhancement solution is the positioning of the checkboxes themselves. So, as it stands right now it will make the checkbox disappear in IE8 and below, but the label will still cause the item to check (not that it saves the usability problem). You could probably degrade it to IE8+ support if you change double colons to single and use ms's old filters for rotation, but I haven't tested it. The best thing to do is find how to solve #1 – Kevin Peno Aug 23 '13 at 08:23
-
The code snippet revision didn't add any value (or even work) and removed some context, so I've reverted it. If you add it again, please make sure it works. I'll take a look at updating the jsfiddle to work again too if I can. – Kevin Peno Mar 11 '16 at 21:22
You could create a checkbox image and use that as your checkbox
The following post discusses custom input controls...

- 34,899
- 5
- 77
- 90
-
Two images, one for the checked state and one for the unchecked state. Javascript could swap them for you based on a variable that you set each time the image is clicked. – JYelton Apr 14 '10 at 17:07
If you need to change tick color from black to white, just try applying filter: invert(1)
to the checkbox.

- 442
- 4
- 15
-
Simple and clever. I used the greyscale filter to achieve a more neutral solution. – MastaBaba Apr 12 '21 at 15:38
-
You can do like this.
input[type='checkbox']:checked {
background-color: #023047;
}
input[type='checkbox']:checked:after {
content: '\2713';
color:white;
}
input[type='checkbox']{
text-align: center;
display: table-cell;
vertical-align: middle;
width: 20px !important;
height: 20px !important;
appearance:none;
border-radius:10%;
border: 1px solid rgb(191 35 42 / 90%);
box-shadow: none;
font-size: 1em;
}
<input type="checkbox" > checkbox 1
<input type="checkbox" > checkbox 2

- 329
- 1
- 7
Check this It will Show you how to style a checkbox How to create a custom checkbox You can do it without JS
/* Customize the label (the container) */
.container {
display: block;
position: relative;
padding-left: 35px;
margin-bottom: 12px;
cursor: pointer;
font-size: 22px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* Hide the browser's default checkbox */
.container input {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
/* Create a custom checkbox */
.checkmark {
position: absolute;
top: 0;
left: 0;
height: 25px;
width: 25px;
background-color: #eee;
}
/* On mouse-over, add a grey background color */
.container:hover input ~ .checkmark {
background-color: #ccc;
}
/* Create the checkmark/indicator (hidden when not checked) */
.checkmark:after {
content: "";
position: absolute;
display: none;
}
/* Show the checkmark when checked */
.container input:checked ~ .checkmark:after {
display: block;
}
/* Style the checkmark/indicator */
.container .checkmark:after {
left: 9px;
top: 5px;
width: 5px;
height: 10px;
border: solid white;
border-width: 0 3px 3px 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
/* When the checkbox is checked, add a blue background */
.container input:checked ~ .checkmark {
background-color: #2196F3;
}
.container input.white:checked ~ .checkmark:after {
border: solid white;
border-width: 0 3px 3px 0;
}
.container input.black:checked ~ .checkmark:after {
border: solid #000;
border-width: 0 3px 3px 0;
}
.container input.red:checked ~ .checkmark:after {
border: solid #cb1a1a;
border-width: 0 3px 3px 0;
}
.container input.green:checked ~ .checkmark:after {
border: solid #1f4f12;
border-width: 0 3px 3px 0;
}
.container input.yellow:checked ~ .checkmark:after {
border: solid #c6c253;
border-width: 0 3px 3px 0;
}
<label class="container">Black
<input type="checkbox" class="black" checked="checked">
<span class="checkmark"></span>
</label>
<label class="container">White
<input type="checkbox" class="white">
<span class="checkmark"></span>
</label>
<label class="container">Yellow
<input type="checkbox" class="yellow">
<span class="checkmark"></span>
</label>
<label class="container">Red
<input type="checkbox" class="red">
<span class="checkmark"></span>
</label>
<label class="container">Green
<input type="checkbox" class="green">
<span class="checkmark"></span>
</label>

- 406
- 2
- 13
If you use b-form-checkbox
and you will find css
of mark is svg
like that...
.custom-checkbox
.custom-control-input:checked
~ .custom-control-label::after {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath **fill='%23000'** d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e");
It's drawn by svg
, so you can change coordinate to modify mark or change fill
to change mark color.

- 4,811
- 4
- 23
- 45

- 1
- 1
You can imitate a check box with another element and set the background color as desired.
<span onclick="this.innerHTML = (this.innerHTML ? '' : 'X')"></span>
<style>
span{
display:inline-block;
width:10px; height:10px;
font:10px/10px 'Sans Serif'; color: green;
border:solid 1px black;
vertical-align:middle;
cursor:pointer;
}
</style>
You can get a little fancier by using ::before or after
<span class='checked' onclick="this.classList.toggle('checked')"></span>
<style>
span{
display:inline-block;
height: 10px; width:10px;
border:solid 1px black;
vertical-align:middle;
cursor:pointer;
}
span.checked::before{
content:'×';
display:block; height: 10px;
font:10px/10px 'Sans Serif';
color:green;
}
</style>
You can extend this, by using background image or a svg sprite in the ::after tag (see https://stackoverflow.com/a/19255455/87520)
I haven't tried to make it perfect, just to demonstrate the concept. As you can see, the background color is green, no images, no libraries involved; minimal js.

- 13,758
- 9
- 81
- 91