By One Crayon


2008-11-20 18:02:01 8 Comments

This is one of the minor CSS problems that plagues me constantly. How do folks around Stack Overflow vertically align checkboxes and their labels consistently cross-browser? Whenever I align them correctly in Safari (usually using vertical-align: baseline on the input), they're completely off in Firefox and IE. Fix it in Firefox, and Safari and IE are inevitably messed up. I waste time on this every time I code a form.

Here's the standard code that I work with:

<form>
    <div>
        <label><input type="checkbox" /> Label text</label>
    </div>
</form>

I usually use Eric Meyer's reset, so form elements are relatively clean of overrides. Looking forward to any tips or tricks that you have to offer!

30 comments

@Patrick 2013-04-17 14:46:43

I have not completely tested my solution, but it seems to work great.

My HTML is simply:

<label class="checkbox"><input type="checkbox" value="0000">0000 - 0100</label>

I then set all checkboxes to 24px for both height and width. To make the text aligned I make the label's line-height also 24px and assign vertical-align: top; like so:

EDIT: After IE testing I added vertical-align: bottom; to the input and changed the label's CSS. You may find you need a conditional IE css case to sort out padding - but the text and box are inline.

input[type="checkbox"] {
    width: 24px;
    height: 24px;
    vertical-align: bottom;
}
label.checkbox {
    vertical-align: top;
    line-height: 24px;
    margin: 2px 0;
    display: block;
    height: 24px;
}
<label class="checkbox"><input type="checkbox" value="0000">0000 - 0100</label>
<label class="checkbox"><input type="checkbox" value="0100">0100 - 0200</label>
<label class="checkbox"><input type="checkbox" value="0200">0200 - 0300</label>
<label class="checkbox"><input type="checkbox" value="0300">0300 - 0400</label>

If anyone finds that this doesn't work, please kindly let me know. Here is it in action (in Chrome and IE - apologies as screenshots were taken on retina and using parallels for IE):

screenshot of checkboxes: Chrome screenshot of checkboxes: IE

@YakovL 2019-09-26 16:06:30

This is quite old, but since you asked to let you know, this doesn't work well in FireFox (checkboxes are above the baseline). You may be interested in a detailed explanation I've posted

@MusikAnimal 2013-08-19 21:38:53

The chosen answer with 400+ upvotes did not work for me in Chrome 28 OSX, probably because it wasn't tested in OSX or that it did work in whatever was around in 2008 when this question was answered.

The times have changed, and new CSS3 solutions are now feasible. My solution uses pseudoelements to create a custom checkbox. So the stipulations (pros or cons, however you look at it) are as follows:

  • Only works in modern browsers (FF3.6+, IE9+, Chrome, Safari)
  • Relies on a custom designed checkbox, that will be rendered exactly the same in every browser/OS. Here I've just chosen some simple colors, but you could always add linear gradients and such to give it more of a bang.
  • Is geared to a certain font/font size, which if changed, you'd simply change the positioning and size of the checkbox to make it appear vertically aligned. If tweaked correctly, the end result should still be near to exactly the same in all browser / operating systems.
  • No vertical-alignment properties, no floats
  • Must use the provided markup in my example, it will not work if structured like the question, however, the layout will essentially look the same. If you want to move things around, you'll have to also move the associated CSS

div.checkbox {
    position: relative;
    font-family: Arial;
    font-size: 13px;
}
label {
    position: relative;
    padding-left: 16px;
}
label::before {
    content :"";
    display: inline-block;
    width: 10px;
    height: 10px;
    background-color: white;
    border: solid 1px #9C9C9C;
    position: absolute;
    top: 1px;
    left: 0px;
}
label::after {
    content:"";
    width: 8px;
    height: 8px;
    background-color: #666666;
    position: absolute;
    left: 2px;
    top: 3px;
    display: none;
}
input[type=checkbox] {
    visibility: hidden;
    position: absolute;
}
input[type=checkbox]:checked + label::after {
    display: block;
}
input[type=checkbox]:active + label::before {
    background-color: #DDDDDD;
}
<form>
    <div class="checkbox">
        <input id="check_me" type=checkbox />
        <label for="check_me">Label for checkbox</label>
    </div>
</form>

This solution hides the checkbox, and adds and styles pseudoelements to the label to create the visible checkbox. Because the label is tied to the hidden checkbox, the input field will still get updated and the value will be submitted with the form.

And if you're interested, here's my take on radio buttons: http://jsfiddle.net/DtKrV/2/

Hope someone finds this useful!

@Carlo Pires 2011-09-01 22:31:07

<form>
    <div>
        <label style="display: inline-block">
            <input style="vertical-align: middle" type="checkbox" />
            <span style="vertical-align: middle">Label text</span>
         </label>
    </div>
</form>

The trick is to use vertical-align only in table cells or inline-block if using label tag.

@gidzior 2013-11-21 09:31:41

I think this is the easiest way

input {
    position: relative;
    top: 1px;
}
<form>
    <div>
        <label><input type="checkbox" /> Label text</label>
    </div>
<form>

@JonSnow 2015-04-29 13:58:38

the question is: does it work well in all browsers? ;-)

@YakovL 2019-06-12 09:05:25

Let's finally take a look at the source of the problem

