tags:

views:

255

answers:

3

I need to simulate the look of a typical paper form in CSS. It consists of a two-column table of fields. Each field consists of a field name (of variable width) followed by an underline that continues to the end of the column. The field might be populated, in which case there is some text centered above the line, or it may be blank. If that isn't clear, he's a rough idea in manky ASCII art:

Name: _______Foo_______  Age: _____17______
Location: __Melbourne__  Handedness: _Left_

(except that the underline would continue under any text)

To implement the underline without text, I assume I should use a border-bottom rather than a text-decoration: underline. Additionally, I need the bordered element to take up the full available space. Both of those argue for a block-level element. However, I can't find any way to get the block level element (either a div, an li, or a span set to display: block or inline-block) to remain on the same line as the label. As soon as I give it a width: 100%, it newlines. I've tried various combinations of floats, and I'm not inclined to do anything ridiculous with absolute positioning. Any recommendations?

A: 

I guess you could set the width for each element individually - I know it's not an elegant solution, but better then using javascript.

Jakub Hampl
True, it's better than using javascript, but I'm hoping for something even better than that. Setting individual widths would obviously hurt flexibility, maintainability, etc.
sidereal
Though it has the added benefit of having reasonably simple and semantic html.
Jakub Hampl
A: 

I've experimented with this a bit this evening and the following is a possibility. You can make different classes for different sizes. It's a little better than having to code the sizes individually.

Name: <hr class="fieldA" /> Email: <hr class="fieldA" />

CSS:

.fieldA {
    padding-left:120px;
    height:1px;
    display:inline-block;
    margin-bottom:0;
    color:#000000;
    backgound-color:#000000;  
}
Diodeus
Thanks, Diodeus. Unfortunately, it's not clear how text would be rendered above the underline (if the field is populated). I've tried a couple of ways using your hr solution and the text is always pushed to the right or left of the hr.
sidereal
+2  A: 

I have two solutions for you. One is nice, but does not work in IE. One is ugly, but seems to work everywhere. First, the nice one, using divs and css:

<style type="text/css"> 
  .container { width:500px; }
  .field { width:240px; display:table; float:left; }
  .label { white-space:nowrap; display:table-cell; width:1px; } 
  .data { border-bottom: solid 1px black; width="100%";text-align:center; margin-left:10px; white-space:nowrap; display:table-cell; } 
  .row { display:table-row; }
</style> 

<div class="container"> 
  <div class="field"> 
    <div class="row"> 
      <div class="label">label 1</div> 
      <div class="data">data 1</div> 
    </div>
  </div>
  <div class="field"> 
    <div class="row"> 
      <div class="label">label 2</div> 
      <div class="data">data 2 </div> 
    </div>
  </div>
  <div class="field"> 
    <div class="row"> 
      <div class="label">label 3</div> 
      <div class="data">data 3 </div> 
    </div>
  </div>
  <div class="field"> 
    <div class="row"> 
      <div class="label">label 4</div> 
      <div class="data">data 4 </div> 
    </div>
  </div>
</div>

Since IE doesn't support table-cell (etc), we need an ugly one:

<style type="text/css">
  .table-field { width:240px; display:table; float:left; }
  .table-label { white-space:nowrap; } 
  html>body .table-label { width:1px; }  /* force firefox to shrink label to fit text */
  .table-data { border-bottom: solid 1px black; width="100%";text-align:center; white-space:nowrap; } 
</style> 

<div class="container"> 
  <table class="table-field"><tr><td class="table-label">label 1</td><td class="table-data">data 1</td></tr></table>
  <table class="table-field"><tr><td class="table-label">label 2</td><td class="table-data">data 2</td></tr></table>
  <table class="table-field"><tr><td class="table-label">label 3</td><td class="table-data">data 3</td></tr></table>
  <table class="table-field"><tr><td class="table-label">label 4</td><td class="table-data">data 4</td></tr></table>
  <table class="table-field"><tr><td class="table-label">label 5</td><td class="table-data">data 5</td></tr></table>
  <table class="table-field"><tr><td class="table-label">label 6</td><td class="table-data">data 6</td></tr></table>
</div>

Either way, this needs colors and margins/padding to look good.

Ray
Thanks Ray. The display:table-cell solution is pretty close. Initially I didn't like the hardcoded field width, but it looks like that's just a max width and it correctly shrinks to handle long labels. Also, it's not enforcing the two-per-row constraint, and if I lower the width it'll pull up a third. Though that might be even more flexible. . Regardless, not working in IE's kind of a problem.I'd thought about the table solution. It's a bit heavy, but it might be the only solution. I'll mull it over for a bit and see if anyone else has something. Otherwise, I'll give you the check.
sidereal
The widths in the 'field' and 'container' classes work together to keep two fields per row. You could do it a different way by having two separate 'field' classes - field-1 and field-2 for the first and second fields in each row. Add "clear:left" to field-1 to force field-1 to start on a new line.
Ray