How can I achieve the following structure without using tables or JavaScript? The white borders represent edges of divs and aren\'t relevant to the question.
The usual way to do it is as outlined by Guffa, nested elements. It's a bit sad having to add extra markup to get the hooks you need for this, but in practice a wrapper div here or there isn't going to hurt anyone.
If you must do it without extra elements (eg. when you don't have control of the page markup), you can use box-sizing, which has pretty decent but not complete or simple browser support. Likely more fun than having to rely on scripting though.
Maybe I'm being dumb, but isn't table the obvious solution here?
<div class="parent">
<div class="fixed">
<div class="stretchToFit">
</div>
.parent{ display: table; width 100%; }
.fixed { display: table-cell; width: 150px; }
.stretchToFit{ display: table-cell; vertical-align: top}
Another way that I've figured out in chrome is even simpler, but man is it a hack!
.fixed{
float: left
}
.stretchToFit{
display: table-cell;
width: 1%;
}
This alone should fill the rest of the line horizontally, as table-cells do. However, you get some strange issues with it going over 100% of its parent, setting the width to a percent value fixes it though.
New way I've just stumbled upon: css calc():
.calculated-width {
width: -webkit-calc(100% - 100px);
width: -moz-calc(100% - 100px);
width: calc(100% - 100px);
}
Source: css width 100% minus 100px
I had a similar issue where I wanted a banner across the top of the screen that had one image on the left and a repeating image on the right to the edge of the screen. I ended up resolving it like so:
CSS:
.banner_left {
position: absolute;
top: 0px;
left: 0px;
width: 131px;
height: 150px;
background-image: url("left_image.jpg");
background-repeat: no-repeat;
}
.banner_right {
position: absolute;
top: 0px;
left: 131px;
right: 0px;
height: 150px;
background-image: url("right_repeating_image.jpg");
background-repeat: repeat-x;
background-position: top left;
}
The key was the right tag. I'm basically specifying that I want it to repeat from 131px in from the left to 0px from the right.