The checkboxes are rendered using images (one may set custom ones via CSS). Here is an (unchecked) checkbox in FireFox, highlighted with DOM inspector:

it's just a square

And here's the same unstyled checkbox in Chrome:

it's an uncentered square with "margins" on the right and on the bottom

You can see the margin (orange); padding is not present (would be shown green). So what's this pseudo-margin on the right and on the bottom of the checkbox? These are parts of the image used for the checkbox. That's why using just vertical-align: middle doesn't really suffice and that's the source of the cross-browser problems.

So what can we do about this?

One obvious option is – replace the images! Fortunately, one can do this via CSS and replace those with external images, base64 (in-CSS) images, in-CSS svg or just pseudo-elements. It's a robust (cross-browser!) approach, and here's an example of such adjustment stolen from this question:

.checkbox-custom {
  opacity: 0;
  position: absolute;
}
.checkbox-custom,
.checkbox-custom-label {
  display: inline-block;
  vertical-align: middle;
  margin: 5px;
  cursor: pointer;
}
.checkbox-custom + .checkbox-custom-label:before {
  content: '';
  display: inline-block;
  background: #fff;
  border-radius: 5px;
  border: 2px solid #ddd;
  vertical-align: middle;
  width: 10px;
  height: 10px;
  padding: 2px;
  margin-right: 10px;
  text-align: center;
}
.checkbox-custom:checked + .checkbox-custom-label:before {
  width: 1px;
  height: 5px;
  border: solid blue;
  border-width: 0 3px 3px 0;
  transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  border-radius: 0px;
  margin: 0px 15px 5px 5px;
}
<div>
  <input id="checkbox-1" class="checkbox-custom" name="checkbox-1" type="checkbox">
  <label for="checkbox-1" class="checkbox-custom-label">First Choice</label>
</div>
<div>
  <input id="checkbox-2" class="checkbox-custom" name="checkbox-2" type="checkbox">
  <label for="checkbox-2" class="checkbox-custom-label">Second Choice</label>
</div>

You may want to read some more in-depth articles about such styling like some listed here; it's out of scope of this answer.

Ok, still what about no-custom-images-or-pseudo-elements solution?

TL;DR: looks like this won't work, use custom checkbox instead

First, let's notice that if in other browsers those pseudo-margins inside checkbox icon were arbitrary, there were no consistent solution. To build one, we have to explore the anatomy of such images in existing browsers.

So what browsers do have the pseudo-margins in checkboxes? I've checked out Chrome 75, Vivaldi 2.5 (Chromium-based), FireFox 54 (don't ask why such outdated), IE 11, Edge 42, Safari ?? (borrowed one for a minute, forgot to check out the version). Only Chrome and Vivaldi has such pseudo-margins (I suspect all Chromium-based browsers as well, like Opera).

What's the size of those pseudo-margins? To figure this out one can use a zoomed checkbox:

input {
  zoom: 10;
  box-shadow: 0 0 1px inset #999;
}
<input type=checkbox>

my result is ~7% of width/height and hence 0.9-1.0px in absolute units. The accuracy may be questioned, though: try different values of zoom for the checkbox. In my tests in both Chrome and Vivaldi the relative size of the pseudo-margin is very different at zoom values 10, 20 and at values 11-19 (??):

for zoom = 10 it's 7% while for zoom = 11 it's almost twice that value

scale seems to be more consistent:

input {
  transform: scale(10) translate(50%, 50%);
  box-shadow: 0 0 1px inset #999;
}
<input type=checkbox>

so probably ~14% and 2px are the correct values.

Now that we know (?) the size of the pseudo-margin, let's note this is not enough. Are the sizes of the checkbox icons the same for all browsers? Alas! Here's what DOM inspector shows for unstyled checkboxes:

  • FireFox: 13.3px
  • Chromium-based: 12.8px for the whole thing, hence 12.8 (100% - 14%) = 11px for what is visually perceived as checkbox
  • IE 11, Edge: 13px
  • Safari: n/a (these should be compared on the same screen, I believe)

Now before we discuss any solutions or tricks, let's ask: what is a correct alignment? What are we trying to achieve? To certain point it's a matter of taste, but basically I can think of the following "nice" alignments' aspects:

