views:

220

answers:

2

I've looked at other questions and am unable to find the solution to this. Consider this image: mockup

I want to wrap divs and stack them vertically. The GREEN div would be a wrapper on a line. The BLUE div would contain an html label and maybe icon for a tooltip. The ORANGE div would contain some sort of entry (input, select, textarea).

Several of these would be stacked vertically to make up a form. I am doing this now, but I have to specify a height for the container div and that really needs to change depending on the content - considering any entry could land there. Images and other stuff could land here, as well.

I have a width set on the BLUE div and the ORANGE is float:left. How can I get rid of the height on divs and let that be determined by content? Is there a better way? Changing all to something else would be difficult and would prefer a way to style all elements or something.

The code I'm using is like:

<div class=EntLine>
    <div class=EntLbl>
      <label for="Name">Name</label>
    </div>
    <div class=EntFld>
      <input type=text id="Name" />
    </div>
</div>

The CSS looks like:

.EntLine {
  height: 20px;
  position: relative;
  margin-top: 2px;
  text-align: left;
  white-space: nowrap;
}

.EntLbl {
  float: left;
  width: 120px;
  padding: 3px 0px 0px 3px;
  min-width: 120px;
  max-width: 120px;
  vertical-align: text-top;
}

.EntFld {
  float: left;
  height: 20px;
  padding: 0px;
  width: 200px;
}

Thanks!

+1  A: 

Well, for a start I think you could use less mark-up to achieve your aim. You might have a good reason for wrapping a div around every element of your form, but if it's just to force a single label-input pair to each line then you can nest the input inside the label tag:

      <label for="Name">Name
          <input type="text" id="Name" />
      </label>

This way you can use a simple:

label {display: block; }

to force each pair to their own line. This would also remove the need to float the labels, which removes the need to specify the height of any containing element.

You can still apply multiple classes to the relevant fields/labels, but it's far less trouble. Unless I'm really missing something.

Failing all of that, you could simply add an empty div (or other element), after the last of your fields and style with:

#empty_element {
disply: block;
height: 0;
clear: both; /* to force the parent element to expand to contain this element and, by extension, any non 'position:absolute' siblings that precede it in the mark-up */
visibility: hidden;
}
David Thomas
One reason for doing that is to ensure consistency in the app regardless of the form the user is seeing. It's also easier for me to read and much easier to maintain consistency for other developers I have working for me. I can give them the chunk of code above and allow no variations. The extra markup is not so much a problem as it is a solution in this case.
Erick
You find it easier to work with five nested elements -instead of two- for every label/input pair? I'm surprised, but it's your shop...see the edit, for a possible solution that'll force the containing-element to expand to include the children, though it *does* involve adding yet another element to the form(s).
David Thomas
+1  A: 

If I understand your question correctly, I believe that your problem is that the outer green container does not expand to cover the two inner divs - instead the two inner divs overhang the bottom of the green container.

There are a number of solutions to this issue - here are two pages with different methods:

http://www.positioniseverything.net/easyclearing.html

http://www.quirksmode.org/css/clearing.html

cbp
That was the answer for me. The quirksmode.org page did the trick! Thanks a lot everyone!
Erick