2

I'd like to get the following sizing behavior on a row of data. The 'abcd...' field is a variable size, and I'd like as much of it displayed as possible after all the other fields have taken up their required space. The '0123...' field is a variable size, and I'd like fully displayed right after the first field. The 'X' field is a known fixed size, and I'd like it pinned to the right side.

| abcdefghijklmnopqrstuvwxyz | 0123456789 |     | X |
| abcdefghijklmnopqrstuvwxyz | 0123456789 |   | X |
| abcdefghijklmnopqrstuvwxyz | 0123456789 | | X |
| abcdefghijklmnopqrstuvwxyz | 0123456789 | X |
| abcdefghijklmnopqrstuvwx | 0123456789 | X |
| abcdefghijklmnopqrstuv | 0123456789 | X |
| abcdefghijklmnopqrst | 0123456789 | X |

I've tried many table-based and floating div approaches, but nothing works right across all browsers. Here's an approach that works with webkit but not others.

<div style="width:300px">
 <div style="float:right;width:20px">
  X
 </div>
 <div style="overflow:hidden">
  <div style="float:left">
   <div style="overflow:hidden">
    <div style="float:right">
     0123456789
    </div> 
    <div style="overflow:hidden;white-space:nowrap">
     abcdefghijklmnopqrstuvwxyz
    </div>
   </div>
  </div>
 </div> 
</div>

Some of the nested divs are not required by webkit, but I was trying to get this working in other browsers. Anyone have ideas on how to solve this? Thanks!

  • This looks like tabular data to me. Why not simply use tables ? – Valentin Flachsel Sep 26 '10 at 08:09
  • I tried a number of table and hybrid table/floating div approaches, but didn't get as close to the desired behavior as the example above. My problem with using tables was trying to get them to truncate cell content without specifying a fixed width for the cell. – Dieter Maximus Sep 26 '10 at 16:22
  • I couldn't find a CSS solution for this, so I resorted to JavaScript. I used an approach similar to this solution - http://stackoverflow.com/questions/118241/calculate-text-width-with-javascript. – Dieter Maximus Oct 15 '10 at 15:35

2 Answers2

0

I have misread the question the first time, and since my answer was nowhere near what you were looking for, I decided to replace it completely with the proper solution in order to keep the answer clean. Anyways, this should do the trick:

CSS

.row {
    width: 300px;
}
.clear {
    clear: both;
}
.col_1 {
    float: left;
    position: relative;
    width: 280px;
    overflow: hidden;
}
.col_2 {
    position: absolute;
    background: #FFF;
    top: 0;
    right: 0;
    white-space: nowrap;
}
.col_3 {
    float: right;
    width: 20px;
}

HTML

<div class="row">
    <div class="col_1">
        abcdefghijklmnopqrstuvwxyz
        <div class="col_2">0123456789</div>
    </div>
    <div class="col_3">x</div>
    <div class="clear"></div> 
</div>
<!-- repeat as needed -->

The only thing that's required is to change the background of .col_2 so it matches the one of .col_1 since the extra content of .col_1 is hidden behind .col_2.

Hope this helps !

Valentin Flachsel
  • 10,795
  • 10
  • 44
  • 67
  • I tried it out. Unfortunately, there's nothing to stop the floats from shifting down to another row once the width gets too small. So I end up with 'abcd...' on top with '123...' and 'X' on the bottom. – Dieter Maximus Sep 26 '10 at 16:17
  • Oh, I'm sorry, I misread your question. Not sure this is possible with pure CSS. Is a jQuery solution acceptable ? – Valentin Flachsel Sep 26 '10 at 17:35
  • No problem. I was hoping to find a pure HTML/CSS solution. In another part of my app, I actually render dialogs off-screen to get their sizes before positioning them on-screen. So while I might revert to a JavaScript solution here as well, I wanted to exhaust my CSS options first. Thanks for helping. – Dieter Maximus Sep 26 '10 at 17:45
  • I have spoken too soon :) Please see my updated answer for a pure CSS solution. – Valentin Flachsel Sep 26 '10 at 18:04
  • That's close, but it's aligning the 2nd field incorrectly when the row is wide. The 2nd field pins right to the X rather than left to the 1st field. I get the same behavior when I remove the float:left and overflow:hidden wrapper divs. To give you a little more insight into my alignment goals, I have a content header containing the title of the content followed immediately by some button controls (e.g. edit & delete) with a close button pinned to the right. It seemed like that should be doable, but I may have to back down from that design. – Dieter Maximus Sep 26 '10 at 18:18
  • Is the `div` containing the control buttons (`.col_2`) always the same width (i.e. the same buttons for every entry) ? – Valentin Flachsel Sep 26 '10 at 18:32
  • Unfortunately not. Some buttons are dropdowns and the selected item that's displayed in the button changes the button width. Also the number and type of action buttons change depending on the currently selected content. – Dieter Maximus Sep 26 '10 at 18:40
  • In that case, I really can't think of any other pure CSS solution, but if it helps, I can write a jQuery solution for you. – Valentin Flachsel Sep 26 '10 at 18:46
  • Thanks for the offer, and for all your help in trying to figure this one out. That was very generous. I spent a whole day experimenting with CSS solutions and wanted to give the community a crack at this before ditching. If nothing turns up, I think I'll be able to work out a JavaScript solution for it. – Dieter Maximus Sep 26 '10 at 19:36
