13
All,

I have a checkbox that I applied the following CSS style to:

-webkit-appearance: none;

This same code is on some text fields I have and these still continue to work just fine. Why is this functionality causing the checkbox to not allowed to be checked?

I like the styling of the checkbox this way but still need the functionality to work. If I change the code to:

-webkit-appearance: checkbox;

It displays the standard checkbox. Any ideas? Here is a demonstration:

/* http://jsfiddle.net/VWC76/ */

input[type='checkbox'] {
  height: 20px;
  border: 1px solid #B5B7B8;
  font: 14px/26px 'pt-sans', 'Helvetica Neue', Arial, Helvetica, Geneva, sans-serif;
  padding: 7px 7px 7px 12px;
  /*margin:0 0 30px 0;*/
  
  background: #FFF;
  border: 1px solid #d5d5d6;
  outline: none;
  color: #96999D;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  
  -webkit-appearance: none;
  -webkit-font-smoothing: antialiased;
  border-radius: 4px;
  transition: all 0.15s;
}

input[type=checkbox]:focus {
  border-color: #ACACB8;
  color: #2E3236;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18)!important;
}

div {
    border: 1px inset #ccc;
    border-radius: 7px;
    margin: 1em;
    padding: 1em;
}

#webkitCheckbox {
    -webkit-appearance: checkbox;
}
<div>
    <label>
        <input type="checkbox" />
        <span>This has <code>-webkit-appearance: none;</code></span>
    </label>
</div>

<div>
    <label>
        <input type="checkbox" id="webkitCheckbox" />
        <span>This has <code>-webkit-appearance: checkbox;</code></span>
    </label>
</div>
Dai
  • 141,631
  • 28
  • 261
  • 374
user1048676
  • 9,756
  • 26
  • 83
  • 120
  • 4
    When you set it to none, it disables the standard appearance (checkbox). You could specify your inputs by just saying `input[type=text] { -webkit-appearance: none; }`. – Chad Nov 18 '13 at 20:52
  • 2
    I don't want to display the standard appearance checkbox. I want to display my custom version with the CSS applied but when I do that, I lose the functionality of the checkbox. – user1048676 Nov 18 '13 at 20:57

4 Answers4

22

You just nuked all styles of checkbox on WebKit, so yes you can't see whether they're checked or not (they still are, it just isn't visible to us sighted people without a screen reader).

You need to style the checked state with the :checked pseudo: http://jsfiddle.net/VWC76/450/

input[type=checkbox]:checked {
    background-color: red;
    /* or whatever styles you want depending on your design */
    /* be as obvious as possible that it's a checkbox and that it's checked! */
}

EDIT:

EDIT 2:

  • in the fiddle demo, adding focusable elements before and after checkbox to show it works with keyboard (just click on the first occurence of "Test" and then tab tab space tab). It lacks any visual cue that checkbox/label is focused which is a bad thing (it's a demo). Best seen on Chrome which is a worse thing :p (you need Autoprefixer. Try on Codepen)
FelipeAls
  • 21,711
  • 8
  • 54
  • 74
  • Lol. I'm here cause I too, without realizing, pressed the big red launch nuke button. Luckily I didn't cause any damage =P – Peege151 Sep 10 '16 at 04:18
  • The example is not accessible. It's completely unusable with a keyboard. – Webveloper Sep 10 '17 at 22:12
  • @Webveloper Only in JSFiddle (it's a complex mix of iframes,hard to use with a keyboard except if you click in the correct iframe…) or anywhere? I added focusable elements and an edit explanation: it works. – FelipeAls Mar 09 '18 at 09:08
5

You need to add a input[type=checkbox]:checked

input[type=checkbox]:checked {
   background: #BADA55;
}

If this is what you're looking for?

Ace
  • 969
  • 4
  • 10
3

Disabling the appearance removes the checked appearance too. You also need to add styles to define how the checkbox will appear when checked.

input[type='checkbox']:checked
{
    position:relative;
}
input[type='checkbox']:checked:before
{
    content:'';
    display:block;
    width:17px;
    height:16px;
    position:absolute;
    top:1px;
    left:1px;
    background:none #ACACB8;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    border-radius: 3px;
    opacity:0.5;
}

Check out the fiddle below for an example:

http://jsfiddle.net/8n8hM/

Neaox
  • 1,933
  • 3
  • 18
  • 29
  • 3
    Beware that `:before` pseudo on an `input` works *for now* and may not work in a future (or not so future) version of Blink/WebKit. See [this answer](http://stackoverflow.com/a/4660434/137626) for reference and also Jukka K. Korpela's answer. I'd make sure that the checked input gets some style, a style hidden by the one set by `:before` – FelipeAls Nov 18 '13 at 21:08
1

The best way to personnalize checkbox or radio button that works cross browser is by using label that you set for your checkbox. In your css, you hide your checkbox and you add any style you want for the label.

input[type='checkbox'] {
    outline: 0;
    user-select: none;
    display: inline-block;
    position: absolute;
    opacity: 0;
}
input[type='checkbox'] + label {
    display:inline-block;
    width:20px;
    height:20px;
    background-color:blue
}
input[type='checkbox']:checked + label {
    background-color:red
}
<input id="myChk" type="checkbox" />
<label for="myChk">&nbsp</label>

See this jsfiddle.

service-paradis
  • 3,333
  • 4
  • 34
  • 43
  • by current browser standards, for the protection of the user, any input box rendered invisible, off screen, or inaccessible, is not submitted with the form values. This example removes the checkbox from display, and removes its value from submission. – ppostma1 Dec 19 '18 at 17:03
  • Never had problem using this. Do you have any official links? – service-paradis Dec 19 '18 at 18:04