3

I'm having a bit of a "moment" where I am stumped on an issue I thought should be pretty easy (and probably is, I'm just over complicating I'm sure).

I'm looking to have a div with multiple children div's; the children should automatically expand or contract based on the number there are (the site I'm working on is in a CMS that allows a user to add or remove items).

My issue is having the div's respect the min- and max-width declaration. I have a hunch that it could be something to do with them being float:left, but I've tried a few other variations with no luck.

My main objective is to get these columns to fill their space on one "row", up to 4 columns.

EDIT: I need to have these columns be a minimum width, as well as a maximum width. So if there are 3 child div's, they should all be wider than if there were 4 child div's.

Here is an example of my code: http://codepen.io/joe/full/IJvGp

HTML

<div class="sub cf">
  <div class="row">
      <div class="col">
          Column 1
      </div>

    <div class="col">
        Column 2
      </div>

      <div class="col">
        Column 3
    </div>

    <div class="col">
        Column 4
    </div>
  </div>
</div>

CSS

.sub {
  width: 670px;
  background: #fff;
  border: 10px solid #414042;
}

.sub .row {
  padding: 0;
  float: left;
  width: 100%;
}

.sub .row .col {
  min-width: 166px;
  max-width: 222px;
  width: 100%;
  float: left;
  border-right: 1px solid #D0D2D3; 
  margin: 0;
  padding: 0;
}


.cf::before, .cf::after {
  content: "";
  display: table;
}
.cf::after {
  clear: both;
}
Damon Bauer
  • 2,718
  • 1
  • 22
  • 35
  • You gave them each a width of 100%. If you want to fit 4 of them in one row, you'd have to give each a width of something like 25%. – DA. Jan 02 '13 at 16:50
  • 3
    This isn't necessarily easy in CSS. Probably the most straight-forward options are `display: table;` (see [Use CSS display:table for Layout](http://www.onenaught.com/posts/201/use-css-displaytable-for-layout), not supported by IE until IE8), or the new [CSS3 Flexible Boxes](https://developer.mozilla.org/en-US/docs/CSS/Using_CSS_flexible_boxes) (however, this currently has even less browser support :-p When it does become available, it will be fantastic…). – thirdender Jan 02 '13 at 17:09
  • +1 for giving a try at `display: table`, with or without `table-layout: fixed` for 2 different algorithms. One based on (relative) width of content, the other on widths you indicate. – FelipeAls Jan 02 '13 at 17:26

6 Answers6

1

Removing the width:100%; on the .sub .row .col item made them appear in 4 columns.

Regardless it looks like you should be using a table instead of this approach.

corymathews
  • 12,289
  • 14
  • 57
  • 77
1

CSS3 Solution

Remove the min and max widths on .col but add the box-sizing: border-box property to that. Then add the following code below the .col definition which yields the result in this fiddle:

.sub .row .col:nth-last-of-type(2),
.sub .row .col:nth-last-of-type(2) ~ .col
{
   width: 50%;
}

.sub .row .col:nth-last-of-type(3),
.sub .row .col:nth-last-of-type(3) ~ .col
{
   width: 33.3%;
}

.sub .row .col:nth-last-of-type(4),
.sub .row .col:nth-last-of-type(4) ~ .col
{
   width: 25%;
}
ScottS
  • 71,703
  • 13
  • 126
  • 146
  • ScottS - this looks great, except I have to support down to IE7. It's just as practical to use this code, although it is effective. – Damon Bauer Jan 02 '13 at 20:13
  • @motoxer4533: Okay, thanks for the input. Since you were using pseudo-elements, I would not have guessed you were supporting down to IE7 (since it does not recognize them), and since you were using the double colon on the pseudo-elements, it appeared you did not care about IE8 either. Thanks for the input. – ScottS Jan 02 '13 at 20:45
  • Gotcha. It's a clearfix (http://nicolasgallagher.com/micro-clearfix-hack/) that I removed some of the code for this specific example. – Damon Bauer Jan 03 '13 at 15:37
1

With jquery you could dynamically set the column widths as a % based on the number of columns within the row.

var colWidth = (1 / $('.sub.cf .row').children().length * 100) + '%';
$('.sub.cf .col').outerWidth(colWidth);​

working fiddle. Insert or remove more columns and rerun it to see how it works.

Scrimothy
  • 2,536
  • 14
  • 23
  • As much as I would like to not use jQuery for this, I think it is smarter. Only 2 lines is alright in my book. Thanks for the succinct code and clever solution. – Damon Bauer Jan 02 '13 at 18:32
  • Since users can add and remove columns, you'll never be able to account for the number you have, so you'll probably need js for this. I understand wanting to use css only here, but as long as you're already using jquery elsewhere, you're not really bloating too much here. Glad it helped. – Scrimothy Jan 02 '13 at 18:35
  • That's what I learned. My hope was that using min- & max-width, it would be at least min-, but no more than max-; oh well. Thanks again. – Damon Bauer Jan 02 '13 at 18:47
0

You could try something like this:

HTML:

<div class="sub">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</div>

CSS:

.sub {
    text-align: justify;
    width: 670px;
    background: #fff;
    sborder: 10px solid #414042;
}

.sub div {
    display: inline-block;
    max-width: 166px;
    min-height: 100px;
    border-right: 1px solid #D0D2D3;
    margin: 0;
    padding: 0;
}

.sub:after {
    content: '';
    width: 100%;
    display: inline-block;
}
Ryan
  • 1,387
  • 14
  • 23
  • 1
    Interesting approach, and one of my favorites :-p My question re: this technique is up at [“text-align: justify;” inline-block elements properly?](http://stackoverflow.com/questions/11589590/text-align-justify-inline-block-elements-properly) The problem I was having was that the `:after` clearing element was creating a whitespace one line of text high. – thirdender Jan 02 '13 at 17:06
0

The main problem here is width: 100% and max-width: 222px. With width: 100% you are making the children divs as big as you can. And because of max-width: 222px they all become 222px width. Your parent div is 670px width, so if you do the math: 222px * 4 = 888px. The children divs' total width is exceeding the parent's width, that's why it's pulling the last div down.

You can try: Codepen

If you don't care much about supporting IE8- then ScottS solution is the best.

Angel Yan
  • 960
  • 7
  • 10
-1

You have the following code.

max-width:222px;

Reduce it to some value so that it can be accomdated!

max-width:166px;

works for me!

Sumit Gera
  • 1,249
  • 4
  • 18
  • 34