0

You're going to need to specify a "row" div that holds all 3 divs per row. tell every one of those inner cells of the row to clear:none; and float where desired!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<style type="text/css">
html, div, body {font-family: arial; font-size: 12px; font-weight: bold; color: #666666;}
html {margin-top: 200px;}

div.contain {
border: 5px solid black;
margin: 0 auto;
width: 500px !Important;
height: 500px !important;
}

div.row{
width: 500px;
display: block;
overflow: auto;
}
div.letters {
float: left;
clear: none;
border: 1px solid red;
width: auto;
padding: 10px;
}
div.numbers{
float: left;
clear: none;
border: 1px solid blue;
width: auto;
padding: 10px;
}
div.x {
float: right;
clear: none;
border: 1px solid green;
width: auto;
padding: 10px;
}

</style>
</head>
<body>
<div class="contain">

<div class="row">
    <div class="letters">abcdefghijklmnopqrstuvwxyz</div>
    <div class="numbers">0123456789</div>
    <div class="x">X</div>
</div>
<div class="row">
    <div class="letters">abcdefghijklmnopqrstuvwxy</div>
    <div class="numbers">0123456789</div>
    <div class="x">X</div>
</div>
<div class="row">
    <div class="letters">abcdefghijklmnopqrstuvwx</div>
    <div class="numbers">0123456789</div>
    <div class="x">X</div>
</div>
<div class="row">
    <div class="letters">abcdefghijklmnopqrstuvw</div>
    <div class="numbers">0123456789</div>
    <div class="x">X</div>
</div>
<div class="row">
    <div class="letters">abcdefghijklmnopqrstuv</div>
    <div class="numbers">0123456789</div>
    <div class="x">X</div>
</div>
<div class="row">
    <div class="letters">abcdefghijklmnopqrstu</div>
    <div class="numbers">0123456789</div>
    <div class="x">X</div>
</div>
<div class="row">
    <div class="letters">abcdefghijklmnopqrst</div>
    <div class="numbers">0123456789</div>
    <div class="x">X</div>
</div>
<div class="row">
    <div class="letters">abcdefghijklmnopqrs</div>
    <div class="numbers">0123456789</div>
    <div class="x">X</div>
</div>
<div class="row">
    <div class="letters">abcdefghijklmnopqr</div>
    <div class="numbers">0123456789</div>
    <div class="x">X</div>
</div>
<div class="row">
    <div class="letters">abcdefghijklmnopq</div>
    <div class="numbers">0123456789</div>
    <div class="x">X</div>
</div>
<div class="row">
    <div class="letters">abcdefghijklmnop</div>
    <div class="numbers">0123456789</div>
    <div class="x">X</div>
</div>
<div class="row">
    <div class="letters">abcdefghijklmno</div>
    <div class="numbers">0123456789</div>
    <div class="x">X</div>
</div>

</div>
</body>
</html>
Shawn
  • 9
  • 1
  • Thanks for taking a crack at it. I think that you missed the root of the problem though. The underlying content in the first field is always the same (e.g. 'abcdefghijklmnopqrstuvwxyz'). But when the width of the overall row shrinks, that's the field that has its display area truncated. That's why the prior solution attempts were using 'overflow: hidden'. – Dieter Maximus Oct 15 '10 at 15:34