text and checkbox on the same baseline (I deliberately don't adjust checkbox size here):

enter image description here

or have same middle line in terms of lowercase letters:

enter image description here

or same middle line in terms of capital letters (it's easier to see the difference for different font size):

enter image description here

and also we have to decide whether the size of the checkbox should be equal to the height of a lowercase letter, a capital letter or something else (bigger, smaller or between lowercase and capital).

For this discussion let's call an alignment nice if the checkbox is on the same baseline as the text and has the size of a capital letter (a highly arguable choice):

enter image description here

Now what tools do we have to:

  1. adjust checkbox size
  2. recognize Chromium with its pseudo-margined checkbox and set specific styles
  3. adjust checkbox/label vertical alignment

?

  1. Regarding the checkbox size adjustment: there are width, height, size, zoom, scale (have I missed something?). zoom and scale don't allow to set absolute size, so they may help only with adjusting to text size, not set cross-browser size (unless we can write browser-specific rules). size doesn't work with Chrome (did it work with old IE? anyway, it's not that interesting). width and height work in Chrome and other browsers, so we can set a common size, but again, in Chrome it sets the size of the whole image, not the checkbox itself. Note: it is minimum(width, height) which defines a checkbox's size (if width ≠ height, the area outside checkbox square is added to "pseudo-margin").

    An unfortunate thing is, the pseudo-margins in Chrome checkbox are not set to zero for any width and heights, as far as I can see.

  2. I'm afraid there's no reliable CSS-only method these days.

  3. Let's consider vertical alignment. vertical-align can't give consistent results when set to middle or baseline because of the Chrome's pseudo-margin, the only real option to get the same "coordinate system" for all the browsers is to align label and input to the top:

    comparing vertical-align: top and bottom

    (on the picture: vertical-align: top, bottom and bottom without box-shadow)

So what result do we get from this?

input[type="checkbox"] {
    height: 0.95em;
    width: 0.95em;
}
label, input {
    vertical-align: top;
}
<label><input type="checkbox">label</label>

The snippet above works with Chrome (Chromium-based browsers), but other browsers require a smaller size of the checkbox. It seems to be impossible to adjust both the size and vertical alignment in a way that works around Chromium's checkbox image quirk. My final suggestion is: use custom checkboxes instead – and you'll avoid frustration :)

@Nathan Bowers 2009-01-30 09:12:46

Sometimes vertical-align needs two inline (span, label, input, etc...) elements next to each other to work properly. The following checkboxes are properly vertically centered in IE, Safari, FF, and Chrome, even if the text size is very small or large.

They all float next to each other on the same line, but the nowrap means that the whole label text always stays next to the checkbox.

The downside is the extra meaningless SPAN tags.

.checkboxes label {
  display: inline-block;
  padding-right: 10px;
  white-space: nowrap;
}
.checkboxes input {
  vertical-align: middle;
}
.checkboxes label span {
  vertical-align: middle;
}
<form>
  <div class="checkboxes">
    <label for="x"><input type="checkbox" id="x" /> <span>Label text x</span></label>
    <label for="y"><input type="checkbox" id="y" /> <span>Label text y</span></label>
    <label for="z"><input type="checkbox" id="z" /> <span>Label text z</span></label>
  </div>
</form>

Now, if you had a very long label text that needed to wrap without wrapping under the checkbox, you'd use padding and negative text indent on the label elements:

.checkboxes label {
  display: block;
  padding-right: 10px;
  padding-left: 22px;
  text-indent: -22px;
}
.checkboxes input {
  vertical-align: middle;
}
.checkboxes label span {
  vertical-align: middle;
}
<form>
  <div class="checkboxes">
    <label for="x"><input type="checkbox" id="x" /> <span>Label text x so long that it will probably wrap so let's see how it goes with the proposed CSS (expected: two lines are aligned nicely)</span></label>
    <label for="y"><input type="checkbox" id="y" /> <span>Label text y</span></label>
    <label for="z"><input type="checkbox" id="z" /> <span>Label text z</span></label>
  </div>
</form>

@William Gross 2010-08-12 14:42:04

Thanks! The "vertical-align: middle" on both the input and the span worked great for me.

@PHPst 2013-12-18 14:18:32

display: block; float: left; seems to be redundant

@parliament 2014-11-05 17:43:20

so is it not okay to omit for attribute if using the span? (like One Crayon commented in accepted answer) w3.org/TR/html401/interact/forms.html#h-17.9.1

@Tommy Sørensen 2016-01-10 22:02:24

You don't have to use a for attribute when you have the input inside the label. It work's without it.

@Tim 2016-01-29 13:34:07

This should be the accepted answer by my opinion. There is no tweaking required.

@Jason C 2017-06-05 00:17:49

Awesome and confirmed still works on Chrome 58 (Windows) (unlike current top answer).

@tom 2018-11-18 23:26:49

You don't even need the span. It's enough to put a vertical-align: middle on the checkbox.

@Epirocks 2019-05-30 16:00:36

vertical-align: middle; on both label and checkbox worked out of the box for me. Nothing else needed

@YakovL 2019-06-09 12:01:18

I've edited the answer to remove the redundant float: left bit like @PHPst has suggested. If you not a single problem about it, please comment. The display bits are only needed here to align the 3 examples in a row/column

@vladiim 2019-01-31 00:27:57

I found the only way I could line them up was using position absolute for the input. Playing around with input's top variable got the result I wanted.

div {
  clear:    both;
  float:    none;
  position: relative;
}

input {
  left:     5px;
  position: absolute;
  top:      3px;
}

label {
  display:     block;
  margin-left: 20px;
}

@ 2009-04-05 19:41:57

Working off of One Crayon's solution, I have something that works for me and is simpler:

.font2 {font-family:Arial; font-size:32px} /* Sample font */

input[type=checkbox], input[type=radio] {
  vertical-align: middle;
  position: relative;
  bottom: 1px;
}

input[type=radio] { 
  bottom: 2px; 
} 
<label><input type="checkbox" /> Label text</label>
<p class="font2">
  <label><input type="checkbox"/> Label text</label>
</p>

Renders pixel-for-pixel the same in Safari (whose baseline I trust) and both Firefox and IE7 check out as good. It also works for various label font sizes, big and small. Now, for fixing IE's baseline on selects and inputs...


Update: (Third-Party Edit)

The proper bottom position depends on font-family and font-size! I found using bottom: .08em; for checkbox & radio elements is a good general value. I tested it in Chrome/Firefox/IE11 in windows with Arial & Calibri fonts using several small/mid/large font-sizes.

.font2, .font2 input {font-family:Arial; font-size:32px} /* Sample font */

input[type=checkbox], input[type=radio] {
  vertical-align: middle; 
  position: relative;
  bottom: .08em; /* this is a better value for different fonts! */
}
<label><input type="checkbox" /> Label text</label> 

<p class="font2">
  <label><input type="checkbox"/> Label text</label>
</p>

@One Crayon 2009-04-08 00:18:10

Just a note for others: this won't work in IE6 because it doesn't support the [type=checkbox] CSS targeting.

@HartleySan 2014-08-19 01:43:48

You can just add a class instead of using unsupported selectors if IE6 support is required.

@newman 2017-04-28 22:20:47

This one worked for me. However, instead of setting "position: relative; bottom: 1px", you can use "margin: 0 0 1px 0" to achieve the same result.

@Dylan Sharhon 2018-08-28 22:55:13

Simple solution:

<label style="display:block">
  <input style="vertical-align:middle" type="checkbox">
  <span  style="vertical-align:middle">Label</span>
</label>

Tested in Chrome, Firefox, IE9+, Safari, iOS 9+

@NinjaKC 2014-06-05 12:10:14

So I know this has been answered many times, but I feel I have a way more elegant solution than those that have been provided already. And not only 1 elegant solution, but 2 separate solutions to tickle your fancy. With that said, everything you need to know and see are contained in 2 JS Fiddle's, with comments.


Solution #1 relies on the native "Checkbox" of the given browser, though with a twist... Its contained in a div which is easier to position cross-browser, with an overflow: hidden to chop the excess of a 1px stretched checkbox (this is so you cant see the ugly borders of FF)

Simple HTML: (follow the link to review the css with comments, code block is to satisfy stackoverflow) http://jsfiddle.net/KQghJ/

<label><div class="checkbox"><input type="checkbox" /></div> Label text</label>

Solution #2 uses the "Checkbox Toggle Hack" to toggle the CSS state of a DIV, which has been properly positioned across browser, and setup with a simple sprite for the checkbox unchecked and checked states. All that is needed is to adjust the background-position with said Checkbox Toggle Hack. This, in my opinion, is the more elegant solution as you have more control over your checkboxes & radios, and can guarantee they look the same across browser.

Simple HTML: (follow the link to review the CSS with comments, code block is to satisfy StackOverflow) http://jsfiddle.net/Sx5M2/

<label><input type="checkbox" /><div class="checkbox"></div>Label text</label>

If anyone disagree's with these methods, please leave me a comment, I would love to hear some feedback on why others have not come across these solutions, or if they have, why I see no answers here regarding them? If anyone sees one of these methods fail, it would be nice to see that too, but these have been tested in the latest browsers and rely on HTML / CSS methods that are quite old, and universal as far as I have seen.

@digitalsanctum 2008-11-20 18:07:01

try vertical-align: middle

also your code seems like it should be:

<form>
    <div>
        <input id="blah" type="checkbox"><label for="blah">Label text</label>
    </div>
</form>

@One Crayon 2008-11-20 18:13:08

<label for="blah"> is only necessary if you're using something where it doesn't make sense for the label to wrap (like a textbox; I'll generally use <label for="blah">Foo</label><input id="blah" type="text" /> in that instance). With checkboxes I find it's less markup to wrap it.

@EndangeredMassa 2008-11-20 18:30:09

Not exactly true: The Label-for will allow users to click the label in order to check the checkbox, in addition to simply clicking the checkbox itself. It's quite handy for tying the two elements together.

@One Crayon 2008-11-20 18:34:32

If an input is nested inside a label, then clicking the label with activate/give focus to the input; the for attribute is solely for the case when the input is not nested.

@Armstrongest 2008-11-26 21:33:08

That's true One Crayon, but it's still good practice to use the "for" attribute, or you will have problems with some browsers that don't recognize this syntax cough IE.

@Simon_Weaver 2009-01-30 12:02:43

if you don't want your checkbox to have an ID then you need to wrap the checkbox inside the label

@Prime 2017-06-13 21:43:48

input[type=checkbox]
{
    vertical-align: middle;
} 
<input id="testCheckbox" name="testCheckbox" type="checkbox">
<label for="testCheckbox">I should align</label>

@dylanfm 2009-01-30 09:26:00

This works well for me:

fieldset {
  text-align:left;
  border:none
}
fieldset ol, fieldset ul {
  padding:0;
  list-style:none
}
fieldset li {
  padding-bottom:1.5em;
  float:none;
  clear:left
}
label {
  float:left;
  width:7em;
  margin-right:1em
}
fieldset.checkboxes li {
  clear:both;
  padding:.75em
}
fieldset.checkboxes label {
  margin:0 0 0 1em;
  width:20em
}
fieldset.checkboxes input {
  float:left
}
<form>
  <fieldset class="checkboxes">
    <ul>
      <li>
        <input type="checkbox" name="happy" value="yep" id="happy" />
        <label for="happy">Happy?</label>
      </li>
      <li>
        <input type="checkbox" name="hungry" value="yep" id="hungry" />
        <label for="hungry">Hungry?</label>
      </li>
    </ul>
  </fieldset>
</form>

@IDisposable 2009-01-31 06:45:21

bless you for using ems instead of pxs.

@Bryan A 2008-11-20 21:21:50

I usually use line height in order to adjust the vertical position of my static text:

label {
  line-height: 18px;
}
input {
  width: 13px;
  height: 18px;
  font-size: 12px;
  line-height: 12px;
}
<form>
  <div>
    <label><input type="checkbox" /> Label text</label>
  </div>
</form>

Hope that helps.

@Craig 2019-07-18 00:23:31

line-height, duh. Always forget about that one. Good job, works great.

@Waleed Eissa 2008-12-28 05:23:25

Try my solution, I tried it in IE 6, FF2 and Chrome and it renders pixel by pixel in all the three browsers.

* {
  padding: 0px;
  margin: 0px;
}
#wb {
  width: 15px;
  height: 15px;
  float: left;
}
#somelabel {
  float: left;
  padding-left: 3px;
}
<div>
  <input id="wb" type="checkbox" />
  <label for="wb" id="somelabel">Web Browser</label>
</div>

@One Crayon 2009-01-31 03:54:28

Interesting; I like the idea of floating both elements; that elegantly fixes the wrapping issue. I am attached to wrapping input with label, but that code is a heck of a lot cleaner than the solution I arrived at.

@se_pavel 2009-04-17 07:27:54

in this example the checkbox input and label should be also have property display: block and in such case they will be treated as normal DIV's that can be aligned easily

@Enrique 2011-04-17 23:58:41

this has a problem, what happens if the label doesn't fit into the available space? the label and checkbox are separated (the checkbox is up-right, and the label down-left). If you wrap the checkbox inside your label you don't have this problem.

@Alexis Wilke 2014-01-07 06:02:25

It did not work to the pixel, but it was decent enough to get things to look better on the 3 major browsers. I suppose I could have spent another hour to see that it would work better...

@One Crayon 2008-11-20 19:47:43

After over an hour of tweaking, testing, and trying different styles of markup, I think I may have a decent solution. The requirements for this particular project were:

  1. Inputs must be on their own line.
  2. Checkbox inputs need to align vertically with the label text similarly (if not identically) across all browsers.
  3. If the label text wraps, it needs to be indented (so no wrapping down underneath the checkbox).

Before I get into any explanation, I'll just give you the code:

label {
  display: block;
  padding-left: 15px;
  text-indent: -15px;
}
input {
  width: 13px;
  height: 13px;
  padding: 0;
  margin:0;
  vertical-align: bottom;
  position: relative;
  top: -1px;
  *overflow: hidden;
}
<form>
  <div>
    <label><input type="checkbox" /> Label text</label>
  </div>
</form>

Here is the working example in JSFiddle.

This code assumes that you're using a reset like Eric Meyer's that doesn't override form input margins and padding (hence putting margin and padding resets in the input CSS). Obviously in a live environment you'll probably be nesting/overriding stuff to support other input elements, but I wanted to keep things simple.

Things to note:

  • The *overflow declaration is an inline IE hack (the star-property hack). Both IE 6 and 7 will notice it, but Safari and Firefox will properly ignore it. I think it might be valid CSS, but you're still better off with conditional comments; just used it for simplicity.
  • As best I can tell, the only vertical-align statement that was consistent across browsers was vertical-align: bottom. Setting this and then relatively positioning upwards behaved almost identically in Safari, Firefox and IE with only a pixel or two of discrepancy.
  • The major problem in working with alignment is that IE sticks a bunch of mysterious space around input elements. It isn't padding or margin, and it's damned persistent. Setting a width and height on the checkbox and then overflow: hidden for some reason cuts off the extra space and allows IE's positioning to act very similarly to Safari and Firefox.
  • Depending on your text sizing, you'll no doubt need to adjust the relative positioning, width, height, and so forth to get things looking right.

Hope this helps someone else! I haven't tried this specific technique on any projects other than the one I was working on this morning, so definitely pipe up if you find something that works more consistently.

@Armstrongest 2008-11-26 21:34:52

note. You should probably put a "for" attribute on your label, to ensure it works for all browsers and text readers. ( I realize you probably left it off for simplicity)

@One Crayon 2008-11-28 17:33:00

Good grief, I hadn't realized how many people were ignorant of this: if you are wrapping the input in the label tag, the "for" attribute is unnecessary. Feel free to see for yourself: w3.org/TR/html401/interact/forms.html#h-17.9.1

@ebruchez 2009-01-30 17:54:24

I disagree with the suggestion about using conditional comments. Keep the *foobar CSS hack. That works well, is used by frameworks like YUI, and allows you to keep together what belongs together.

@Glen Solsberry 2009-01-30 20:16:49

I've seen issues with IE when wrapping the input with the label. Like, clicks on either the label or the input don't cause a cursor. ymmv...

@One Crayon 2009-01-31 03:47:11

@gms8994: are you able to reproduce the IE error, or is it anecdotal? I'd love to avoid that particular problem. :-)

@IDisposable 2009-01-31 06:46:27

You could switch all those px values for more-useful em values and have far less pain with font sizes.

@One Crayon 2009-02-06 22:23:51

@IDisposable: Since none of the pixel values are remotely affecting font sizing, I fail to see why they'd be better as ems. Unless the checkbox sizes up when font-size increases, pixels are better for that kind of positioning code.

@se_pavel 2009-04-17 07:29:52

the properties position:relative and values less than zero is seems to me too complex for everyday use - I prefer the variant stackoverflow.com/questions/306252/… with my addition in comment

@thismat 2010-05-21 09:09:29

@One Crayon: This is one of those 4am hair pulling life savers. Done it so many times before, never had luck finding this solution.

@Jeremy Kauffman 2010-07-30 00:23:34

There is a big issue with this! Since the label is a block level element, you can now click to the right of the label text and trigger radio/checkbox changes.

@Enrique 2011-04-18 00:16:45

The problem with wraping the checkbox inside the label is that you can't access this rule: input[type=checkbox]:checked+label

@Paul Calcraft 2011-04-27 06:35:01

Wrapping the checkbox in the label without the 'for' doesn't seem to work for me in IE6 (under IETester), all other browsers seem to be fine. Repro: jsfiddle.net/2Cz2y/7

@ddekany 2011-11-13 01:34:22

Didn't worked well on Android (2.3), whose browser has bigger checkboxes than other browsers, thus the indentation of the 2nd line was off.

@Jan Turoň 2012-01-14 14:26:14

@One Crayon: omitting for in label will fail in IE6

@jinglesthula 2012-03-22 19:39:36

@Enrique using adjacent sibling selector (+) doesn't work in IE lt 9 afaik, so it's a tradeoff either way. Js solutions are cringe-worthy when pure css solutions exist, but for that one, js may be the best way.

@Enrique 2012-03-23 01:28:33

@jinglesthula: no, that's not true, it works fine even in IE7 (reference.sitepoint.com/css/adjacentsiblingselector)

@Peter Hedberg 2012-07-01 14:19:11

@One Crayon: -1 on the ignorant comment. Atømix just pointed out support for all browsers, the same reason why you added the star-property hack.

@Sam Hasler 2013-03-11 14:19:38

@OneCrayon text readers can be confused by input in label: "Until browser implementors fix their accessibility support, if you want controls to be understandable to AT [assistive technology] users label controls using for and id. Do not use the control inside the label method. Do not use a combination of the 2 methods." from: blog.paciellogroup.com/2011/07/…

@MusikAnimal 2013-08-19 17:42:40

Tried this is out in Chrome 28, Mac OSX, and the checkbox is visibly lower than the text

@Ayyash 2013-12-07 13:10:48

as of dec 7, 2013, checkboxes align correctly on all browsers, with no hacks, am I mistaken?

@eflat 2013-12-13 22:30:40

Maybe other things/styles on my page caused a conflict, but I found that for IE7, I needed the property vertical-align:baseline instead of bottom.

@Phil LaNasa 2014-03-17 13:19:01

top: -4px; *top: -2px; actually worked best for me.

@Andrew 2014-07-21 02:15:43

Fantastic solution! I just changed padding-left and text-indent to 16px rather than 15px and it works perfectly.

@Hans 2014-08-01 23:20:37

Note, this doesn't appear to work in the latest versions of Chrome (I'm using v36). i.imgur.com/y9Ffxsh.png Edit: nor Firefox (v31)

