171

How can I change checkbox (input) border's style? I've put border:1px solid #1e5180 upon it, but in FireFox 3.5, nothing happens!

Jørn Schou-Rode
  • 37,718
  • 15
  • 88
  • 122
Ricky
  • 34,377
  • 39
  • 91
  • 131

13 Answers13

256

I suggest using "outline" instead of "border". For example: outline: 1px solid #1e5180.

kapa
  • 77,694
  • 21
  • 158
  • 175
Greg
  • 2,571
  • 2
  • 14
  • 2
  • 5
    outline is very good, and it works for all input and select boxes, making this useful for ".error" classes. – SztupY Oct 03 '11 at 14:42
  • 2
    You may need to add `!important` to your css when using outline. I was testing this in Firefox 12.0 and without !important the outline would vanish for as long as I was clicking the checkbox. – Weezle May 16 '12 at 20:18
  • 3
    This is a great alternative, but the problem of the outline is that in IE7 it doesnt works!! – Yises Jul 03 '12 at 08:29
  • 24
    @Yises You have to worry about IE7? Yikes, I'm sorry. – theblang Dec 07 '12 at 18:42
  • @Weezle, not sure if that was in your case, but it may be that `input:active` uses the `outline` to display the dotted frame. – TWiStErRob Jan 23 '14 at 22:37
  • 1
    This is probably the best and most appropriate answer when dealing with simple checkboxes. If only someone could bump it up as the correct answer. – Jester Feb 22 '18 at 19:21
  • This is an excellent workaround. On the handful of browsers and devices I've tested on, it has the desired effect. – John Riggs Apr 05 '20 at 14:42
  • 3
    It does not aligned with corner radius checkbox – Lahiru Pinto Aug 27 '21 at 09:59
85

You should use

-moz-appearance:none;
-webkit-appearance:none;
-o-appearance:none;

Then you get rid of the default checkbox image/style and can style it. Anyway a border will still be there in Firefox

Oliver Salzburg
  • 21,652
  • 20
  • 93
  • 138
Valerij
  • 27,090
  • 1
  • 26
  • 42
  • 2
    Opera lets you style checkboxes without any extra hackery - I would leave off the -o-appearance style. -moz-appearance and -webkit-appearance are great, though. – Neall Oct 06 '10 at 15:18
  • 9
    Oops - spoke too soon: "-webkit-appearance: none;" seems to disable the checkbox behavior. – Neall Oct 06 '10 at 15:22
  • 6
    for me (chrome 5) it doesnt , you need to style the :checked state extra – Valerij Oct 30 '10 at 19:07
  • 1
    appearance had never been a part of CSS standard. Do not use it. – Evgeny Aug 26 '13 at 21:21
  • wow this is awesome i'm gonna get rid of plugins. i can do anything=> | input[type=checkbox] | input[type=checkbox]:hover | input[type=checkbox]:checked | input[type=checkbox]:checked:after ... – h0mayun Aug 31 '14 at 09:12
84

If something happens in any browser I'd be surprised. This is one of those outstanding form elements that browsers tend not to let you style that much, and that people usually try to replace with javascript so they can style/code something to look and act like a checkbox.

Sofía
  • 784
  • 10
  • 24
29

You can use box shadows to fake a border:

-webkit-box-shadow: 0px 0px 0px 1px rgba(255,0,0,1);
-moz-box-shadow: 0px 0px 0px 1px rgba(255,0,0,1);
box-shadow: 0px 0px 0px 1px rgba(255,0,0,1);
Dennis Heiden
  • 757
  • 8
  • 16
  • @retrovertigo which version? – Dennis Heiden Jan 22 '19 at 10:01
  • Version 12.0.2 (14606.3.4) / latest on macOS 10.14 – retrovertigo Jan 24 '19 at 08:28
  • @retrovertigo I have tested my solution and you are right. My answer doesn't work for Safari without further modifications (like -webkit-appearance: none; ). 3 years later, I would use the solutions given by pendingfox or Adan. But I will try to extend my answer within some weeks. Thank you for your feedback. – Dennis Heiden Mar 16 '19 at 11:41
25

Here's my version that uses FontAwesome for checkbox ticker, I think FontAwesome is used by almost everybody so it's safe to assume you have it too. Not tested in IE/Edge and I don't think anyone cares.

input[type=checkbox] {
 -moz-appearance:none;
 -webkit-appearance:none;
 -o-appearance:none;
 outline: none;
 content: none; 
}

