Update & Summary
I feel obligated to make this question clearer, now that there is a bounty attached.
(Also, I'm pretty sure this will be child's play when the calc()
CSS3 unit value is supported, doing something like width: calc(25% - 5px)
; though we'll probably be browsing the internet in our minds by that point)
I'm working on a CSS framework for a few projects that share design requirements; namely a fluid 12 column layout. Using floated .column
elements with percentage widths of (100% / 12) x col_size
, this is reasonably easy. However, the issue comes with the addition of fixed margins (or any form of spacing) between columns.
My initial attempt used the fluid columns as described, with a .panel
child nested in each. HTML/CSS snippet follows (reduced for brevity):
.column{
float: left;
display: inline-block;
}
.width-01{ width: 8.3333%; }
.width-02{ width: 16.6666%; }
.width-03{ width: 25%; }
/* etc */
.panel{
width: 100%;
padding: 5px;
box-sizing: border-box; /* so padding doesn't increase width */
}
<div class="column width-02">
<div class="panel">Width-02</div>
</div>
<div class="column width-03">
<div class="panel">Width-03</div>
</div>
<div class="column width-02">
<div class="panel">Width-02</div>
</div>
<div class="column width-05">
<div class="panel">Width-05</div>
</div>
This snippet would produce a layout similar to that of the image below, however all .panel
elements have 5px
padding on all sides. I'm trying to make the content edge of the outside columns flush with the edge of the view-port (or parent container for that matter). Another approach would be to eliminate the .panel
class altogether, and just go with columns:
.column{
float: left;
display: inline-block;
padding-left: 10px;
box-sizing: border-box;
}
.column:first-child{ padding-left: 0px; }
.width-01{ width: 8.3333%; }
.width-02{ width: 16.6666%; }
.width-03{ width: 25%; }
/* etc */
<div class="column width-02">Width-02</div>
<div class="column width-03">Width-03</div>
<div class="column width-02">Width-02</div>
<div class="column width-05">Width-05</div>
Again, this works well, producing results even closer to that of the image below, however now the (actual) problem is that the padding is eating into the width of the columns screwing up the width distribution. The :first-child
column has 10 pixels (or whatever the margin size is) greater content area width than it's siblings.
This may seem innocuous, even unnoticeable; however there are a few instances where having exact (as exact as possible) width distribution between elements is either necessary, or would make things altogether easier.
And so, whether using padding, margin, or some combination thereof; is there any solution for fluid columns, fixed margins, with even distribution of gutter space that won't rob "marginal" (***haha*) content area from the adjacent columns?**
Original Question
Due to the simple lack of results in my searches and attempts, I've concluded this is impossible. If anywhere can yield an answer though, I'm certain it is here.
Is there any way, using pure CSS, to achieve a fluid width columned layout with fixed width margins?
Important note: This figure is only an example, and not the specific layout I'm looking to achieve. A given solution should permit any combination of adjacent columns, the total width distribution totaling 12 or less. Consider the popular 960 grid for reference.)
Note: In a 12 column layout, the width distribution of the columns in the image are 2, 3, 2, and 5 respectively.
So far, I've resorted to a grid that, using percentages, nearly accomplishes this. The problem is, in order to achieve the margins, each column requires an additional child (I call them .panel
) with:
width: 100%;
box-sizing: border-box;
padding: 10px;
This is, again nearly, fine; the issue is with this approach is that the first and last column have outer "margins" (10px
) and the "margins" between each column are doubled (2 x 10px
)
Certainly, with the inclusion of the new CSS3 calc()
value type, this could be solved much more easily. Something in the direction of:
.width-12 > .panel{ width: 100%; }
.width-09 > .panel{
width: calc(75% - 10px);
margin: ...;
}
I've got some Javascript fixes, I've hacked out some stuff that "works", but I'm on a quest. Hopefully the holiest of grails exists.
The following solution, and the one @avall provided (although certainly a good choice on simplifying) unfortunately aren't what I'm looking for. The main issue being, the margins are not distributed evenly among columns.
The only way I can see this working is reducing the .panel
padding to 5px
and something like:
.column:first-child > .panel {
padding-left: 0px;
}
.column:last-child > .panel {
padding-right: 0px;
}
/* not necessary? in any case, haven't tested */
.column:only-child > .panel {
padding-right: 0px;
padding-left: 0px;
}
This solution is not acceptable, only because IE8 fails to recognize the :last-child
(and for that matter :only-child
) pseudo selectors.
See Question&Answers more detail:
os