@Yahreen 2015-05-18 19:00:19

Is placing the input inside the label ADA-compliant / accessible?

@Jason C 2017-06-05 00:15:09

Text is too high on Chrome 58 (Windows).

@Mike 2017-06-23 03:57:56

I was creating checkboxes through jquery and no matter what I did, the text and the checkbox would always be on separate lines. This fixed it 100%. Thank you so much. I use Firefox. Hopefully it will appear the same on other browsers, which I will find out soon enough.

@user25 2017-08-12 16:54:38

Doesn't look good, many constants, negative values... This answer stackoverflow.com/a/494922/4548520 looks much better for me (first example)

@Brandito 2018-06-04 00:51:32

Text is higher than the checkbox on Edge, Firefox, Chrome (latest versions at the time of writing) on Windows 10, atleast they're all roughly the same position across each browser, just needs tweaking.

@Bryan Willis 2016-07-24 23:53:35

Now that flexbox is supported in all modern browsers, something like this seems like an easier approach to me.

<style>
label {
  display: flex;
  align-items: center;
}
input[type=radio], input[type=checkbox]{
  flex: none;
}
</style>
<form>
  <div>
    <label><input type="checkbox" /> Label text</label>
  </div>
</form>


Here's the complete prefixed version demo:

label {
	display: -webkit-box;
	display: -webkit-flex;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-align: center;
	-webkit-align-items: center;
	-ms-flex-align: center;
	align-items: center;
}
input[type=radio], 
input[type=checkbox] {
	-webkit-box-flex: 0;
	-webkit-flex: none;
	-ms-flex: none;
	flex: none;
	margin-right: 10px; 
}
/* demo only (to show alignment) */
form {
  max-width: 200px
}
<form>
  <label>
    <input type="radio" checked>
    I am an aligned radio and label
  </label>
  <label>
      <input type="checkbox" checked>
    I am an aligned checkbox and label
  </label>
