Creative form alignment

I’m trying to put together an elastic form. The XHTML is pretty standard…


<fieldset>
     <legend>
          Form List Demo
     </legend>
     <ul class="formList">
          <li>
               <label for="standardTextbox">Standard Textbox</label>
               <input type="text" name="standardTextbox" id="standardTextbox" class="textbox">
          </li>           .
          . etc.
          .
     </ul>
</fieldset>

and I’m going for form elements that…

  1. text on left, form elements on the right
  2. pairs of label / form elements stack neatly one on top of the other
  3. labels and form elements align neatly horizontally
  4. form width adjusts automatically to the size of the longest pair
  5. but form elements and labels wrap to accomodate narrow browsers (e.g. non-maximized browsers, mobile devices, etc.

If I write off #3, then I’m already done. Here’s the relevant CSS which is pretty light.


/*  Form List  */

.formList {
list-style-type: none;
float: left;
font-weight: bold;
}

/*  Style All form components  */
.formList input, 
.formList textarea {
font-weight: bold;
}

/*  Style Textboxes  */
.formList .textbox, 
.formList textarea {
width: 13em;
}

.formList .shortTextbox {
width: 2em;
}

/*  Drop Downs  */

.formList .dropDown, 
.formList .dropDown ul {
border: 0.05em solid #000000;
margin: 0;
padding: 0;
}

.formList .dropDown {
display: inline;
margin: 0;
padding: 0.2em 1em;
}

.formList .dropDown ul {
list-style-type: none;
position: absolute;
display: none;
}

.formList .dropDown:hover ul {
display: block;
}

/*  Miscellaneous  */
.formList label { 
vertical-align: top;
}

However, there’s no doubt it looks a little messy with only the labels (and not the form elements) aligned horizontally. However, every solution I’ve tried to align the form elements neatly breaks two or more of my other specs. Any ideas?

Here’s a link to the demo I’m working on.
http://www.earthchronicle.com/EC/Content/Computers/Programming/~OOCSSGallery.aspx#formListTest

Hi,

If you want nice columns then you have to throw a width in somewhere to get them nicely aligned.

I would give a width to the label element and then align the text right so that is lines up nicely. If you make the label display:inline-block then you can also set vertical alignment nicely.

I personally would not use a list but as you have started I have used your structure and your names to complete this.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
html, body, ul, form, fieldset,input {
 margin:0;
 padding:0
}
form{margin:10px;}
fieldset.formList{
    border-width:1px 0 0;
    width:50&#37;;
    color:#000;
}
.formList ul {
    list-style:none;
    border:5px solid red;
    min-width:320px;
}
.formList label {
    display:inline-block;
    vertical-align:middle;
    width:30%;
    text-align:right;
    margin:0 1%;
}
.formList input {
    vertical-align:middle
}
.formList li {
    width:100%;
    clear:both;
    border-bottom:1px dotted #fff;
    color:#000;
    padding:10px 0;
    background:#C2D2D3
}
.textbox {width:200px}
.textbox2 {width:50px}
.formList textarea {
    width:200px;
    vertical-align:middle;
    overflow:auto;
}
.formList li:nth-of-type(odd){background:#fffccc}
</style>
</head>
<body>
<form id="form1" method="post" action="">
    <fieldset class="formList">
    <legend> Form List Demo </legend>
    <ul>
        <li>
            <label for="standardTextbox">Label goes here:</label>
            <input type="text" name="standardTextbox" id="standardTextbox" class="textbox" />
        </li>
        <li>
            <label for="standardTextbox2">Label:</label>
            <input type="text" name="standardTextbox2" id="standardTextbox2" class="textbox" />
        </li>
        <li>
            <label for="standardTextbox3">A longer label goes here: </label>
            <input type="text" name="standardTextbox3" id="standardTextbox3" class="textbox2" />
        </li>
        <li>
            <label for="comment">A vertically aligned comment can go here even when it wraps:</label>
            <textarea name="comment" id="comment" cols="25" rows="5"></textarea>
        </li>
    </ul>
    </fieldset>
</form>
</body>
</html>


Of course there are loads of other methods but the inline-block avoids the problem with float clearing and float rising and the fact that you cant vertically align floats.

Dunno about others, but I’m totally mystified as to what you are asking here. The specifications listed above seem to contradict each other. What is the actual question? Ideally, could you do a page with just the form on it, as it’s very hard to test the version you linked to with all that other stuff on the page. I’m wondering if you are just asking for vertical-align: middle on the labels?

Sorry for the confusion. I’d like to horizontally align the form elements. The labels stack up in a nice column, perfect, just what I want. However, (as you’d expect) the form elements are inline and simply follow right after. While this isn’t awful, it’s not the sort of crisp-looking form that I prefer.

I would like the form elements to stack up in a nice column as well. My preference would be to have all the left edges aligned, but I would certainly accept aligning the right hand edges of the form elements compared to the rather ragged look that I have now.

I would like to do something like - float: right; on the form elements. However, this removes the form elements from the flow and they start poking outside the list items and interfering with the form elements (and labels) above and below them. (FYI if you’re looking at the test at http://www.earthchronicle.com/EC/Content/Computers/Programming/~OOCSSGallery.aspx#formListTest, the bright green border is applied to the ul, the dark green borders are the li elements, and the red border is the labels. I want to horizontally align the form elements but not if it means having them poke outside the dark green borders.)

If that’s all the explanation you needed, then great. Stop reading. Otherwise I will explain the specs in more detail.

  1. I would prefer each label / form element set to be ordered with the label to the left of the form component. (I would entertain alternatives.)

  2. Each set should not interfere with the sets above and below it. (e.g. I’ve tried using floats and positioning on the form elements to make them line up in a column, but since they’re removed from the flow of the page, they can screw up labels and form elements in other list items.)

  3. I would like all the labels to make one column and all the form elements to make another (like the crisp designs people used to rely on tables for).

  4. A ul element wraps the form elements. It’s set to float: left; so that it doesn’t expand to 100% width. Instead the ul snaps to the width of the longest label / form element set. I’ll happily entertain other ways of accomplishing that, but I don’t want to lose that behavior.

  5. If you resize the width of the browser, the current behavior is for the text and form components to wrap neatly since everything is inline. I’ll happily entertain other ways of accomplishing that, but I don’t want to lose that behavior.

perhaps you’re looking for something like that. it’s only to make you an idea how to align labels and make two columns. i can make more improvements, but only if that is what you’re looking for.

<!DOCTYPE html>
<html>

<head>
  <title></title>
  <style type="text/css">
    fieldset.column {float: left; width: 50&#37;;}
    label { width: 150px; display: inline-block; }
  </style>
</head>

<body>

    <form>
    
      <fieldset>
      
        <fieldset>
          <label for="standardTextbox">Standard Textbox</label>
            <input type="text" name="standardTextbox" id="standardTextbox" class="textbox" />
        </fieldset>
        
        <fieldset>
          <label for="shortTextboxDemo">Short Textbox</label>
            <input type="text" name="shortTextboxDemo" id="shortTextboxDemo" class="shortTextbox" />
        </fieldset>
        
        <fieldset>
          <label for="standardTextarea">Standard Textarea</label> 
            <textarea name="standardTextarea" id="standardTextarea" rows="4" cols="20">Default Content</textarea>
        </fieldset>
        
        <fieldset>
        <label for="test1-page1">Test One / Page One</label>
          <input type="checkbox" name="test1-page1" id="test1-page1" value="complete" />
        </fieldset>
        
        <fieldset>
        <label for="test2-page1">Test Two / Page One</label>
          <input type="checkbox" name="test2-page1" id="test2-page1" value="complete" />
        </fieldset>
        
        <fieldset>
        <label for="test3-page1">Test Three / Page One</label>
          <input type="checkbox" name="test3-page1" id="test3-page1" value="complete" />
        </fieldset>
        
      </fieldset>

      <fieldset class="column">
        
        <fieldset>
          <label for="test1-page2">Test One / Page Two</label>
            <input type="checkbox" name="test1-page2" id="test1-page2" value="complete" />
        </fieldset>
        
        <fieldset>
          <label for="test2-page2">Test Two / Page Two</label>
            <input type="checkbox" name="test2-page2" id="test2-page2" value="complete" />
        </fieldset>
        
        <fieldset>
          <label for="test3-page2">Test Three / Page Two</label>
            <input type="checkbox" name="test3-page2" id="test3-page2" value="complete" />
        </fieldset>
        
      </fieldset>

      <fieldset>
      
        <fieldset>
          <label for="vacationPackageFirstClass">First Class</label>
            <input type="radio" name="vacationPackage" id="vacationPackageFirstClass" value="firstClass" />
        </fieldset>
        
        <fieldset>
          <label for="vacationPackageCoach">Coach</label>
            <input type="radio" name="vacationPackage" id="vacationPackageCoach" value="coach" checked="checked" />
        </fieldset>
        
      </fieldset>

      <fieldset>
      
        <fieldset>
        <label for="vacationDestinationTahiti">Tahiti</label>
          <input type="radio" name="vacationDestination" id="vacationDestinationTahiti" value="tahiti" checked="checked" />
        </fieldset>
        
        <fieldset>
        <label for="vacationDestinationParis">Paris</label>
          <input type="radio" name="vacationDestination" id="vacationDestinationParis" value="paris" />
        </fieldset>
        
        <fieldset>
        <label for="vacationDestinationNewYork">New York</label>
          <input type="radio" name="vacationDestination" id="vacationDestinationNewYork" value="newYork" />
        </fieldset>  

      </fieldset>

      <fieldset>
        <input type="submit" name="submitButton" id="submitButtonTest" class="submitButton" />
      </fieldset>
      
    </form>

</body>
</html>