views:

2406

answers:

4

Assuming the following markup:

<fieldset>
    <legend>Radio Buttons</legend>
    <ol>
        <li>
            <input type="radio" id="x">
            <label for="x"><!-- Insert multi-line markup here --></label>
        </li>
        <li>
            <input type="radio" id="x">
            <label for="x"><!-- Insert multi-line markup here --></label>
        </li>
    </ol>
</fieldset>

How do I style radio button labels so that they look like the following in most browsers (IE6+, FF, Safari, Chrome:

Radio Button Labels

A: 

Make input and label both

float: left;
display: block;

Set width's for the label and input.


apply

clear: both;
 vertical-align: middle;

to all the li's.

Dmitri Farkov
or set "overflow:hidden" on li instead of clear:both
dasha salo
dasha, what's the benefit of doing that? Just curious.
Patrick Klingemann
Dmitry, in IE if float is set on radio buttons they stick to the top of the block. I am not sure but probably you will have to wrap radio buttons in spans and float them instead, no?
dasha salo
overflow:hidden and clear:both react differently in my opinion, and clear both is required to keep the li's from going over each other. To ensure proper vertical-alignment, I think li has to have vertical align set on it, not the label, my mistake.
Dmitri Farkov
+1  A: 

Using the following markup and css I was able to produce multi-line labels that do not wrap under the radio button:

<style type="text/css">
    fieldset input, label {
      float: left;
      display: block;
    }

    fieldset li {
      clear: both;
    }
</style>

<fieldset>
  <ol>
    <li>
      <input type="radio" id="x" />
      <label for="x">
        stuff<br/>
        stuff1
      </label>
    </li>
    <li>
      <input type="radio" id="x" />
      <label for="x">
        stuff<br/>
        stuff1
      </label>
    </li>
  </ol>
</fieldset>

however I was unable to use:

fieldset label {
  vertical-align: middle;
}

to center the label vertically on the radio button, even when applying a width (both suggestions in Dmitri Farkov's answer. My main purpose was to prevent wrapping under the radio button, so this solution will be fine for the time being.

Patrick Klingemann
But what if the label text is a mass of text with no explicit linebrakes? Say 50 words, and the selection list is presented in a div thats set to 400px width. Then the whole label-content will be presented under the input! How do I solve this?
UlfR
That problem doesn't seem to happen if you use the markup from the original question.
Patrick Klingemann
After a bunch of testing, my answer above appears to be the best solution. Vertially centered labels are not really desirable for long text. Imagine text that is several paragraphs long. Would you really want the radio button vertically centered over several paragraphs? I doubt it. I'm selecting this as the answer.
Patrick Klingemann
+1  A: 

I believe this does it all. You didn't mention that it has to validate, however, so I used the inline-block (-moz-inline-box) display. One of my favorites, actually.

Here's a working copy

Tested in Safari 3, FireFox 3, and IE7.

    <style type="text/css">
ol{
 padding-left: 0;
 margin-left:0;
}

ol>li {
 list-style-type: none;
 margin-bottom: .5em;
}

ol>li input[type=radio] {
 display: -moz-inline-box;
 display: inline-block;
 vertical-align: middle;
}

ol>li label {
 display: -moz-inline-box;
 display: inline-block;
 vertical-align: middle;
}
</style>
rpflo
This solution works pretty well, I voted it up, but didn't accept it because I want it to work in IE6 also.
Patrick Klingemann
A: 

Since I asked how to handle really long labels above, and I finally solved it myself. Here is the solution to my problem. Maybe it could help you to?

<style type="text/css">
  #master_frame { 
      background: #BBB;
      height: 300px;
      width: 300px;
  } 
  fieldset.radios { 
      border: none;
  } 
  fieldset fields { 
      clear: both;
  } 
  input { 
      float: left;
      display: block;
  } 
  label { 
      position: relative;
      margin-left: 30px;
      display: block;
  } 
</style>

<div id="master_frame">
  <fieldset class='radios'>
    <div class='field'>
      <input type="radio" id="a" />
      <label for="a">Short</label>
    </div>
    <div class='field'>
      <input type="radio" id="b" />
      <label for="b">
        A really long and massive text that does not fit on one row!
      </label>
    </div>
  </fieldset>
</div>
UlfR
There's an issue with this one in IE6, if the label text is short, the label and the radio button appear indented.
Patrick Klingemann