</form>

@Henrik Erlandsson 2015-09-16 14:02:16

The following gives pixel-perfect consistency across browsers, even IE9:

The approach is quite sensible, to the point of being obvious:

  1. Create an input and a label.
  2. Display them as block, so you can float them as you like.
  3. Set the height and the line-height to the same value to ensure they center and align vertically.
  4. For em measurements, to calculate the height of the elements, the browser must know the height of the font for those elements, and it must not itself be set in em measurements.

This results in a globally applicable general rule:

input, label {display:block;float:left;height:1em;line-height:1em;}

With font size adaptable per form, fieldset or element.

#myform input, #myform label {font-size:20px;}

Tested in latest Chrome, Safari, and Firefox on Mac, Windows, Iphone, and Android. And IE9.

This method is likely applicable to all input types that are not higher than one line of text. Apply a type rule to suit.

@YakovL 2019-06-28 10:25:15

hm, this does look well when the label starts with a lowercase letter, but if it starts with a capital one, it's much worse. Could you add a snippet here?

@Buzogany Laszlo 2015-02-24 19:07:55

The only perfectly working solution for me is:

input[type=checkbox], input[type=radio] {
    vertical-align: -2px;
    margin: 0;
    padding: 0;
}

Tested today in Chrome, Firefox, Opera, IE 7 and 8. Example: Fiddle

