36

I am trying to change the default 'box image' of the checkbox with CSS, but it is not working. Is there any way around this?

.class_checkbox{
    background: url("../images/button_bullet_normal.png") no-repeat scroll 0 0 transparent;
}
<input type="checkbox" class="class_checkbox">
TylerH
  • 20,799
  • 66
  • 75
  • 101
themhz
  • 8,335
  • 21
  • 84
  • 109
  • 4
    Not without JavaScript. Do you want to rephrase your question? – iambriansreed Apr 22 '12 at 18:51
  • Check this: [previous question](http://stackoverflow.com/a/1986931/1190388) – hjpotter92 Apr 22 '12 at 18:55
  • You have to use javascript. There is not 100% way to do this just using HTML+CSS. Example: http://ryanfait.com/resources/custom-checkboxes-and-radio-buttons/ – crash01 Apr 22 '12 at 18:54
  • Here is a pure CSS way to change your checkbox style. I found it really useful, since I had already other functions related to the exact same checkboxes. http://www.jotform.org/html-elements/css-checkbox-background-color/ – user2831723 Jan 08 '14 at 12:01

5 Answers5

94

You can use pure css, just add a label to the checkbox like this:

.check_box {
    display:none;
}

.check_box + label{
    background:url('images/check-box.png') no-repeat;
    height: 16px;
    width: 16px;
    display:inline-block;
    padding: 0 0 0 0px;
}

.check_box:checked + label{
    background:url('images/check-box-checked.png') no-repeat;
    height: 16px;
    width: 16px;
    display:inline-block;
    padding: 0 0 0 0px;
}

Example HTML:

    .check_box {
     display:none;
    }

    .check_box + label{
     background:url('images/check-box.png') no-repeat;
     height: 16px;
     width: 16px;
     display:inline-block;
        padding: 0 0 0 0px;
    }

    .check_box:checked + label{
        background:url('images/check-box-checked.png') no-repeat;
     height: 16px;
     width: 16px;
     display:inline-block;
        padding: 0 0 0 0px;
    }
<input type="checkbox" class="check_box" id="checkbox1">
<label for="checkbox1">
Developer
  • 4,158
  • 5
  • 34
  • 66
ali mokrani
  • 1,169
  • 1
  • 8
  • 12
13

Try:

<input type="checkbox" class="input_class_checkbox">

jQuery

$('.input_class_checkbox').each(function(){
    $(this).hide().after('<div class="class_checkbox" />');

});

$('.class_checkbox').on('click',function(){
    $(this).toggleClass('checked').prev().prop('checked',$(this).is('.checked'))
});

Fiddle: http://jsfiddle.net/cn6kn/

$('.input_class_checkbox').each(function(){
    $(this).hide().after('<div class="class_checkbox" />');

});

$('.class_checkbox').on('click',function(){
    $(this).toggleClass('checked').prev().prop('checked',$(this).is('.checked'))
});
.class_checkbox {
    width: 20px;  
    height: 20px;
    background-color: red;
}
.class_checkbox.checked {
    background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" class="input_class_checkbox">
LogicalAnt
  • 907
  • 3
  • 12
  • 28
iambriansreed
  • 21,935
  • 6
  • 63
  • 79
10

I created a Fiddle using pure CSS. The most voted answer doesn't handle click events and won't work well, because the checkbox value won't change.

This is my example:

http://jsfiddle.net/kEHGN/1/

Basically, we need the following html:

<div class="checkbox_wrapper">
    <input type="checkbox" />
    <label></label>
</div>

And the following CSS:

.checkbox_wrapper{
    position: relative;
    height: 16px;
    width: 17px;
}

input[type="checkbox"] {
    opacity:0;
    height: 16px;
    width: 17px;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
}

input[type="checkbox"] + label{
    background:url('../images/unchecked.png') no-repeat;
    height: 16px;
    width: 17px;
    display:inline-block;
    padding: 0 0 0 0px;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
}

input[type="checkbox"]:checked + label{
    background:url('../images/checked.png') no-repeat;
    height: 16px;
    width: 17px;
    display:inline-block;
    padding: 0 0 0 0px;
}

Just check the routes of the images, and the widths and heights should be equal to the width and height of the images. On the fiddler I am using base64 encoded images.

I hope it can be useful.

Tony
  • 10,088
  • 20
  • 85
  • 139
3

I found another way, without using adjacent labels or surrounding divs.

My usecase was that I had a markdown parser that generates those nifty TODO lists and I wanted to style them. Changing the generated HTML wasn't a option, so I came up with this solution:

given a checkbox like this:

<input type="checkbox" id="cb">

You can style it with visibility: hidden on checkbox and visibility: visible on ::after, like this:

#cb {
  visibility: hidden;
}

input#cb::after {
  visibility: visible;
  content: "F";
  color: red;
  background: green;
  padding: 8px;
}

input#cb:checked::after {
  content: " T ";
  color: green;
  background: red;
}
<!doctype html>
<html>

<body>
  <input type="checkbox" id="cb">
</body>

</html>

EDIT:

@connexo in a comment pointed out that input elements cannot have content. It could be easly done using label element, for example like so (please someone correct me if this is wrong, I don't have non-webkit browser handy to test it).

#cb-span * {
  visibility: hidden;
}

input#cb + label::after {
  visibility: visible;
  content: "F";
  color: red;
  background: green;
  padding: 8px;
}

input#cb:checked + label::after {
  content: " T ";
  color: green;
  background: red;
}
<!doctype html>
<html>

<body>
  <span id="cb-span">
    <input type="checkbox" id="cb">
    <label for="cb"></label>
  </span>
</body>

</html>

The checkbox works just like normal one and you can style it anyway you like.

Maybe it'll help someody (and I can bookmark it, because I haven't found anything like this on the web)

Enbyted
  • 68
  • 8
  • This should never have worked in the first place, as `input` elements cannot have `content` - and thus, no `::after` or `::before`. Firefox correctly won't show your T and F. – connexo Mar 10 '18 at 07:07
  • Hmm, I have tested it on firefox back then and it worked perfectly fine. – Enbyted Mar 10 '18 at 19:50
1

Maybe will be useful my sample with LESS.

<div class="custom-checkbox">
    <input component="input" type="checkbox"/>
    <label>Here is caption right to checkbox</label>
</div>

    @imgsize: 25px;
    .custom-checkbox{
        position: relative;

        > input[type="checkbox"] {

        display:none;
        position: absolute;
        top: 0;
        left: 0;

            + label{

                background:url('../img/unchecked.png') no-repeat 0 0;
                background-size:@imgsize;
                height: @imgsize;
                padding: 4px 0 5px 35px;
                display: inline-block;
                -webkit-transition-duration: 0.3s;
                -moz-transition-duration: 0.3s;
                transition-duration: 0.3s;        
            }
        }
        > input[type="checkbox"]:checked + label{

            background:url('../img/checked.png') no-repeat;
            background-size:@imgsize @imgsize;
        }
    }