21

How do I style a checkbox in firefox, and have the checkmark and border disappear?

http://jsfiddle.net/moneylotion/qZvtY/

CSS:

body { background: black; }
#conditions-form { color: white; }
#conditions-form input[type=checkbox] {
    display:inline-block;
    -webkit-appearance: none;
    -moz-appearance: none;
    -o-appearance:none;
    appearance: none;
    width:19px;
    height:19px;
    background: url('http://demo.somedomain.com/wp-content/themes/themename/images/care-plan-checkbox.gif') no-repeat top left;
    cursor:pointer;
}
#conditions-form input[type=checkbox]:checked {
    background:url('http://demo.somedomain.com/wp-content/themes/themename/images/care-plan-checkbox-checked.gif') no-repeat top left;
}

HTML:

<form id="conditions-form">
    <ul>
        <li>
            <input id="condition3" type="checkbox" name="conditions[condition3]"></input>
            <label class="checkbox" for="condition3">Conditions 3</label>
        </li>
    </ul>
</form>
Joeytje50
  • 18,636
  • 15
  • 63
  • 95
jacobnollette
  • 524
  • 1
  • 4
  • 13

4 Answers4

31

There's a quite easy way you can do this via <label> tags. Just place a label around the checkbox, and insert a dummy element that will be used for the custom styled checkbox. For example:

label.checkbox input[type="checkbox"] {display:none;}
label.checkbox span {
  display:inline-block;
  border:2px solid #BBB;
  border-radius:10px;
  width:25px;
  height:25px;
  background:#C33;
  vertical-align:middle;
  margin:3px;
  position: relative;
  transition:width 0.1s, height 0.1s, margin 0.1s;
}
label.checkbox :checked + span {
  background:#6F6;
  width:27px;
  height:27px;
  margin: 2px;
}
label.checkbox :checked + span:after {
  content: '\2714';
  font-size: 20px;
  position: absolute;
  top: -2px;
  left: 5px;
  color: #99a1a7;
}
<label class="checkbox">
  <input type="checkbox"/>
  <span></span>
  I like cake
</label>

EDIT: Note that some choices of colours might render the state of your checkbox invisible for colourblind people. When making this code I didn't think of that, but the above demo might be invisible for R/G colourblind people. When implementing this, please do keep that in mind (pick bright/dark colours for example, or show some difference in shape)


The styles I used are just arbitrary, and you can change that to anything you want. You can even toggle certain text inside it via the ::before pseudo-element, such as what I've done here.

I wasn't able to open the image url you provided to use in your question, but I think you'll be able to include whatever image you want by simply modifying this code a little. Just change the current background color to the image URL you want to use.

Note: This won't work in some older browsers.

Jacob van Lingen
  • 8,989
  • 7
  • 48
  • 78
Joeytje50
  • 18,636
  • 15
  • 63
  • 95
  • This is totally brilliant and simple, nice idea! – vitto Oct 30 '14 at 16:08
  • It works, but I don't recommend using the display none attribute as it's not accessible. @Lee Chase solution is more appropriate. – Julio Cesar Brito Gomes Sep 15 '21 at 19:27
  • @JulioCesarBritoGomes I'm not sure what you mean exactly; what do you mean by 'accessible'? You can click on the input using the label, right? – Joeytje50 Sep 17 '21 at 13:37
  • 1
    @Joeytje50 When I talk about accessibility, I'm talking about blind or low vision people who use screen readers to browse the internet. Screen readers (NVDA, Voice Over...) generally ignore anything with display: none, therefore it is not read out to screen readers. See more at https://www.nomensa.com/blog/how-improve-web-accessibility-hiding-elements OR https://www.w3.org/standards/webdesign/accessibility – Julio Cesar Brito Gomes Sep 20 '21 at 14:40
20

The accepted answer above is great but this slight tweak to the fiddle from Joeytje50 allows the check-boxes to be tabbed to.

Using opacity 0 instead of display none means the checkbox is still tabbable and hence accessible by keyboard.

Position absolute places the input checkbox top left of the drawn box meaning your formatting stays neat.

input[type="checkbox"] {
    opacity: 0;
    position: absolute;
}
input[type="checkbox"] + label {
    text-align:center;
    cursor:pointer;
}
input[type="checkbox"]:focus + label {
    background-color: #ddd;
}
input[type="checkbox"] + label div {
    display:inline-block;
    line-height: 16px;
    font-size: 12px;
    height: 16px;
    width: 16px;
    margin:-0px 4px 0 0;
    border: 1px solid black;
    color: transparent;
}
input[type="checkbox"]:checked + label div {
    color: black;
}
<input type="checkbox" id="c1" name="cc" />
<label for="c1">
    <div>&#x2714;</div>Check Box 1<br />
</label>
<input type="checkbox" id="c12" name="cc" />
<label for="c12">
    <div>&#x2714;</div>Check Box 2<br />
</label>
icc97
  • 11,395
  • 8
  • 76
  • 90
Lee Chase
  • 228
  • 2
  • 5
  • Position absolute will mess up your scrolling unless the container is position relative – Jamie Pate Jun 18 '15 at 22:39
  • 1
    I quite liked this solution - so I created a [forked fiddle](http://jsfiddle.net/icc97/3tgo3yq4/) and added a bit of [material bootswatch](http://bootswatch.com/paper/) styling to the checkboxes (that material bootswatch doesn't support firefox - hence why I came searching) – icc97 Aug 07 '16 at 16:29
9

This tutsplus tutorial solved my question.

input[type="checkbox"] {
  display:none;
}
 
input[type="checkbox"] + label span {
  display:inline-block;
  width:19px;
  height:19px;
  margin:-1px 4px 0 0;
  vertical-align:middle;
  background:url(https://cdn.tutsplus.com/webdesign/uploads/legacy/tuts/391_checkboxes/check_radio_sheet.png) left top no-repeat;
  cursor:pointer;
}
input[type="checkbox"]:checked + label span {
  background:url(https://cdn.tutsplus.com/webdesign/uploads/legacy/tuts/391_checkboxes/check_radio_sheet.png) -19px top no-repeat;
}
<input type="checkbox" id="c1" name="cc" />
<label for="c1"><span></span>Check Box 1</label>
icc97
  • 11,395
  • 8
  • 76
  • 90
jacobnollette
  • 524
  • 1
  • 4
  • 13
  • 3
    N.B. [Link only answers are discouraged](http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers) as if the link disappears then the answer becomes useless - I will edit this answer to add in the relevant HTML + CSS – icc97 Aug 07 '16 at 15:58
4

A cleaner solution IMHO that uses pure css to redraw the elements.

Codepen

                input[type="checkbox"] {
            opacity: 0;
            position: absolute;
        }

        input[type="checkbox"] ~ label:before {
          content: '';
          display: inline-block;
          cursor: pointer;
          ...
          border: 3px solid #999;
          border-radius: 2px;
          transition: .3s;
        }

        input[type="checkbox"]:checked ~ label:before {
          background: #333;
        }
Scott Romack
  • 687
  • 5
  • 12
  • This *almost* works. If you don't use `

    ` tags to separate each item, you're actually checking an individual item plus all the items that follow. I'm don't have a solution, but it even checks all the radio buttons that follow.
    – user2225804 Sep 27 '19 at 15:47