@Buzogany Laszlo 2015-11-05 14:37:46

tested in Chrome and Safari today, and working

@Frank Schwieterman 2010-05-10 22:06:09

One easy thing that seems to work well is to apply a adjust the vertical position of the checkbox with vertical-align. It will still be vary across browsers, but the solution is uncomplicated.

input {
    vertical-align: -2px;
}

Reference

@Johnny_D 2014-09-17 14:37:04

That was the smallest change among all other, which works for me in most recent versions of browsers.

@Dennis98 2015-06-14 12:38:29

That works even better than with vertical-align and position: relative because it's also working in IE9 correctly :)

@S.Serpooshan 2016-12-06 12:31:33

but it depends to font-size. for large font-sizes, it must be adjusted to higher negative values, eg: vertical-align: -6px;

@YakovL 2019-01-07 21:25:27

presumably this can work better with different fonts if set in em

@Marco Sulla 2015-07-30 10:04:29

Use simply vertical-align: sub, as pokrishka already suggested.

Fiddle

HTML Code:

<div class="checkboxes">
    <label for="check1">Test</label>
    <input id="check1" type="checkbox"></input>
</div>

CSS Code:

.checkboxes input {
    vertical-align: sub;
}

@waterplea 2014-11-06 13:59:37

I don't like relative positioning because it makes element rendered above everything else on its level (it can get on top of something if you have complex layout).

