How can I make multi-line, vertically and horizontally aligned labels for radio buttons in HTML Forms with CSS?

36,185

Solution 1

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.

Solution 2

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>

Solution 3

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>

Solution 4

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.

Share:
36,185
Patrick Klingemann
Author by

Patrick Klingemann

Senior Director of Engineering at Articulate, Rise.com

Updated on September 22, 2020

Comments

  • Patrick Klingemann
    Patrick Klingemann over 3 years

    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

  • Patrick Klingemann
    Patrick Klingemann almost 15 years
    dasha, what's the benefit of doing that? Just curious.
  • Dasha Salo
    Dasha Salo almost 15 years
    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?
  • Dmitri Farkov
    Dmitri Farkov almost 15 years
    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.
  • Patrick Klingemann
    Patrick Klingemann about 14 years
    This solution works pretty well, I voted it up, but didn't accept it because I want it to work in IE6 also.
  • John_Smith
    John_Smith about 14 years
    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?
  • Patrick Klingemann
    Patrick Klingemann about 14 years
    That problem doesn't seem to happen if you use the markup from the original question.
  • Patrick Klingemann
    Patrick Klingemann about 14 years
    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
    Patrick Klingemann about 14 years
    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.
  • Jabe
    Jabe about 13 years
    Perfect! BTW: No need for the display: inline-block on the <input>.
  • Andre Figueiredo
    Andre Figueiredo over 6 years
    +1 I'm confused why this was not chosen the accepted solution since it's concise and earlier than current.