input[type=checkbox]:before {
 font-family: "FontAwesome";
    content: "\f00c";
    font-size: 15px;
    color: transparent !important;
    background: #fef2e0;
    display: block;
    width: 15px;
    height: 15px;
    border: 1px solid black;
    margin-right: 7px;
}

input[type=checkbox]:checked:before {

 color: black !important;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet"/>

<input type="checkbox">
pendingfox
  • 528
  • 6
  • 7
  • 6
    For those that don't want to use FontAwesome, you can just remove the font-family attribute and replace the content value with an actual check mark character - copy and paste this: ✓ Then, you can customize it using font-size and line-height attributes on the :before element. – Léo Muniz Mar 19 '22 at 01:19
14

Here is a pure CSS (no images) cross-browser solution based on Martin's Custom Checkboxes and Radio Buttons with CSS3 LINK: http://martinivanov.net/2012/12/21/imageless-custom-checkboxes-and-radio-buttons-with-css3-revisited/

Here is a jsFiddle: http://jsfiddle.net/DJRavine/od26wL6n/

I have tested this on the following browsers:

  • FireFox (41.0.2) (42)
  • Google Chrome (46.0.2490.80 m)
  • Opera (33.0.1990.43)
  • Internet Explorer (11.0.10240.16431 [Update Versions: 11.0.22])
  • Microsoft Edge (20.10240.16384.0)
  • Safari Mobile iPhone iOS9 (601.1.46)

label,
input[type="radio"] + span,
input[type="radio"] + span::before,
label,
input[type="checkbox"] + span,
input[type="checkbox"] + span::before
{
    display: inline-block;
    vertical-align: middle;
}
 
label *,
label *
{
    cursor: pointer;
}
 
input[type="radio"],
input[type="checkbox"]
{
    opacity: 0;
    position: absolute;
}
 
input[type="radio"] + span,
input[type="checkbox"] + span
{
    font: normal 11px/14px Arial, Sans-serif;
    color: #333;
}
 
label:hover span::before,
label:hover span::before
{
    -moz-box-shadow: 0 0 2px #ccc;
    -webkit-box-shadow: 0 0 2px #ccc;
    box-shadow: 0 0 2px #ccc;
}
 
label:hover span,
label:hover span
{
    color: #000;
}
 
input[type="radio"] + span::before,
input[type="checkbox"] + span::before
{
    content: "";
    width: 12px;
    height: 12px;
    margin: 0 4px 0 0;
    border: solid 1px #a8a8a8;
    line-height: 14px;
    text-align: center;
     
    -moz-border-radius: 100%;
    -webkit-border-radius: 100%;
    border-radius: 100%;
     
    background: #f6f6f6;
    background: -moz-radial-gradient(#f6f6f6, #dfdfdf);
    background: -webkit-radial-gradient(#f6f6f6, #dfdfdf);
    background: -ms-radial-gradient(#f6f6f6, #dfdfdf);
    background: -o-radial-gradient(#f6f6f6, #dfdfdf);
    background: radial-gradient(#f6f6f6, #dfdfdf);
}
 
input[type="radio"]:checked + span::before,
input[type="checkbox"]:checked + span::before
{
    color: #666;
}
 
input[type="radio"]:disabled + span,
input[type="checkbox"]:disabled + span
{
    cursor: default;
     
    -moz-opacity: .4;
    -webkit-opacity: .4;
    opacity: .4;
}
 
input[type="checkbox"] + span::before
{
    -moz-border-radius: 2px;
    -webkit-border-radius: 2px;
    border-radius: 2px;
}
 
input[type="radio"]:checked + span::before
{
    content: "\2022";
    font-size: 30px;
    margin-top: -1px;
}
 
input[type="checkbox"]:checked + span::before
{
    content: "\2714";
    font-size: 12px;
}



input[class="blue"] + span::before
{
    border: solid 1px blue;
    background: #B2DBFF;
    background: -moz-radial-gradient(#B2DBFF, #dfdfdf);
    background: -webkit-radial-gradient(#B2DBFF, #dfdfdf);
    background: -ms-radial-gradient(#B2DBFF, #dfdfdf);
    background: -o-radial-gradient(#B2DBFF, #dfdfdf);
    background: radial-gradient(#B2DBFF, #dfdfdf);
}
input[class="blue"]:checked + span::before
{
    color: darkblue;
}



input[class="red"] + span::before
{
    border: solid 1px red;
    background: #FF9593;
    background: -moz-radial-gradient(#FF9593, #dfdfdf);
    background: -webkit-radial-gradient(#FF9593, #dfdfdf);
    background: -ms-radial-gradient(#FF9593, #dfdfdf);
    background: -o-radial-gradient(#FF9593, #dfdfdf);
    background: radial-gradient(#FF9593, #dfdfdf);
}
input[class="red"]:checked + span::before
{
    color: darkred;
}
 <label><input type="radio" checked="checked" name="radios-01" /><span>checked radio button</span></label>
 <label><input type="radio" name="radios-01" /><span>unchecked radio button</span></label>
 <label><input type="radio" name="radios-01" disabled="disabled" /><span>disabled radio button</span></label>

<br/>

 <label><input type="radio" checked="checked" name="radios-02"  class="blue" /><span>checked radio button</span></label>
 <label><input type="radio" name="radios-02" class="blue" /><span>unchecked radio button</span></label>
 <label><input type="radio" name="radios-02" disabled="disabled" class="blue" /><span>disabled radio button</span></label>

<br/>

 <label><input type="radio" checked="checked" name="radios-03"  class="red" /><span>checked radio button</span></label>
 <label><input type="radio" name="radios-03" class="red" /><span>unchecked radio button</span></label>
 <label><input type="radio" name="radios-03" disabled="disabled" class="red" /><span>disabled radio button</span></label>

<br/>
 
<label><input type="checkbox" checked="checked" name="checkbox-01" /><span>selected checkbox</span></label>
<label><input type="checkbox" name="checkbox-02" /><span>unselected checkbox</span></label>
<label><input type="checkbox" name="checkbox-03" disabled="disabled" /><span>disabled checkbox</span></label>

<br/>
 
<label><input type="checkbox" checked="checked" name="checkbox-01" class="blue" /><span>selected checkbox</span></label>
<label><input type="checkbox" name="checkbox-02" class="blue" /><span>unselected checkbox</span></label>
<label><input type="checkbox" name="checkbox-03" disabled="disabled" class="blue" /><span>disabled checkbox</span></label>

<br/>
 
<label><input type="checkbox" checked="checked" name="checkbox-01" class="red" /><span>selected checkbox</span></label>
<label><input type="checkbox" name="checkbox-02" class="red" /><span>unselected checkbox</span></label>
<label><input type="checkbox" name="checkbox-03" disabled="disabled" class="red" /><span>disabled checkbox</span></label>
Adan Rehtla
  • 1,548
  • 2
  • 13
  • 26
10

For Firefox, Chrome and Safari, nothing happens.

For IE the border is applied outside the checkbox (not as part of the checkbox), and the "fancy" shading effect in the checkbox is gone (displayed as an oldfashioned checkbox).

For Opera the border style is actually applying the border on the checkbox element.
Opera also handles other stylings on the checkbox better than other browsers: color is applied as the color of the tick, background-color is applied as background color inside the checkbox (IE applies the background as if the checkbox was inside a <div> with background)).

Conclusion

The easiest solution is to wrap the checkbox inside a <div> like others have suggested.
If you want to completely control the appearance you will have to go with the advanced image/javascript approach, also meantiond by others.

Community
  • 1
  • 1
awe
  • 21,938
  • 6
  • 78
  • 91
  • 2
    +1 for research, but wrapping it inside a div is *not* a solution. It doesn't let you style the checkbox, it lets you style *around* the checkbox, unless you start playing with trying to hide it and paint over it which will have its own problems. –  Mar 17 '10 at 15:05
  • Well, the only browser that lets you style the checkbox itself is Opera. Wrapping it inside a div is a solution that may be good enough, but that really depends on what you want. IE actually acts like you put it in a div if you try to style the checkbox! – awe Mar 24 '10 at 07:35
10

I'm outdated I know.. But a little workaround would be to put your checkbox inside a label tag, then style the label with a border:

<label class='hasborder'><input type='checkbox' /></label>

then style the label:

.hasborder { border:1px solid #F00; }
Hussam
  • 117
  • 1
  • 2
  • 1
    Also keep in mind, the label element will check the checkbox whenever it is clicked, even if the checkbox is not viewable inside of it. So on the label you can do something like `label { position: relative; overflow: hidden; width: 16px; height: 16px; border: 1px solid #0f0; }` and then `label > input[type=checkbox] { position: absolute; left: -999px; }` This will let you custom style your own checkbox and the original checkbox will still get checked/unchecked but the user won't see it. They will only see your custom checkbox. – Gavin May 29 '15 at 05:30
  • 1
    Forgot to add, then you can use selectors like `:hover` and `:checked` to style other states of your custom checkbox. – Gavin May 29 '15 at 05:36
7

Styling checkboxes (and many other input elements for that mater) is not really possible with pure css if you want to drastically change the visual appearance.

Your best bet is to implement something like jqTransform does which actually replaces you inputs with images and applies javascript behaviour to it to mimic a checkbox (or other element for that matter)

ChrisR
  • 14,370
  • 16
  • 70
  • 107
4

No, you still can't style the checkbox itself, but I (finally) figured out how to style an illusion while keeping the functionality of clicking a checkbox. It means that you can toggle it even if the cursor isn't perfectly still without risking selecting text or triggering drag-and-drop!

The example is using a span "button" as well as some text in a label, but it gives you the idea of how you can make the checkbox invisible and draw anything behind it.

This solution probably also fits radio buttons.

The following works in IE9, FF30.0 and Chrome 40.0.2214.91 and is just a basic example. You can still use it in combination with background images and pseudo-elements.

http://jsfiddle.net/o0xo13yL/1/

label {
    display: inline-block;
    position: relative; /* needed for checkbox absolute positioning */
    background-color: #eee;
    padding: .5rem;
    border: 1px solid #000;
    border-radius: .375rem;
    font-family: "Courier New";
    font-size: 1rem;
    line-height: 1rem;
}

label > input[type="checkbox"] {
    display: block;
    position: absolute; /* remove it from the flow */
    width: 100%;
    height: 100%;
    margin: -.5rem; /* negative the padding of label to cover the "button" */
    cursor: pointer;
    opacity: 0; /* make it transparent */
    z-index: 666; /* place it on top of everything else */
}

label > input[type="checkbox"] + span {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    border: 1px solid #000;
    margin-right: .5rem;
}

label > input[type="checkbox"]:checked + span {
    background-color: #666;
}
<label>
    <input type="checkbox" />
    <span>&nbsp;</span>Label text
</label>
corn on the cob
  • 2,093
  • 3
  • 18
  • 29
LGT
  • 4,957
  • 1
  • 21
  • 22
3

<!DOCTYPE html>
<html>
<head>
<style> 

.abc123
{
 -webkit-appearance:none;
    width: 14px;
    height: 14px;
    display: inline-block;
    background: #FFFFFF;
 border: 1px solid rgba(220,220,225,1);
}
.abc123:after {
  content: "";
  display: inline-block;
  position: relative;
  top: -3px;
  left: 4px;
  width: 3px;
  height: 5px;
  border-bottom: 1px solid #fff;
  border-right: 1px solid #fff;
  -webkit-transform: rotate(45deg);
}

input[type=checkbox]:checked   {
    background: #327DFF;
    outline: none;
    border: 1px solid rgba(50,125,255,1);
}
input:focus,input:active {
 outline: none;
}

input:hover {
   border: 1px solid rgba(50,125,255,1);
}

</style>
</head>
<body>

<input class="abc123" type="checkbox"></input>


</body>
</html>
KeepLearn
  • 41
  • 2
2

Here is a simple way (to use before or after pseudo elements / classes):

input[type=checkbox] {
    position: relative;
}

input[type=checkbox]:after {
    position: absolute;
    top: 0;
    left: 0;
    /* Above three lines allow the checkbox:after position at checkbox's position */
    content: '';
    width: 32px;
    height: 32px;
    z-index: 1; /* This allows the after overlap the checkbox */
    /* Anything you want */
}
Alex Fang
  • 95
  • 1
  • 2
  • I think this is a smart way to restyle your checkbox and anything like this. – Alex Fang Jan 13 '15 at 04:45
  • 3
    Not working on Firefox and IE. More importantly, it's an **incorrect** implementation of Chrome, because [**void elements**](http://www.w3.org/TR/html5/syntax.html#elements-0) are NOT allowed to have any contents. – Leo Jan 13 '15 at 05:37
  • Leo, you're misinterpreting the term "contents", all it says is those void elements can't have content in between because there's no closing tag. for example content has a closing tag so there can be a content between those tags. but input does not have the closing tag so it can't have the contents by principle. On the other hand, Pseudo-elements have a property called "content" which is allowed to be used everywhere. – pendingfox Oct 06 '18 at 22:47
2

It's actually just two things you have to do

outline: 1px solid #63DDCF
border: none !important;
ahsan mukhtar
  • 423
  • 7
  • 21
  • This is easy way, the same can be achieved with box-shadow or pseudo elements but this is the simplest way. – Shnigi Apr 14 '23 at 08:08