I've discovered that vertical-align: sub makes checkboxes look good enough aligned in Chrome, Firefox and Opera. Can't check Safari since I don't have MacOS and IE10 is slightly off, but I've found it to be good enough solution for me.

Another solution might be to try and make specific CSS for every browser and fine-tune it with some vertical-align in %/pixels/EMs: http://css-tricks.com/snippets/css/browser-specific-hacks/

@robsch 2018-09-27 10:58:07

Seems to work as long as the font size is not too large.

@Vladimir Kornea 2014-08-07 00:18:52

Hardcode the checkbox's height and width, remove its padding, and make its height plus vertical margins equal to the label's line-height. If the label text is inline, float the checkbox. Firefox, Chrome, and IE7+ all render the following example identically: http://www.kornea.com/css-checkbox-align

@Mariano Desanze 2014-08-08 23:49:35

Nice! But you should consider copying the HTML and CSS code in here. Answers that depends so much on an external link are discouraged. The link is still valuable to see the results, but I think showing the code in here will help you get more up votes.

@YakovL 2019-06-28 10:49:50

nope, they don't (compare in FireFox and in Chrome, in Chrome the checkboxes are above the baseline), I've explained why

@Vladimir Kornea 2019-06-29 12:27:36

The above comment is wrong, compare it yourself.

@YakovL 2019-10-27 10:20:43

Why, you claim the thing that's unsupported even with screenshots from both browsers. It is your job to provide proofs for a claim when you make one, not others' to disprove it. I did compare those and would add the screenshots, but comments don't support adding pictures; you can take a look at pictures in my answer though. This however may differ with browser versions, so providing screenshots with annotations containing browser versions would be helpful.

@Vladimir Kornea 2019-10-27 10:46:35

Visit the page I linked to in different browsers.

@YakovL 2019-11-05 15:13:21

So I did that, did you? :) Don't you see the difference? imagebin.ca/v/50stCZZGl7Ug imagebin.ca/v/50stNBiv29Ks While in FireFox they are perfectly aligned, in Chrome the checkbox is about the baseline (by the way, you can use mentions via @ if you are interested in quicker replies)

@Vladimir Kornea 2019-11-09 01:08:16

It's not often people disagree about what they see. I looked at your images at the pixel level, and they are indeed identically aligned. The only difference is that Chrome's checkbox appears to be one pixel shorter because its bottom row of pixels is lighter than the row above it (ie, what the eye sees as the bottom "border" of the checkbox is actually the second to-bottom row of pixels).

@Milche Patern 2013-07-29 21:55:33

For consistency with form fields across browsers we use : box-sizing: border-box

button, checkbox, input, radio, textarea, submit, reset, search, any-form-field {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

@user966939 2012-11-23 21:21:19

I found out one way to do it that gives the same result in almost all browsers. At the very least up-to-date browsers. It works in Firefox, Chrome, Safari, Opera. In IE it will just look almost as if there were no rules applied for inputs or labels (i.e., it'll still have the label a few pixels below the input), so I think it's excusable.

HTML

<label class="boxfix"><input type="radio">Label</label>

CSS

.boxfix {
    vertical-align: bottom;
}
.boxfix input {
    margin: 0;
    vertical-align: bottom;
    position: relative;
    top: 1.999px; /* the inputs are slightly more centered in IE at 1px (they don't interpret the .999 here), and Opera will round it to 2px with three decimals */
}

@Web Designer cum Promoter 2013-11-20 10:21:02

try this code

input[type="checkbox"] {
    -moz-appearance: checkbox;
    -webkit-appearance: checkbox;
    margin-left:3px;
    border:0;
    vertical-align: middle;
    top: -1px;
    bottom: 1px;
    *overflow: hidden;
    box-sizing: border-box; /* 1 */
    *height: 13px; /* Removes excess padding in IE 7 */
    *width: 13px;
    background: #fff;
}

@Geoff Kendall 2013-05-29 22:40:40

Maybe some folk are making the same mistake I did? Which was... I had set a width for the input boxes, because they were mostly of type 'text' , but then forgotten to over-ride that width for checkboxes - so my checkbox was trying to occupy a lot of excess width and so it was tough to align a label beside it.

.checkboxlabel {
    width: 100%;
    vertical-align: middle;
}
.checkbox {
    width: 20px !important;
}
<label for='acheckbox' class='checkboxlabel'>
    <input name="acheckbox" id='acheckbox' type="checkbox" class='checkbox'>Contact me</label>

Gives clickable labels and and proper alignment as far back as IE6 (using a class selector) and in late versions of Firefox, Safari and Chrome

@Bob Fanger 2010-10-18 13:28:09

position: relative; has some issues in IE with z-index and animations like jQuery's slideUp/slideDown.

CSS:

input[type=checkbox], input[type=radio] {
    vertical-align: baseline;
    position: relative;
    top: 3px;
    margin: 0 3px 0 0;
    padding: 0px;
}
input.ie7[type=checkbox], input.ie7[type=radio] {
    vertical-align: middle;
    position: static;
    margin-bottom: -2px;
    height: 13px;
    width: 13px;
}

jQuery:

$(document).ready(function () {
    if ($.browser.msie && $.browser.version <= 7) {
        $('input[type=checkbox]').addClass('ie7');
        $('input[type=radio]').addClass('ie7');
    }
});

The styling probably needs tweaks depending on the font-size used in <label>

PS:
I use ie7js to make the css work in IE6.

@albert 2010-12-30 20:49:55

<fieldset class="checks">
    <legend>checks for whatevers</legend>
    <input type="" id="x" />
    <label for="x">Label</label>
    <input type="" id="y" />
    <label for="y">Label</label>
    <input type="" id="z" />
    <label for="z">Label</label>
</fieldset>

You should wrap form controls grouped together in their own fieldsets anyways, here, it plays the wrappa. set input/label do display:block, input float left, label float right, set your widths, control spacing with left/right margins, align label text accordingly.

so

fieldset.checks {
    width:200px
}
.checks input, .checks label {
    display:block;
}
.checks input {
    float:right;
    width:10px;
    margin-right:5px
}
.checks label {
    float:left;
    width:180px;
    margin-left:5px;
    text-align:left;
    text-indent:5px
}

you probably need to set border, outline and line-height on both as well for cross-browser/media solutions.

@Jeff 2009-03-19 17:12:35

Yay thanks! This too has been driving me nuts forever.

In my particular case, this worked for me:

input {
    width: 13px;
    height: 13px;
    padding: 0;
    margin:0;
    vertical-align: top;
    position: relative;
    *top: 1px;
    *overflow: hidden;
}
label {
    display: block;
    padding: 0;
    padding-left: 15px;
    text-indent: -15px;
    border: 0px solid;
    margin-left: 5px;
    vertical-align: top;
}

I am using the reset.css which might explain some of the differences, but this seems to work well for me.

Related Questions

Sponsored Content

65 Answered Questions

[SOLVED] How to check whether a checkbox is checked in jQuery?

11 Answered Questions

[SOLVED] How to create a checkbox with a clickable label?

32 Answered Questions

[SOLVED] How to make a div 100% height of the browser window

  • 2009-10-15 21:18:43
  • mike
  • 1871274 View
  • 2023 Score
  • 32 Answer
  • Tags:   html css height

71 Answered Questions

[SOLVED] How do you disable browser Autocomplete on web form field / input tag?

45 Answered Questions

[SOLVED] How to vertically center a div for all browsers?

35 Answered Questions

[SOLVED] How to vertically align an image inside a div

30 Answered Questions

[SOLVED] How do I vertically align text in a div?

25 Answered Questions

[SOLVED] How to align content of a div to the bottom

27 Answered Questions

[SOLVED] How to align a <div> to the middle (horizontally/width) of the page

6 Answered Questions

[SOLVED] Vertical align checkbox / label pairs

Sponsored Content